下面给出的是python代码sn-p,用于通过Farneback方法计算每一帧的光流。尽管下面给出的不是完整的工作代码(网络上有足够的例子),但它显示了流量是如何计算的。
#use this params
farneback_params={
'pyr_scale':0.5,
'levels':3,
'winsize':15,
'iterations': 3,
'poly_n': 5,
'poly_sigma':1.2,
'flags':cv2.OPTFLOW_USE_INITIAL_FLOW
}
#do initializations
while True:
#for every frame,
#get current_frame_gray
flow = cv2.calcOpticalFlowFarneback(prev_frame_gray, current_frame_gray, flow, **farneback_params)
prev_frame_gray = current_frame_gray
如果您假设每个帧的大小为 H x W,则以下断言成立。
assert(flow.shape == (H, W, 2))
assert(flow.dtype == numpy.float32)
如果您查看下面有关 Farneback 方法的文档,
http://docs.opencv.org/3.0-beta/modules/video/doc/motion_analysis_and_object_tracking.html,则以下语句成立
for r in range(H):
for c in range(W):
prev_frame_gray[r,c] corresponds to current_frame_gray[r + flow[r,c, 1], c+ flow[r,c,0]]
所以前一帧(prev_frame_gray)每个像素的速度分量为
flow[r,c,0] in x- direction (columns)
flow[r,c,1] in y- direction (rows)
正如上面的各种代码示例所示,您可以通过以下简单的命令轻松地以极坐标形式(幅度、角度)表示流
mag, ang = cv2.cartToPolar(flow[...,0], flow[...,1])
mag 和 ang 的形状为 (H, W) 和 dtype numpy.float32。 ang 结果给出了 0-2pi 范围内的角度。