您的位置:首页 > 编程语言 > MATLAB

MATLAB实现的视频运动检测方法

2015-12-15 15:37 495 查看
阅前提示,本文是坑,此路不通,请看下篇。

遇到一个问题。有一个视频,需要计算各帧之间的全局的相对运动(或者可以理解为相机的平动)。经过一番查找,大致有三种思路。

无论哪一种方法,都最好先用After Effects处理一下,添加一些模糊啊、裁边的效果,以降低噪音。

 

第一,如果视频数量很少,可以使用一些tricky的方法,人工提取视频的特点。比如说,如果始终能捕捉到某一特定区域的全貌,而不会跑到边缘或者消失,而且该区域不会变形,那么可以计算这个区域的平均位置。计算方法:

x坐标=求和(区域上各点x坐标)/区域上点的数量;

y坐标=求和(区域上各点y坐标)/区域上点的数量;

如果能很好满足前提条件,这样的算法能轻松实现高精度的运动检测。

步骤简述:

1、读取视频

2、选择合适的阈值进行二值化

3、排除干扰区域,提取出目标区域(这步每个视频都不一样,tricky所在)

4、计算目标区域的平均位置。

缺点:对每个视频都要重新配置,而且不一定好用。

如果可以,在拍摄时就要注意包含容易提取的区域。

 

第二,MPEG有motion vector。视频各帧间各区域的运动情况,可以有助于视频压缩,所以很早就应用于视频压缩技术中。在Linux中运行【ffplay –vismv 3 ***.mp4】,可以看到motion vector的播放。不过如何提取出来是个问题,而且它计算出了视频中多个区域的运动向量,跟我们的目标不一样。

这条路我没有走通,倒是在github上有一个个人项目:https://github.com/victorhsieh/motion-vector

 

第三,图像相关识别。MATLAB上有内置函数vision.BlockMatcher.以下是我在用的片段,改编自帮助文档的示例。

vObj = VideoReader('***.avi');

I1 = im2double(rgb2gray(readFrame(vObj)));

s = size(I1);

hbm = vision.BlockMatcher('ReferenceFrameSource', 'Input port', 'BlockSize', round(s/2)*2-1);

hbm.OutputValue = 'Horizontal and vertical components in complex form';

hbm.MaximumDisplacement = round(s/3)*2;

hbm.SearchMethod = 'Three-step';

k = 1;

while hasFrame(vObj)

   I2 = im2double(rgb2gray(readFrame(vObj)));

   m = step(hbm,I1,I2);

   motion(:,k) = m(:);

   k = k+1;

end

save('***.mat');

改动的地方:

1、Block Size改为全局。因为我只要一个运动向量。

2、最大位移改为全局大小的2/3,这个根据实际需要改。

3、搜索策略改为“三步”,因为原来的“逐像素”搜索太慢了,得大约十多分钟才处理一帧。现在大约十多秒一帧。

4、输出保存为.mat文件。

得到一个motion变量,它是一个复数,实部和虚部分别是目标帧相对第一帧在两个方向上的位置变化。

 

更多资料,请搜索:

数字图像相关识别 digital image correlation

图像相关性 image cross-correlation

运动向量 motion vector

(全局)运动估计 (global) motion estimation

注意,motion estimation中提到有几种方法,如基于特征、基于傅里叶分析等,本文不述。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: