由于工程需要用到 Lucas-Kanade 光流,在此进行一下简单整理(后续还会陆续整理关于KCF,PCA,SVM,最小二乘、岭回归、核函数、dpm等等):

光流,简单说也就是画面移动过程中,图像上每个像素的x,y位移量,比如第t帧的时候A点的位置是(x1, y1),那么我们在第t+1帧的时候再找到A点,假如它的位置是(x2,y2),那么我们就可以确定A点的运动了:(u, v) = (x2, y2) - (x1,y1)

1、假设原图是I(x,y,z)  (这里是扩展到三维空间的,所以还有个z值),移动后的图像是I(x+δx,y+δy,z+δz,t+δt),两者满足:

2、其中图像移动可以认为I (x ,y ,z ,t ) = I (x + δx ,y + δy ,z + δz ,t + δt )

也就是说:( H.O.T. 指更高阶,在移动足够小的情况下可以忽略)

3、从这个方程中我们可以得到:

其中Vx = u, Vy=v,也就是光流的值(二维图像没有z),   则是图像在(x ,y,z ,t )这一点的梯度  (就是两帧图像块之间差值) 。

4、假设流(Vx,Vy,Vz)在一个大小为m*m*m(m>1)的小窗中是一个常数,那么从像素1...n , n = m*m*m 中可以得到下列一组方程:

三个未知数但是有多于三个的方程,这个方程组自然是个超定方程,也就是说方程组内有冗余,方程组可以表示为:

也就是:

采用最小二乘法:

5、另外,由于LK算法假设是小位移,为了解决大位移问题,需要在多层图像缩放金字塔上求解,每一层的求解结果乘以2后加到下一层:

6、具体就见matlab代码:

其中求解最小二乘的行列式求解只有2维所以计算量尚可容忍

%Data acquisition
im1= ((imread('1.png')));
im2= ((imread('2.png'))); 
im1=single(im1);
im2=single(im2); 
[result,corner_count,ptx,pty] = harris(im1);  //harris角点是求光流的关键点
imagesc(result);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%parameters : levels number, window size, iterations number, regularization
numLevels= 4;
window= 10;
iterations=3;
alpha = 0.001;

hw = floor(window/2);

t0 = clock;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%pyramids creation
pyramid1 = im1;
pyramid2 = im2;
%init
for i=2:numLevels
im1 = impyramid(im1, 'reduce');
im2 = impyramid(im2, 'reduce');
pyramid1(1:size(im1,1), 1:size(im1,2), i) = im1;
pyramid2(1:size(im2,1), 1:size(im2,2), i) = im2;
end;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Processing all levels
for p = 1:numLevels
%current pyramid
im1 = pyramid1(1:(size(pyramid1,1)/(2^(numLevels - p))), 1:(size(pyramid1,2)/(2^(numLevels - p))), (numLevels - p)+1);
im2 = pyramid2(1:(size(pyramid2,1)/(2^(numLevels - p))), 1:(size(pyramid2,2)/(2^(numLevels - p))), (numLevels - p)+1);

%init
if p==1
u = zeros(size(im1));
v = zeros(size(im1));
else
%resizing
u = 2 * imresize(u,size(u)*2,'bilinear');
v = 2 * imresize(v,size(v)*2,'bilinear');
end

%refinment loop
for r = 1:iterations

u=round(u);
v=round(v);

%every pixel loop
for i = 1+hw:size(im1,1)-hw
for j = 1+hw:size(im2,2)-hw
patch1 = im1(i-hw:i+hw, j-hw:j+hw);

%moved patch
lr = i-hw+v(i,j);
hr = i+hw+v(i,j);
lc = j-hw+u(i,j);
hc = j+hw+u(i,j);

if (lr < 1)||(hr > size(im1,1))||(lc < 1)||(hc > size(im1,2))
%Regularized least square processing
else
patch2 = im2(lr:hr, lc:hc);

fx = conv2(patch1, 0.25* [-1 1; -1 1]) + conv2(patch2, 0.25*[-1 1; -1 1]);
fy = conv2(patch1, 0.25* [-1 -1; 1 1]) + conv2(patch2, 0.25*[-1 -1; 1 1]);
ft = conv2(patch1, 0.25*ones(2)) + conv2(patch2, -0.25*ones(2));

Fx = fx(2:window-1,2:window-1)';
Fy = fy(2:window-1,2:window-1)';
Ft = ft(2:window-1,2:window-1)';

A = [Fx(:) Fy(:)];
G=A'*A;

G(1,1)=G(1,1)+alpha; G(2,2)=G(2,2)+alpha;
U=1/(G(1,1)*G(2,2)-G(1,2)*G(2,1))*[G(2,2) -G(1,2);-G(2,1) G(1,1)]*A'*-Ft(:);
u(i,j)=u(i,j)+U(1); v(i,j)=v(i,j)+U(2);
end
end
end
end
etime(clock,t0)
end

