光流估计
光流是空间运动物体在观测成像平面上的像素运动的“瞬时速度”,根据各个像素点的速度矢量特征,可以对图像进行动态分析,比如目标跟踪。
光流估计就是当给定两帧图像时,下一帧图像和上一帧图像中每一个点有什么不同,而且不同点移动到了什么位置。实现找出人眼所能看到的东西。
L-K有三个前提假设条件:
- 亮度恒定:同一点随着时间的变化,其亮度不会发生改变
- 小运动:随着时间的变化不会引起位置的剧烈变化,只有小运动情况下才能用前后帧之间的单位位置变化引起的灰度变化去近似灰度对位置的偏导数
- 空间一致:一个场景上邻近的点投影到图像上也是临近点,且邻近点速度一致。因为光流法基本方程约束只有一个,而要求x,y方向的速度,有两个未知变量,所以需要联立n多个方程求解
当一个视频中,如果有一辆车在缓慢的行驶过程当中,发生了一个运动和变化,在变化当中光流估计就是看每一帧它的瞬时速度和方向表示什么样子,这光流图中有箭头,有大小有方向,大小表示它的移动速度,即帧和帧之间的瞬时速度,方向就是它前进的目标。位置发生变动时,其像素点的大小没有发生变化
I(x, y, t) = I(x+dx, y+dy, t+dt) = I(x, y, t) + Ixdx + Iydy + Itdt 使用泰勒基数进行展开对上式进行化解即:
Ixdx + Iydy + Itdt = 0 Ix表示x轴的梯度方向,Iy表示y轴的梯度方向,It表示单位时间上的像素点的变化
如果我们使用前后两帧的变化, 那么dx和dy也就是表示x轴和y轴的速度,返回的结果是dx和dy,即在x轴和y轴方向上移动的步数,我们就可以知道目标的位置了
当做光流估计的时候,输入应该都是图像中的角点,在做光流估计之前,一定先把原始的图像进行角点检测,把角点传进去才能用光流估计对角点做些事情
简易demo:
第一步:使用cv2.capture读入视频
第二步:构造角点检测所需参数, 构造lucas kanade参数
第三步:拿到第一帧图像,并做灰度化, 作为光流检测的前一帧图像
第四步:使用cv2.goodFeaturesToTrack获得光流检测所需要的角点
第五步:构造一个mask用于画直线
第六步:读取一张图片,进行灰度化,作为光流检测的后一帧图像
第七步:使用cv2.caclOpticalFlowPyrLK进行光流检测
第八步:使用st==1获得运动后的角点,原始的角点位置
第九步:循环获得角点的位置,在mask图上画line,在后一帧图像上画角点
第十步:使用cv2.add()将mask和frame的像素点相加并进行展示
第十一步:使用后一帧的图像更新前一帧的图像,同时使用运动的后一帧的角点位置来代替光流检测需要的角点
import numpy as np
import cv2
# 第一步:视频的读入
cap = cv2