我有一些代码可以计算并绘制密集的光流:
import cv2 as cv
import numpy as np
cap = cv.VideoCapture(0)
def getFrame():
ret, img = cap.read()
img = cv.resize(img,(640,480))
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
return gray
def draw_flow(img, flow, step=16):
h, w = img.shape[:2]
y, x = np.mgrid[step/2:h:step, step/2:w:step].reshape(2,-1).astype(int)
fx, fy = flow[y,x].T
lines = np.vstack([x, y, x+fx, y+fy]).T.reshape(-1, 2, 2)
lines = np.int32(lines + 0.5)
vis = cv.cvtColor(img, cv.COLOR_GRAY2BGR)
cv.polylines(vis, lines, 0, (0, 255, 0))
for (x1, y1), (_x2, _y2) in lines:
cv.circle(vis, (x1, y1), 1, (0, 255, 0), -1)
return vis
def main():
prevgray = getFrame()
while True:
gray = getFrame()
flow = cv.calcOpticalFlowFarneback(prevgray, gray, None, 0.5, 3, 15, 3, 10, 1.2, 0)
prevgray = gray
cv.imshow('flow', draw_flow(gray, flow))
cv.waitKey(1)
if __name__ == '__main__':
main()
由于花费的时间太长,所以我想到了计算筛分特征,将其匹配,然后计算特征的光学流量的想法。
直到现在我有了这个:
import cv2 as cv
import numpy as np
cap = cv.VideoCapture(0)
sift = cv.xfeatures2d.SIFT_create()
bf = cv.BFMatcher()
def getFrame():
ret, img = cap.read()
img = cv.resize(img,(640,480))
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
return gray
def main():
prev_gray = getFrame()
prev_kp, prev_des = sift.detectAndCompute(prev_gray,None)
while True:
next_gray = getFrame()
next_kp, next_des = sift.detectAndCompute(next_gray,None)
matches = bf.knnMatch(prev_des, next_des, k=2)
# Apply ratio test
good = []
for m,n in matches:
if m.distance < 0.75*n.distance:
good.append([m])
#calc optical flow
prev_kp = next_kp
prev_des = next_des
prev_gray = next_gray
cv.waitKey(1)
if __name__ == '__main__':
main()
如何计算筛选特征的光流,并在第一个代码中使用drwa_flow函数绘制它们?
我也有这段代码:
import numpy as np
import cv2 as cv
lk_params = dict( winSize = (15, 15),
maxLevel = 2,
criteria = (cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 0.03))
feature_params = dict( maxCorners = 500,
qualityLevel = 0.3,
minDistance = 7,
blockSize = 7 )
track_len = 5
tracks = []
cam = cv.VideoCapture(0)
def getFrame():
_ret, bgr = cam.read()
bgr = cv.resize(bgr, (640,480))
gray = cv.cvtColor(bgr, cv.COLOR_BGR2GRAY)
return gray, bgr
while True:
gray, vis = getFrame()
if len(tracks) > 0:
img0, img1 = prev_gray, gray
p0 = np.float32([tr[-1] for tr in tracks]).reshape(-1, 1, 2)
p1, _st, _err = cv.calcOpticalFlowPyrLK(img0, img1, p0, None, **lk_params)
p0r, _st, _err = cv.calcOpticalFlowPyrLK(img1, img0, p1, None, **lk_params)
d = abs(p0-p0r).reshape(-1, 2).max(-1)
good = d < 1
new_tracks = []
for tr, (x, y), good_flag in zip(tracks, p1.reshape(-1, 2), good):
if not good_flag:
continue
tr.append((x, y))
if len(tr) > track_len:
del tr[0]
new_tracks.append(tr)
cv.circle(vis, (x, y), 2, (0, 255, 0), -1)
tracks = new_tracks
cv.polylines(vis, [np.int32(tr) for tr in tracks], False, (0, 255, 0))
mask = np.zeros_like(gray)
mask[:] = 255
for x, y in [np.int32(tr[-1]) for tr in tracks]:
cv.circle(mask, (x, y), 5, 0, -1)
p = cv.goodFeaturesToTrack(gray, mask = mask, **feature_params)
if p is not None:
for x, y in np.float32(p).reshape(-1, 2):
tracks.append([(x, y)])
prev_gray = gray
cv.imshow('lk_track', vis)
ch = cv.waitKey(1)
但是使用此代码时,不要使用筛选功能,也不要像第一个代码那样绘制流程...