LK光流算法公式详解的更多相关文章

  1. HS光流算法详解<转载>

    HS 光流法详解 前言 本文较为详细地介绍了一种经典的光流法 - HS 光流法. 光流法简介 当人的眼睛与被观察物体发生相对运动时,物体的影像在视网膜平面上形成一系列连续变化的图像,这一系列变化的图像 ...

  2. 光流法详解之一(LK光流)

    Lucas–Kanade光流算法是一种两帧差分的光流估计算法.它由Bruce D. Lucas 和 Takeo Kanade提出 [1]. LK光流法有三个假设条件: 1. 亮度恒定:一个像素点随着时 ...

  3. 光流法详解之二(HS光流)

    Horn–Schunck光流算法[1]是一种全局方法估算光流场. 参考博文:https://blog.csdn.net/hhyh612/article/details/79216021 假设条件: H ...

  4. HS 光流法详解

    前言 本文较为详细地介绍了一种经典的光流法 - HS 光流法. 光流法简介 当人的眼睛与被观察物体发生相对运动时,物体的影像在视网膜平面上形成一系列连续变化的图像,这一系列变化的图像信息不断 &quo ...

  5. AVL树详解

    AVL树 参考了:http://www.cppblog.com/cxiaojia/archive/2012/08/20/187776.html 修改了其中的错误,代码实现并亲自验证过. 平衡二叉树(B ...

  6. C++构造函数详解及显式调用构造函数

    来源:http://www.cnblogs.com/xkfz007/archive/2012/05/11/2496447.html       c++类的构造函数详解                  ...

  7. C++中构造函数详解及显式调用构造函数

    C++构造函数详解及显式调用构造函数                                         c++类的构造函数详解                        一. 构造函 ...

  8. LK 光流法简介

    前言 若假定一个局部区域的像素运动是一致的,则可以用这个新的约束条件替代前文中提到的全局速度平滑约束条件.这种光流算法就叫做 LK 光流法. LK 光流法的推导 首先,需要推导出光流约束方程. 这一步 ...

  9. C++11 并发指南------std::thread 详解

    参考: https://github.com/forhappy/Cplusplus-Concurrency-In-Practice/blob/master/zh/chapter3-Thread/Int ...

随机推荐

  1. HTTP协议探究(一):缓存

    一 复习与目标 1 复习 序章主要用WrieShark抓包HTTP报文 复习了TCP协议 讲述了TCP协议与HTTP之间的关系 HTTP1.1更新原因:HTTP1.0一次TCP连接只能发送一次HTTP ...

  2. TCP协议探究(三):RTT、滑动窗口和阻塞处理

    1 RTT算法 1.1 概述 上一节说了重传机制需要设置一个重传超时值(RTO,Retransmission TimeOut),RTO设长了,重发太慢:设短了,可能导致包没有丢,就重发了,可能导致雪崩 ...

  3. C++ 构造函数后面的冒号的作用

    其实冒号后的内容是初始化成员列表,一般有三种情况:     1.对含有对象成员的对象进行初始化,例如,     类line有两个私有对象成员startpoint.endpoint,line的构造函数写 ...

  4. Stanford NLP 课程笔记之计算字符串距离

    在自然语言处理任务中,有时候需要计算两个字符串之间的相似度,也可以称作是两者之间的距离,用最小编辑距离表示. 最小编辑距离用{Insertion,Deletion,Substitution}这三种操作 ...

  5. Stanford NLP 课堂笔记之正则表达式

    1.[]表达式的用法 正则表达式可以让我们匹配我们想要的字符串形式,增加了效率,在自然语言处理领域有较大的作用. 模式 匹配 [Ww]oodchuck Woodchuck,woodchuck [123 ...

  6. 【转】axios用post提交的数据格式

    本文链接:https://blog.csdn.net/wopelo/article/details/78783442vue框架推荐使用axios来发送ajax请求,之前我还写过一篇博客来讲解如何在vu ...

  7. selenium无头浏览器&规避操作

    一.无头浏览器概述: 无头浏览器主要目的是打开浏览器但用户看不到 简单用法如下: from selenium import webdriver from time import sleep from ...

  8. LEANGOO卡片

    转自:https://www.leangoo.com/leangoo_guide/leangoo_cards.html#toggle-id-10 Leangoo的卡片可以是需求.目标.任务.问题.缺陷 ...

  9. 如何用Java代码在SAP Marketing Cloud里创建contact数据

    我们可以使用SAP Marketing Cloud提供的Contact create OData API在第三方应用里创建Contact主数据. API地址:/sap/opu/odata/sap/CU ...

  10. 多进程之multiprocessing模块和进程池的实现

    转载:https://www.cnblogs.com/xiaobeibei26/p/6484849.html Python多进程之multiprocessing模块和进程池的实现 1.利用multip ...