opencv python 多帧降噪算法_基于Camshift算法的小球跟踪

引言

最近上计算机视觉课,布置了一个作业,是进行三个小球的跟踪,具体的场景如下图,目的就是跟踪三个小球,在三个小球的运动过程中用三个方框将其框住,且必须分别框住,不能连在一起。

f6f3dab911d4f13a4fae43fd426bc8a0.png


图1 小球跟踪场景

环境配置

在这里我使用的Python OpenCV库来辅助实现小球跟踪,具体在Windows环境下,Python OpenCV的安装配置过程如下(假定你们已经安装Python 3.x和pip工具,不懂安装Python的可自行百度)
打开Windows系统的cmd(命令行界面,在开始中找),然后执行如下指令安装所需的Python科学计算库Numpy和绘图库matplotlib:
pip install numpy
pip install matplotlib
对于OpenCV的安装,可现在Python Extension Packages for Windows下载对应的OpenCV安装包,注意对应版本。然后同理,在cmd中,cd到对应下载路径,然后输入如下指令:
pip install 下载的安装包的名字

如果完成上述步骤且不报错,同时在cmd中打开Python,然后输入import cv2后不报错,那么表明安装OpenCV成功。当然还有其他安装方式,可参考:windows下的python+ opencv安装攻略

Camshift算法

说完了环境配置,我们就准备开始进行Camshift算法的讲解吧。

基于颜色分布的连续自适应均值漂移算法 (CamShift),是一种基于概率分布图的 MeanShift 算法。最早是由 Bradskit的,该算法在可以在目标在图像中由于距离变化或发生形变时自适应调节窗口的大小,有效解决了跟踪过程中的目标变形问题,在简单背景且目标与环境颜色特征差别较明显的场景够获得很好的跟踪效果。

注意以上的几个要点,Camshift是基于Meanshift算法提出的,是一种基于概率分布图的算法,同时在跟踪过程能够自适应目标的形变,当然,Camshift的效果较好的运用场景是环境背景颜色和目标颜色差异较大(毕竟是基于颜色跟踪)。

其基本思想可总结如下:利用目标的颜色直方图模型将当前帧图像反向投影为概率分布图,初始化搜索窗的尺寸和位置,并根据上一帧得到的结果自适应调整搜索窗口的位置和大小,从而定位出当前图像中目标的中心位置

基本的算法流程如下

1、计算目标的颜色直方图和当前图像的概率分布图。在计算目标直方图模型时,由于 HSV 空间中的 H 分量可以表示颜色信息,所以在计算过程中,可以先将其他的色彩空间的值转化到 HSV 空间,只求 H 分量的 1D 直方图。然后利用此 H分量的直方图对每帧图像做反向投影,然后计算整幅图像对应的概率分布图。所谓的反向投影就是在当前帧图像的搜索区域内,通过对每个像素点的当前值查询目标的颜色直方图,确定该点属于目标的概率。

2、均值漂移确定窗口中心。首先初始化包含目标的初始搜索窗,获得初始化窗口的中心点和尺寸信息。按照零阶矩和一阶矩公式计算目标质心位置和目标的大小,并根据质心位置重新设置搜索窗口的位置和尺寸参数。重复这一过程直到质心到窗口中心点的距离小于给定阈值(即新算出的质心位置距离上一次计算所得的质心位置的距离小于某个阈值时停止,我写的程序中采用的是欧氏距离)为止。

3、连续自适应目标跟踪过程。就是在连续的图像序列上,对输入的每一帧图像都利用前一帧确定的目标区域位置和尺寸信息作为初始值,重复进行(2)过程,以达到对目标的持续跟踪目的。

几个问题的解释

反向投影

1、首先计算目标区域的直方图,程序中计算的直方图的离散灰度等级为12,因为H通道图的值分布为0-179,则计算出来的直方图是每15个灰度值为一个等级,如0-14即等级1,15-29即等级2......以此类推。

2、计算整幅图像关于目标区域直方图的概率分布图,计算方式其实非常简单。假设1步中计算的直方图分为m级,每一级直方图对应值用

表示,对应的直方图索引用
表示。输入一帧完整图片,计算帧中每个像素的像素值对应于目标区域直方图的哪一等级,然后将对应等级的直方图的值赋给该像素。记原像素值对应目标位置的直方图的直方图索引为
,新像素值为
则用公式可表示为:

为了使得计算出来的概率图每一点的像素值都在0~255之间,此时需要做如下的处理:

,其中
是目标直方图的最大值。

如果不太理解上述的过程,可以参考下图,其思想是一样的,只是下面是针对灰度图,上面的算法流程是针对HSV图的H通道。

49819a67e49db44b0ded83eba16dd295.png

零阶矩,一阶矩的计算

零阶矩公式:

一阶矩公式:

其中

指的是图像在
处像素的像素值,在这里就是概率分布图在
处的像素值。

通过零阶矩和一阶矩,就可以算出目标的当前的质心位置和面积大小,公式如下:

目标质心位置

目标当前的大小

目标有背景某处的颜色相似,或者目标暂时找不到怎么办

针对本题,其中跑道和中间小球的颜色是相近的,此时单纯利用HSV图的H通道分量是不足以分开中间小球和跑道,因此要结合HSV图的S通道进行处理,此时发现视频中每帧图像中,跑道的S分量都是大于150,因此在此采用的方法是简单地将图中S分量大于150的像素都置为0(即转变为黑色),得到的对比效果如下图,第一张图是未置零S分量大于150的像素的情况,第二张图则是置零S分量大于150的像素的情况,效果还是挺明显的,可以很好地将各小球从背景中提取出来。

86d6d5fa5f4b2a9bd6c1f9011d2e15ea.png

e979f90663a77443c14df23bcc5e551d.png

可能有人会问,那这样为什么还要提取H通道,直接提取前景即可识别出3个小球。但是本题的目的是为了分别框出3个小球,而3个小球在H通道的直方图特征是不同,因此可以说通过S通道的特征将小球从背景中提取出来,然后通过H通道的特征分开3个小球,从而实现分别检测的目的。

因此当发现目标的颜色属性和Camshift算法的要求不太相符时,可以采用结合多个通道的方法进行调整。
而针对目标暂时找不到的情况,可以采用的方式是扩大搜索范围,目标找不到的可能是因为目标的移动速度加快,导致该帧中的位置在下一帧中的位置变化过大,在初始搜索框范围内无法找到对应目标(提现为一阶矩计算所得的值为0),meanshift算法的过程总是在指定的搜索框(可看做是一个邻域)中寻找目标。因此可以在判断一阶矩为0的情况下扩大搜索框,然后重新搜索即可(对应的扩大搜索框的方式可参考程序)

Camshift实现小球跟踪代码

闲话不多说,还是看看代码实现,相信通过代码,应该会对算法有更深刻的认识(写的有点乱,勿喷,主体代码都有注释,欢迎留言交流。)。
Camshift实现小球跟踪代码 代码执行方式,在环境配置工作完成的前提下,直接运行Camshift_with_demo目录下的main函数(请在pycharm IDE中打开,或者按照提示修改一下源文件即可),然后就可以看到实际效果。

参考文献/Blog

1、基于MeanShift算法和卡尔曼滤波的视频目标跟踪技术研究_胡波

2、MeanShift粒子滤波算法在视频目标跟踪中的应用研究_张虎

3、Opencv中关于反向投影图的解释_幻语星云_新浪博客

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值