0x00. 光流
光流是进行视频中运动对象轨迹标记的一种很常用的方法,在OpenCV中实现光流也很容易。
CalcOpticalFlowPyrLK
函数计算一个稀疏特征集的光流,使用金字塔中的迭代 Lucas-Kanade 方法。
简单的实现流程:
- 加载一段视频。
- 调用
GoodFeaturesToTrack
函数寻找兴趣点。 - 调用
CalcOpticalFlowPyrLK
函数计算出两帧图像中兴趣点的移动情况。 - 删除未移动的兴趣点。
- 在两次移动的点之间绘制一条线段。
代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
import cv2.cv as cv capture = cv.CaptureFromFile('img/myvideo.avi') nbFrames = int(cv.GetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_COUNT)) fps = cv.GetCaptureProperty(capture, cv.CV_CAP_PROP_FPS) wait = int(1/fps * 1000/1) width = int(cv.GetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_WIDTH)) height = int(cv.GetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_HEIGHT)) prev_gray = cv.CreateImage((width,height), 8, 1) #Will hold the frame at t-1 gray = cv.CreateImage((width,height), 8, 1) # Will hold the current frame prevPyr = cv.CreateImage((height / 3, width + 8), 8, cv.CV_8UC1) #Will hold the pyr frame at t-1 currPyr = cv.CreateImage((height / 3, width + 8), 8, cv.CV_8UC1) # idem at t max_count = 500 qLevel= 0.01 minDist = 10 prev_points = [] #Points at t-1 curr_points = [] #Points at t lines=[] #To keep all the lines overtime for f in xrange( nbFrames ): frame = cv.QueryFrame(capture) #Take a frame of the video cv.CvtColor(frame, gray, cv.CV_BGR2GRAY) #Convert to gray output = cv.CloneImage(frame) prev_points = cv.GoodFeaturesToTrack(gray, None, None, max_count, qLevel, minDist) #Find points on the image #Calculate the movement using the previous and the current frame using the previous points curr_points, status, err = cv.CalcOpticalFlowPyrLK(prev_gray, gray, prevPyr, currPyr, prev_points, (10, 10), 3, (cv.CV_TERMCRIT_ITER|cv.CV_TERMCRIT_EPS,20, 0.03), 0) #If points status are ok and distance not negligible keep the point k = 0 for i in range(len(curr_points)): nb = abs( int(prev_points[i][0])-int(curr_points[i][0]) ) + abs( int(prev_points[i][1])-int(curr_points[i][1]) ) if status[i] and nb > 2 : prev_points[k] = prev_points[i] curr_points[k] = curr_points[i] k += 1 prev_points = prev_points = GoodFeaturesToTrack 函数寻找兴趣点。CalcOpticalFlowPyrLK 函数计算出两帧图像中兴趣点的移动情况。代码示例:
|