基于Python及OpenCV的光流实现
本文内容摘自 << Programming Computer Vision with Python >> 一书
1. 光流
光流是目标、场景或摄像机在连续两帧图像间运动时造成的目标的运动。它是图像在平移过程中的二维矢量场。
光流法主要依赖于三个假设:
- 亮度很定。 图像中目标的像素强度在连续帧之间不会发生变化。
- 时间规律。 相邻帧之间的时间足够短,以至于在考虑运行变化时可以忽略他们之间的差异。
- 空间一致性。相邻像素具有相似的运动。
2. 基于Python及OpenCV的实现
import cv2
from numpy import *
from pylab import *
def draw_flow(im, flow, step=16):
"""在间隔分开的像素采样点处绘制光流"""
h, w = im.shape[:2]
y, x = mgrid[step / 2:h:step, step / 2:w:step].reshape(2, -1).astype(int)
fx, fy = flow[y, x].T
# 创建线的终点
lines = vstack([x, y, x + fx, y + fy]).T.reshape(-1, 2, 2)
lines = int32(lines)
# 创建图像并绘制
vis = cv2.cvtColor(im, cv2.COLOR_GRAY2BGR)
for (x1, y1), (x2, y2) in lines:
cv2.line(vis, (x1, y1), (x2, y2), (0, 255, 0), 1)
cv2.circle(vis, (x1, y1), 1, (0, 255, 0), -1)
return vis
if __name__ == '__main__':
# 设置视频捕获
# cap = cv2.VideoCapture(r"E:\data\vidoe.avi") # 使用本地视频
cap = cv2.VideoCapture(0) # 使用摄像头
ret, im = cap.read()
prev_gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) # 获取灰度图像
while True:
ret, im = cap.read()
gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
# 计算流
flow = cv2.calcOpticalFlowFarneback(prev_gray, gray, None, 0.5, 3, 15, 3, 5, 1.2, 0)
prev_gray = gray
# 画出流矢量
cv2.imshow('Optical flow', draw_flow(gray, flow))
if cv2.waitKey(10) == 27:
break
运行效果