2015-07-08 3 views
1

Текущий алгоритм использует goodFeaturestoTrack для выбора угловых точек, но я хочу выбрать свои собственные точки. Во-вторых, я хочу сохранить данные о том, к какому пикселю переместилась эта точка. Как мне решить эти две проблемы? Код, который я использую в настоящее время:Выберите мои собственные точки вместо угловых точек при реализации оптического потока в opencv python

import numpy as np 
import cv2 

cap = cv2.VideoCapture('output.avi') 

# params for ShiTomasi corner detection 
# throw every other corners below quality level. Sort rest in descending order. Pick greatest, throw rest in min and pick N greatest 
feature_params = dict(maxCorners = 1,  # how many pts. to locate 
         qualityLevel = 0.3, # b/w 0 & 1, min. quality below which everyone is rejected 
         minDistance = 7,  # min eucledian distance b/w corners detected 
         blockSize = 7)  # 

# Parameters for lucas kanade optical flow 
lk_params = dict(winSize = (15,15), # size of the search window at each pyramid level 
        maxLevel = 2,  # 0, pyramids are not used (single level), if set to 1, two levels are used, and so on 
        criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03)) 
        # Criteria : Termination criteria for iterative search algorithm. 
        # after maxcount { Criteria_Count } : no. of max iterations. 
        # or after { Criteria Epsilon } : search window moves by less than this epsilon 


# Create some random color for the pt. chosen 
color = np.random.randint(0,255,(1,3)) 

# Take first frame and find corners in it 

ret, old_frame = cap.read()  #read frame 
old_gray = cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY) #convert to grayscale 

p0 = cv2.goodFeaturesToTrack(old_gray, mask = None, **feature_params) #use goodFeaturesToTrack to find the location of the good corner. 

#cvPoint pl = new cvPoint(2,3) 


# Create a mask image for drawing purposes filed with zeros 
mask = np.zeros_like(old_frame) 

while(1): 
    ret,frame = cap.read() 
    frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) 

    # calculate optical flow 
    # err kind of gives us the correlation error(matching error) 

    p1, st, err = cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params) 

    # Select good points 
    good_new = p1[st==1] 
    good_old = p0[st==1] 

    # draw the tracks 
    for i,(new,old) in enumerate(zip(good_new,good_old)): 
     a,b = new.ravel() 
     c,d = old.ravel() 
     mask = cv2.line(mask, (a,b),(c,d), color[i].tolist(), 2) 
     frame = cv2.circle(frame,(a,b),5,color[i].tolist(),-1) 
    img = cv2.add(frame,mask) 

    cv2.imshow('frame',img) 
    k = cv2.waitKey(30) & 0xff 
    if k == 27: 
     break 
# 
# # Now update the previous frame and previous points 
    old_gray = frame_gray.copy() 
    p0 = good_new.reshape(-1,1,2) 
# 
## release and destroy all windows. 
cv2.destroyAllWindows() 
cv2.release() 
+1

Итак, на самом деле я напечатал good_new, который, как я думаю, дает мне пиксели относительно того, где эта точка движется. Я правильно или неправильно, пожалуйста, расскажите. –

+0

Это правильно в соответствии с документацией здесь (http://docs.opencv.org/modules/imgproc/doc/feature_detection.html#goodfeaturestotrack). Кроме того, я ценю, что вы продолжаете работать над вопросом даже после того, как спросите его. Я считаю, что ваше решение - это просто изменить функцию goodFeaturesToTrack(). Просто убедитесь, что новая функция возвращает расположение множества точек. Я напишу несколько примеров кода через несколько часов, когда смогу. –

ответ

1

Как упоминал Марк Миллер, в качестве входных точек можно использовать любой вектор-объект. cv2.calcOpticalFlowPyrLK будет использовать их, чтобы найти на новом изображении новые местоположения этих функций, сравнивая патчи пикселей вокруг заданных координат.

Чтобы сохранить новые, Вам нужно поймать возвращаемые значения cv2.calcOpticalFlowPyrLK

немного о других функциях: cv2.goodFeaturesToTrack (Shi - Thomasi или Харрис углы) используются, потому что две перпендикулярные края очень легко найти, что дает множество функций, поэтому даже если некоторые из них будут закрыты, вы не получите ничего. Более продвинутые функции, такие как ORB, содержат гораздо больше информации в своих дескрипторах, которые могут быть использованы для связывания функции на разных изображениях, чем два параметра, которые были получены в углах Shi - Thomasi или Harris, и было бы немного отходов использовать их с простым Lucas - алгоритм Канаде.

+0

Видимо, в моем случае я хочу отследить наклейку на лбу ребенка. Поскольку ребенок машет головой во всех направлениях, сопоставление шаблонов не очень подходит моей цели (хотя я сейчас с этим работаю). Но алгоритм LK очень хорош в отслеживании таких точек. Итак, было бы прекрасно, если бы я смог найти его с помощью алгоритма LK. –

+0

Вы также можете попробовать некоторые функции с ориентацией инвариантных функций. Это совершенно новый уровень сложности. [Здесь] (http://dsp.stackexchange.com/questions/1288/what-are-some-free-alternatives-to-sift-surf-that-can-be-used-in-commercial-app) - некоторые намеки на это. У вас могут возникнуть проблемы, если упомянутый ребенок слишком быстро движет головой или камера слишком медленная. Предполагается, что LK будет работать для небольших переводов отслеживаемых точек. – morynicz