光流特征提取:LK算法求稠密光流
光流特征:
光流(optical flow)是空间运动物体在观察成像平面上的像素运动的瞬时速度。光流法是利用图像序列中像素在时间域上的变化以及相邻帧之间的相关性来找到上一帧跟当前帧之间存在的对应关系,从而计算出相邻帧之间物体的运动信息的一种方法。通常将二维图像平面特定坐标点上的灰度瞬时变化率定义为光流矢量。一言以概之:所谓光流就是瞬时速率,在时间间隔很小(比如视频的连续前后两帧之间)时,也等同于目标点的位移。
1.基本假设条件
(1)亮度恒定不变。即同一目标在不同帧间运动时,其亮度不会发生改变。这是基本光流法的假定(所有光流法变种都必须满足),用于得到光流法基本方程;
(2)时间连续或运动是“小运动”。即时间的变化不会引起目标位置的剧烈变化,相邻帧之间位移要比较小。同样也是光流法不可或缺的假定。
2.基本约束方程
考虑一个像素I(x,y,t)在第一帧的光强度(其中t代表其所在的时间维度)。它移动了 (dx,dy)的距离到下一帧,用了dt时间。因为是同一个像素点,依据上文提到的第一个假设我们认为该像素在运动前后的光强度是不变的,即:
3.步骤:
a.首先,对每一帧建立一个高斯金字塔,最低分辨率图像在最顶层,原始图片在底层。
b.计算光流。从顶层(Lm层)开始,通过最小化每个点的邻域范围内的匹配误差和,得到顶层图像中每个点的光流。
c.顶层的光流计算结果(位移情况)反馈到第Lm-1层,作为该层初始时的光流值的估计g。
d.这样沿着金字塔向下反馈,重复估计动作,直到到达金字塔的底层(即原图像)。(准确值=估计值+残差) “残差”即本算法的关键对于每一层L,每个点的光流的计算都是基于邻域内所有点的匹配误差和最小化。
4.源码
import numpy as np
import cv2 as cv
cap= cv.VideoCapture("training_lib_KTH/person02_boxing_d1_uncomp.avi")#视频帧的读取
ret, frame1 = cap.read()##第一个参数ret 为True 或者False,代表有没有读取到图片
#第二个参数frame1表示截取到一帧的图片
prvs = cv.cvtColor(frame1,cv.COLOR_BGR2GRAY)#BGR和灰度图的转换
hsv = np.zeros_like(frame1)# 构造矩阵hsv,维度和frame1一致,初始化全为0
hsv[...,1] = 255
while(1):
ret, frame2 = cap.read()
next = cv.cvtColor(frame2,cv.COLOR_BGR2GRAY)
flow = cv.calcOpticalFlowFarneback(prvs,next, None, 0.5, 3, 15, 3, 5, 1.2, 0)
mag, ang = cv.cartToPolar(flow[...,0], flow[...,1])#笛卡尔坐标转换为极坐标获得极轴和极角
hsv[...,0] = ang*180/np.pi/2
hsv[...,2] = cv.normalize(mag,None,0,255,cv.NORM_MINMAX)
bgr = cv.cvtColor(hsv,cv.COLOR_HSV2BGR)
cv.imshow(frame2,bgr)
k = cv.waitKey(30) & 0xff
if k == 27:
break
elif k == ord(s):
cv.imwrite(opticalfb.png,frame2)
cv.imwrite(opticalhsv.png,bgr)
prvs = next
cv.calcOpticalFlowFarneback()函数说明:
calcOpticalFlowFarneback( InputArray _prev0, InputArray _next0, OutputArray _flow0, double pyr_scale, int levels, int winsize, int iterations, int poly_n, double poly_sigma, int flags ) // 参数说明如下: // _prev0:输入前一帧图像 // _next0:输入后一帧图像 // _flow0:输出的光流 // pyr_scale:金字塔上下两层倍数关系,0.5表示每层比上一层小两倍 // levels:金字塔层数 // winsize:均值窗口大小,越大越能denoise并且能够检测快速移动目标,但会引起模糊运动区域 // iterations:迭代次数 // poly_n:像素领域大小,一般为5,7等 // poly_sigma:高斯标注差,一般为1-1.5 // flags:计算方法。主要包括OPTFLOW_USE_INITIAL_FLOW和OPTFLOW_FARNEBACK_GAUSSIAN
视频输入
结果
