『壹』 运动目标检测——光流法与opencv代码实现
运动目标的检测的其主要目的是 获取目标对象的运动参数(位置、速度、加速度等)及运动轨迹 ,通过进一步分析处理,实现对目标行为更高层级上的理解。
运动目标检测技术目的是 从序列图像中将变化区域从背景图像中提取出来 ,常用于视频监视、图像压缩、三维重构、异常检测等。
运动目标检测主流方法有帧差法、背景差法、光流法等。光流法源于 仿生学 思想,更贴近于直觉,大量昆虫的视觉机理便是基于光流法。
二十世纪五十年代心理学家Gibson在他的著作“The Perception of Visual World”中首次提出了以心理学实验为基础的光流法基本概念,而直到八十年代才由Horn、Kanade、Lucash和Schunck创造性地将灰度与二维速度场相联系,引入光流约束方程的算法,对光流计算做了奠基性的工作。
光流(optical flow):由于目标对象或者摄像机的移动造成的图像对象在连续两帧图像中的移动。
小球在连续五帧运动构成的光流 小球在连续五帧运动构成的光流通俗说,对于一个图片序列,把每张图像每个像素在连续帧之间的运动速度和方向( 某像素点在连续两帧上的位移矢量 )找出来就是光流场。
第t帧的时A点的位置是(x1, y1),第t+1帧时A点位置是(x2,y2),则像素点A的位移矢量:(ux, vy) = (x2, y2) - (x1,y1)
如何知道第t+1帧的时候A点的位置涉及到不同的光流计算方法,主要有四种:基于梯度的方法、基于匹配的方法、基于能量的方法、基于相位的方法。
光流法依赖于三个假设:
根据所形成的光流场中 二维矢量的疏密程度 ,光流法可分为稠密光流与稀疏光流。
基于区域匹配生成的稠密光流场 基于区域匹配生成的稠密光流场 稀疏光流只对有 明显特征的组点 (如角点)进行跟踪,计算开销小。
http://www.opencv.org.cn/opencvdoc/2.3.2/html/moles/video/doc/motion_analysis_and_object_tracking.html#calcopticalflowfarneback
(1)calcOpticalFlowPyrLK
基于金字塔LK光流算法,计算某些点集的稀疏光流。
参考论文《Pyramidal Implementation of the Lucas Kanade Feature TrackerDescription of the algorithm》
(2)calcOpticalFlowFarneback
基于Gunnar Farneback 的算法计算稠密光流。
参考论文《Two-Frame Motion Estimation Based on PolynomialExpansion》
(3)CalcOpticalFlowBM
通过块匹配的方法来计算光流
(4)CalcOpticalFlowHS
基于Horn-Schunck 的算法计算稠密光流。
参考论文《Determining Optical Flow》
(5)calcOpticalFlowSF
论文《SimpleFlow: A Non-iterative, Sublinear Optical FlowAlgo》的实现
『贰』 求大神解释下matlab程序,关于运动目标检测的
function vu = get_mask()//定义函数VU
bg = imread('tu\\131.jpg');//读入图片131.jpg
bg = rgb2gray(bg);//将图片转换为灰度图像
bg = im2bw(bg, graythresh(bg));//再转换为二值图,阈内值是对灰度图像用最大类间容方差法得到的
Img = imread('tu\\1.jpg');//读入图片1.JPG
I = rgb2gray(Img);//转换为灰度图
I = im2bw(I, graythresh(I));//转换为二值图
bw = I;//
L = bwlabel(I);//从黑背景甄别白块,返回和I相同大小的图像L
stats = regionprops(L, 'Area');//统计被标记白块的区域的总面积
Ar = cat(1, stats.Area);//按列连接矩阵
[mr, ind] = max(Ar);//找到Ar中那些最大值的索引位置,将他们放在向量ind中
I(L~=ind) = 0;//I中L与ind不相等的位置赋值为零
vu = imfill(I, 'holes');//将原图填充孔洞
『叁』 运动目标检测 高斯混合模型 matlab
--------------------------------------------------------------------------
% 基于中位数算法的运动目标检测
% 第1种实现方法
%--------------------------------------------------------------------------
%*******************************读取视频数据********************************
% 调用aviread函数读取视频文件
vid = aviread('WalkingMan.avi')
size(vid(1).cdata) % 查看第1帧的大小,也是每一帧的大小
vid(1).colormap % 查看第1帧的colormap值
%*****************************数据类型的转换********************************
% 把vid的cdata字段的取值转换成一个240×360×3×80的四维数组IM
IM = cat(4,vid.cdata);
size(IM) % 查看IM的大小
[m,n,k,h] = size(IM); % 把IM的大小赋给四个变量
% 把IM转换成一个80行,240×360×3列的矩阵
I = reshape(IM,[m*n*k,h])';
%********************调用median函数求中位数,进行视频图像分割****************
I = median(I); % 求I矩阵中各列元素的中位数
I = reshape(I,[m,n,k]); % 将向量I转成240×360×3的三维数组,得到背景图像
figure; % 新建一个图形窗口
imshow(I); % 显示背景图像
figure; % 新建一个图形窗口
imshow(IM(:,:,:,1) - I); % 显示第1帧中的目标图像
%--------------------------------------------------------------------------
% 基于中位数算法的运动目标检测
% 第1种实现方法
%--------------------------------------------------------------------------
% 调用mmreader函数创建读取视频文件的多媒体阅读对象WalkManObj
WalkManObj = mmreader('WalkingMan.avi');
% 根据多媒体阅读对象WalkManObj,读取视频的各帧图像数据
IM = read(WalkManObj, [1, inf]);
[m,n,k,h] = size(IM); % 把IM的大小赋给四个变量
% 把IM转换成一个80行,240×360×3列的矩阵
I = reshape(IM,[m*n*k,h])';
I = median(I); % 求I矩阵中各列元素的中位数
I = reshape(I,[m,n,k]); % 将向量I转成240×360×3的三维数组,得到背景图像
figure; % 新建一个图形窗口
imshow(I); % 显示背景图像
figure; % 新建一个图形窗口
imshow(IM(:,:,:,1) - I); % 显示第1帧中的目标图像