Lucas-Kanade稀疏光流法

光流法

光流

由于目标对象或者摄像机的移动造成的图像对象在连续两帧图像中的移动被称为光流。如下图所示,它是一个 2D 向量场,可以用来显示一个点从第一帧图像到第二帧图像之间的移动,箭头表示光流场向量。

光流.png

其中,光流包括稀疏光流与稠密光流。图像中的每个像素都使用这种方法,则通常将其称为“稠密光流”。有一种替代类算法被称为“稀疏光流”,仅仅跟踪图像中某些点的子集。

Lucas-Kanade稀疏光流法

假设先验

LK光流全称为Lucas-Kanade光流,算法原理比较好理解,首先,LK光流对应用场景提出了三个假设先验:

  • 亮度恒定:假设像素在运动过程中亮度(灰度值)恒定,其实这是大部分计算机视觉任务都需要的一个先验。
  • 像素偏移小:检测光流的两帧之间不能有过大的motion,否则LK光流会检测失败。
  • 空间一致性:当前帧相邻的像素在下一帧应该也是相邻的,这样便于求解图像块的梯度进而寻找到匹配的像素。

算法流程
给定t 时刻的图像上的像素点I(x,y) ,算法的目标是找到在下一时刻该像素的在各个方向上的位移,用公式表达就是:
I ( x , y , t ) = I ( x + \delta x , y + \delta y , t + \delta t ) \tag{1}

图111.png

可以对等号右边的式子采用泰勒展开:

image.png

可以看到等号后边第一项与等号左边相等可以消去,\frac{\partial I}{\partial x}\frac{\partial I}{\partial y} 比较好理解,就是当前时刻图像在δxδy方向的梯度了,\frac{\partial I}{\partial t} 表示的的是时间方向上的梯度,也就是下一帧与当前帧的差分。δt是两帧时间差也就是1,而δxδy就是我们要求解的像素运动。由此我们可以得到:
I _ { x } \delta x + I _ { y } \delta y = - I _ { t }\tag{3}
我们现在有两个未知数但是只有一个方程,无法求解,根据我们在最开始的第三个假设,此时我们可以使用需要求解的像素周围5×5的像素块来帮助我们得到更多的方程式:
\left[ \begin{array} { c } { I _ { x 1 } I _ { y 1 } } \\ { I _ { x 2 } I _ { y 2 } } \\ { \cdots } \\ { I _ { x 24 } I _ { y 24 } } \\ { I _ { x 25 } I _ { y 25 } } \end{array} \right] \left[ \begin{array} { c } { \delta x } \\ { \delta y } \end{array} \right] = \left[ \begin{array} { c } { - I _ { t 1 } } \\ { - I _ { t 2 } } \\ { \cdots } \\ { - I _ { t 24 } } \\ { - I _ { t 25 } } \end{array} \right]\tag{4}
此时便组成了一个超定方程组,也就是方程个数大于未知数个数,这是我们可以使用最小二乘法来求解这个方程组。
\begin{aligned} A x & = - b \\ A ^ { T } A x & = A ^ { T } ( - b ) \\ \end{aligned}\tag{5}
方程的解必须满足以下条件:

  • A ^ { T } A 必须可逆

  • A ^ { T } A 中的特征值\lambda _ { 1 }\lambda _ { 2 }不能太小。如下图所示,当特征值过小,说明像素块选在平缓区域。

flat.png
  • A ^ { T } A\lambda _ { 1 }/\lambda _ { 2 }不能太大。如下图所示,当\lambda _ { 1 }/\lambda _ { 2 }过大时,说明素块选在边缘区域。

    edge.png

总结

像素块不能选在平缓区域和边缘区域。如下图所示,像素块最好选在纹理丰富的区域。

high_texture截图_20200225054308.png

LK光流法存在的问题

在实际的拍摄的视频中,每一帧不一定都满足三个假设:亮度恒定、像素偏移小和空间一致性。

  • 亮度恒定不满足,

    解决方法:梯度恒定

  • 像素偏移过大

    解决方法:采样高斯金字塔方法,估计光流

    ?111.png
  • 像素块不满足空间一致性。

代码实现:

import numpy as np
import cv2

cap = cv2.VideoCapture("768x576.avi")

# ShiTomas角点检测的参数
feature_params = dict(maxCorners =100,qualityLevel=0.3,minDistance=7,blockSize=7)

# 金字塔LK算法参数
lk_params = dict(winSize=(15,15),maxLevel=2,criteria=(cv2.TERM_CRITERIA_EPS|cv2.TermCriteria_COUNT,10,0.03))
# 创建随机颜色
color = np.random.randint(0,255,(100,3))

ret,old_frame = cap.read()
old_gray = cv2.cvtColor(old_frame,cv2.COLOR_BGR2GRAY)
p0 = cv2.goodFeaturesToTrack(old_gray,mask=None,**feature_params)

mask = np.zeros_like(old_frame)

while(1):
    ret,frame = cap.read()
    
    if ret is True: 
        frame_gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
    else:   
        break

    p1,st,err = cv2.calcOpticalFlowPyrLK(old_gray,frame_gray,p0,None,**lk_params)

    good_new =p1[st==1]
    good_old =p0[st==1]

    for i,(new,old) in enumerate(zip(good_new,good_old)):
        a,b = new.ravel()
        c,d = old.ravel()
        mask = cv2.line(mask,(a,b),(c,d),color[i].tolist(),2)
        frame = cv2.circle(frame,(a,b),5,color[i].tolist(),-1)
    img = cv2.add(frame,mask)

    cv2.imshow('frame',img)
    k = cv2.waitKey(30)&0xff
    if k == 27:
        break

    old_gray = frame_gray.copy()
    p0 = good_new.reshape(-1,1,2)

cv2.destroyAllWindows()
cap.release()

参考文献:

[1] B. Lucas and T. Kanade, “An iterative image registration technique with an application to stereo vision,” in Proc. of International Joint Conf. On Artificial Intelligence, pp.674-679, 1981.

[2] 浙江大学陆系群副教授,《Motion Estimation Optical Flow.PPT》

[3] 《OpenCV-Python 中文教程》

[4] LK稀疏光流法

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270