Cv运动分析与对象跟踪

转载,出自点击打开链接

目录 
1 背景统计量的累积
1.1 Acc
1.2 SquareAcc
1.3 MultiplyAcc
1.4 RunningAvg
2 运动模板
2.1 UpdateMotionHistory
2.2 CalcMotionGradient
2.3 CalcGlobalOrientation
2.4 SegmentMotion
3 对象跟踪
3.1 MeanShift
3.2 CamShift
3.3 SnakeImage
4 光流
4.1 CalcOpticalFlowHS
4.2 CalcOpticalFlowLK
4.3 CalcOpticalFlowBM
4.4 CalcOpticalFlowPyrLK
5 预估器
5.1 CvKalman
5.2 CreateKalman
5.3 ReleaseKalman
5.4 KalmanPredict
5.5 KalmanCorrect
5.6 CvConDensation
5.7 CreateConDensation
5.8 ReleaseConDensation
5.9 ConDensInitSampleSet
5.10 ConDensUpdateByTime


1.背景统计量的累积:
1.1)Acc:将帧叠加到累积器(accumulator)中

void cvAcc( const CvArr* image, CvArr* sum, const CvArr* mask=NULL );
image
输入图像, 1- 或 3-通道, 8-比特或32-比特浮点数. (多通道的每一个通道都单独处理).
sum
同一个输入图像通道的累积,32-比特或64-比特浮点数数组.
mask
可选的运算 mask.
函数 cvAcc 将整个图像 image 或某个选择区域叠加到 sum 中:

sum(x,y)=sum(x,y)+image(x,y) if mask(x,y)!=0

1.2)SquareAcc:叠加输入图像的平方到累积器中

void cvSquareAcc( const CvArr* image, CvArr* sqsum, const CvArr* mask=NULL );
image
输入图像, 1- 或 3-通道, 8-比特或32-比特浮点数 (多通道的每一个通道都单独处理)
sqsum
同一个输入图像通道的累积,32-比特或64-比特浮点数数组.
mask
可选的运算 mask.
函数 cvSquareAcc 叠加输入图像 image 或某个选择区域的二次方,到累积器 sqsum 中

sqsum(x,y)=sqsum(x,y)+image(x,y)2 if mask(x,y)!=0

1.3)MultiplyAcc:将两幅输入图像的乘积叠加到累积器中

void cvMultiplyAcc( const CvArr* image1, const CvArr* image2, CvArr* acc, const CvArr* mask=NULL );
image1
第一个输入图像, 1- or 3-通道, 8-比特 or 32-比特 浮点数 (多通道的每一个通道都单独处理)
image2
第二个输入图像, 与第一个图像的格式一样
acc
同一个输入图像通道的累积,32-比特或64-比特浮点数数组.
mask
可选的运算 mask.
函数 cvMultiplyAcc 叠加两个输入图像的乘积到累积器 acc:

acc(x,y)=acc(x,y) + image1(x,y)•image2(x,y) if mask(x,y)!=0

1.4)RunningAvg:更新 running average 滑动平均( Hunnish: 不知道 running average 如何翻译才恰当)

void cvRunningAvg( const CvArr* image, CvArr* acc, double alpha, const CvArr* mask=NULL );
image
输入图像, 1- or 3-通道, 8-比特 or 32-比特 浮点数 (each channel of multi-channel image is processed independently).
acc
同一个输入图像通道的累积,32-比特或64-比特浮点数数组.
alpha
输入图像权重
mask
可选的运算 mask
函数 cvRunningAvg 计算输入图像 image 的加权和,以及累积器 acc 使得 acc 成为帧序列的一个 running average:

acc(x,y)=(1-α)•acc(x,y) + α•image(x,y) if mask(x,y)!=0
其中 α (alpha) 调节更新速率 (累积器以多快的速率忘掉前面的帧).


2.运动模板

2.1)UpdateMotionHistory:去掉影像(silhouette) 以更新运动历史图像

void cvUpdateMotionHistory( const CvArr* silhouette, CvArr* mhi,double timestamp, double duration );
silhouette
影像 mask,运动发生地方具有非零象素
mhi
运动历史图像(单通道, 32-比特 浮点数),为本函数所更新
timestamp
当前时间,毫秒或其它单位
duration
运动跟踪的最大持续时间,用 timestamp 一样的时间单位
函数 cvUpdateMotionHistory 用下面方式更新运动历史图像:

mhi(x,y)=timestamp  if silhouette(x,y)!=0
         0          if silhouette(x,y)=0 and mhi(x,y)<timestamp-duration
         mhi(x,y)   otherwise
也就是,MHI(motion history image) 中在运动发生的象素点被设置为当前时间戳,而运动发生较久的象素点被清除。

2.2)CalcMotionGradient:计算运动历史图像的梯度方向

void cvCalcMotionGradient( const CvArr* mhi, CvArr* mask, CvArr* orientation,
                           double delta1, double delta2, int aperture_size=3 );
mhi
运动历史图像
mask
Mask 图像;用来标注运动梯度数据正确的点,为输出参数。
orientation
运动梯度的方向图像,包含从 0 到 360 角度
delta1, delta2
函数在每个象素点 (x,y) 邻域寻找 MHI 的最小值 (m(x,y)) 和最大值 (M(x,y)),并且假设梯度是正确的,当且仅当:
min(delta1,delta2) <= M(x,y)-m(x,y) <= max(delta1,delta2).
aperture_size
函数所用微分算子的开孔尺寸 CV_SCHARR, 1, 3, 5 or 7 (见 cvSobel).
函数 cvCalcMotionGradient 计算 MHI 的差分 Dx 和 Dy ,然后计算梯度方向如下式:

orientation(x,y)=arctan(Dy(x,y)/Dx(x,y))
其中都要考虑 Dx(x,y)' 和 Dy(x,y)' 的符号 (如 cvCartToPolar 类似). 然后填充 mask 以表示哪些方向是正确的(见 delta1 和delta2 的描述).

2.3)CalcGlobalOrientation:计算某些选择区域的全局运动方向

double cvCalcGlobalOrientation( const CvArr* orientation, const CvArr* mask, const CvArr* mhi,
                                double timestamp, double duration );
orientation
运动梯度方向图像,由函数 cvCalcMotionGradient 得到
mask
Mask 图像. 它可以是正确梯度 mask (由函数 cvCalcMotionGradient 得到)与区域 mask 的结合,其中区域 mask 确定哪些方向需要计算。
mhi
运动历史图象
timestamp
当前时间(单位毫秒或其它)最好在传递它到函数 cvUpdateMotionHistory 之前存储一下以便以后的重用,因为对大图像运行 cvUpdateMotionHistory 和 cvCalcMotionGradient 会花费一些时间
duration
运动跟踪的最大持续时间,用法与 cvUpdateMotionHistory 中的一致
函数 cvCalcGlobalOrientation 在选择的区域内计算整个运动方向,并且返回 0° 到 360° 之间的角度值。首先函数创建运动直方图,寻找基本方向做为直方图最大值的坐标。然后函数计算与基本方向的相对偏移量,做为所有方向向量的加权和:运行越近,权重越大。得到的角度是基本方向和偏移量的循环和。

2.4)SegmentMotion:将整个运动分割为独立的运动部分

CvSeq* cvSegmentMotion( const CvArr* mhi, CvArr* seg_mask, CvMemStorage* storage,
                        double timestamp, double seg_thresh );
mhi
运动历史图像
seg_mask
发现应当存储的 mask 的图像, 单通道, 32bits, 浮点数.
storage
包含运动连通域序列的内存存储仓
timestamp
当前时间,毫秒单位
seg_thresh
分割阈值,推荐等于或大于运动历史“每步”之间的间隔。
函数 cvSegmentMotion 寻找所有的运动分割,并且在seg_mask 用不同的单独数字(1,2,...)标识它们。它也返回一个具有 CvConnectedComp 结构的序列,其中每个结构对应一个运动部件。在这之后,每个运动部件的运动方向就可以被函数 cvCalcGlobalOrientation 利用提取的特定部件的掩模(mask)计算出来(使用 cvCmp)


3.对象跟踪
3.1)MeanShift:在反向投影图中发现目标中心

int cvMeanShift( const CvArr* prob_image, CvRect window,CvTermCriteria criteria, CvConnectedComp* comp );
prob_image
目标直方图的反向投影(见 cvCalcBackProject).
window
初始搜索窗口
criteria
确定窗口搜索停止的准则
comp
生成的结构,包含收敛的搜索窗口坐标 (comp->rect 字段) 与窗口内部所有象素点的和 (comp->area 字段).
函数 cvMeanShift 在给定反向投影和初始搜索窗口位置的情况下,用迭代方法寻找目标中心。当搜索窗口中心的移动小于某个给定值时或者函数已经达到最大迭代次数时停止迭代。 函数返回迭代次数。

3.2)CamShift:发现目标中心,尺寸和方向

int cvCamShift( const CvArr* prob_image, CvRect window, CvTermCriteria criteria,
                CvConnectedComp* comp, CvBox2D* box=NULL );
prob_image
目标直方图的反向投影 (见 cvCalcBackProject).
window
初始搜索窗口
criteria
确定窗口搜索停止的准则
comp
生成的结构,包含收敛的搜索窗口坐标 (comp->rect 字段) 与窗口内部所有象素点的和 (comp->area 字段).
box
目标的带边界盒子。如果非 NULL, 则包含目标的尺寸和方向。
函数 cvCamShift 实现了 CAMSHIFT 目标跟踪算法([Bradski98]). 首先它调用函数 cvMeanShift 寻找目标中心,然后计算目标尺寸和方向。最后返回函数 cvMeanShift 中的迭代次数。

CvCamShiftTracker 类在 cv.hpp 中被声明,函数实现了彩色目标的跟踪。

3.3)SnakeImage:改变轮廓位置使得它的能量最小

void cvSnakeImage( const IplImage* image, CvPoint* points, int length,
                   float* alpha, float* beta, float* gamma, int coeff_usage,
                   CvSize win, CvTermCriteria criteria, int calc_gradient=1 );
image
输入图像或外部能量域
points
轮廓点 (snake).
length
轮廓点的数目
alpha
连续性能量的权 Weight[s],单个浮点数或长度为 length 的浮点数数组,每个轮廓点有一个权
beta
曲率能量的权 Weight[s],与 alpha 类似
gamma
图像能量的权 Weight[s],与 alpha 类似
coeff_usage
前面三个参数的不同使用方法:
CV_VALUE 表示每个 alpha, beta, gamma 都是指向为所有点所用的一个单独数值;
CV_ARRAY 表示每个 alpha, beta, gamma 是一个指向系数数组的指针,snake 上面各点的系数都不相同。因此,各个系数数组必须与轮廓具有同样的大小。所有数组必须与轮廓具有同样大小
win
每个点用于搜索最小值的邻域尺寸,两个 win.width 和 win.height 都必须是奇数
criteria
终止条件
calc_gradient
梯度符号。如果非零,函数为每一个图像象素计算梯度幅值,且把它当成能量场,否则考虑输入图像本身。
函数 cvSnakeImage 更新 snake 是为了最小化 snake 的整个能量,其中能量是依赖于轮廓形状的内部能量(轮廓越光滑,内部能量越小)以及依赖于能量场的外部能量之和,外部能量通常在哪些局部能量极值点中达到最小值(这些局部能量极值点与图像梯度表示的图像边缘相对应)。

参数 criteria.epsilon 用来定义必须从迭代中除掉以保证迭代正常运行的点的最少数目。

如果在迭代中去掉的点数目小于 criteria.epsilon 或者函数达到了最大的迭代次数 criteria.max_iter ,则终止函数。


(未完待续)


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值