zoukankan      html  css  js  c++  java
  • Camshift原理 及其OpenCV实现

    Camshift原理

    camshift利用目标的颜色直方图模型将图像转换为颜色概率分布图,初始化一个搜索窗的大小和位置,并根据上一帧得到的结果自适应调整搜索窗口的位置和大小,从而定位出当前图像中目标的中心位置。
    分为三个部分:
    1--色彩投影图(反向投影):
    (1).RGB颜色空间对光照亮度变化较为敏感,为了减少此变化对跟踪效果的影响,首先将图像从RGB空间转换到HSV空间。(2).然后对其中的H分量作直方图,在直方图中代表了不同H分量值出现的概率或者像素个数,就是说可以查找出H分量大小为h的概率或者像素个数,即得到了颜色概率查找表。(3).将图像中每个像素的值用其颜色出现的概率对替换,就得到了颜色概率分布图。这个过程就叫反向投影,颜色概率分布图是一个灰度图像。
    2--meanshift
    meanshift算法是一种密度函数梯度估计的非参数方法,通过迭代寻优找到概率分布的极值来定位目标。
    算法过程为:
    (1).在颜色概率分布图中选取搜索窗W
    (2).计算零阶距:
    转载:Camshift算法原理及其Opencv实现 - qiqi - ♂My Love¤Your Song♀
    计算一阶距:
    转载:Camshift算法原理及其Opencv实现 - qiqi - ♂My Love¤Your Song♀
    计算搜索窗的质心:
    转载:Camshift算法原理及其Opencv实现 - qiqi - ♂My Love¤Your Song♀
    (3).调整搜索窗大小
    宽度为转载:Camshift算法原理及其Opencv实现 - qiqi - ♂My Love¤Your Song♀;长度为1.2s;
    (4).移动搜索窗的中心到质心,如果移动距离大于预设的固定阈值,则重复2)3)4),直到搜索窗的中心与质心间的移动距离小于预设的固定阈值,或者循环运算的次数达到某一最大值,停止计算。关于meanshift的收敛性证明可以google相关文献。
    3--camshift
    将meanshift算法扩展到连续图像序列,就是camshift算法。它将视频的所有帧做meanshift运算,并将上一帧的结果,即搜索窗的大小和中心,作为下一帧meanshift算法搜索窗的初始值。如此迭代下去,就可以实现对目标的跟踪。
    算法过程为:
    (1).初始化搜索窗
    (2).计算搜索窗的颜色概率分布(反向投影)
    (3).运行meanshift算法,获得搜索窗新的大小和位置。
    (4).在下一帧视频图像中用(3)中的值重新初始化搜索窗的大小和位置,再跳转到(2)继续进行。
    camshift能有效解决目标变形和遮挡的问题,对系统资源要求不高,时间复杂度低,在简单背景下能够取得良好的跟踪效果。但当背景较为复杂,或者有许多与目标颜色相似像素干扰的情况下,会导致跟踪失败。因为它单纯的考虑颜色直方图,忽略了目标的空间分布特性,所以这种情况下需加入对跟踪目标的预测算法。


    Camshift的opencv实现
    原文http://blog.csdn.net/houdy/archive/2004/11/10/175739.aspx
    1--Back Projection
    计算Back Projection的OpenCV代码。
    (1).准备一张只包含被跟踪目标的图片,将色彩空间转化到HSI空间,获得其中的H分量:
    IplImage* target=cvLoadImage("target.bmp",-1); //装载图片
    IplImage* target_hsv=cvCreateImage( cvGetSize(target), IPL_DEPTH_8U, 3 );
    IplImage* target_hue=cvCreateImage( cvGetSize(target), IPL_DEPTH_8U, 3 );
    cvCvtColor(target,target_hsv,CV_BGR2HSV); //转化到HSV空间
    cvSplit( target_hsv, target_hue, NULL, NULL, NULL ); //获得H分量
    (2).计算H分量的直方图,即1D直方图:
    IplImage* h_plane=cvCreateImage( cvGetSize(target_hsv),IPL_DEPTH_8U,1 );
    int hist_size[]={255}; //将H分量的值量化到[0,255]
    float* ranges[]={ {0,360} }; //H分量的取值范围是[0,360)
    CvHistogram* hist=cvCreateHist(1, hist_size, ranges, 1);
    cvCalcHist(&target_hue, hist, 0, NULL);
    在这里需要考虑H分量的取值范围的问题,H分量的取值范围是[0,360),这个取值范围的值不能用一个byte来表示,为了能用一个byte表示,需要将H值做适当的量化处理,在这里我们将H分量的范围量化到[0,255]。
    (3).计算Back Projection:
    IplImage* rawImage;
    //get from video frame,unsigned byte,one channel
    IplImage* result=cvCreateImage(cvGetSize(rawImage),IPL_DEPTH_8U,1);
    cvCalcBackProject(&rawImage,result,hist);
    (4). result即为我们需要的.
    2--Mean Shift算法
    质心可以通过以下公式来计算:
    (1).计算区域内0阶矩
    for(int i=0;i< height;i++)
    for(int j=0;j< width;j++)
    M00+=I(i,j)
    (2).区域内1阶矩:
    for(int i=0;i< height;i++)
    for(int j=0;j< width;j++)
    {
    M10+=i*I(i,j);
    M01+=j*I(i,j);
    }
    (3).则Mass Center为:
    Xc=M10/M00; Yc=M01/M00
    在OpenCV中,提供Mean Shift算法的函数,函数的原型是:
    int cvMeanShift(IplImage* imgprob,CvRect windowIn,
    CvTermCriteria criteria,CvConnectedComp* out);
    需要的参数为:
    (1).IplImage* imgprob:2D概率分布图像,传入;
    (2).CvRect windowIn:初始的窗口,传入;
    (3).CvTermCriteria criteria:停止迭代的标准,传入;
    (4).CvConnectedComp* out:查询结果,传出。
    注:构造CvTermCriteria变量需要三个参数,一个是类型,另一个是迭代的最大次数,最后一个表示特定的阈值。例如可以这样构造 criteria:
    criteria=cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,10,0.1)。
    3--CamShift算法
    整个算法的具体步骤分5步:
    Step 1:将整个图像设为搜寻区域。
    Step 2:初始话Search Window的大小和位置。
    Step 3:计算Search Window内的彩色概率分布,此区域的大小比Search Window要稍微大一点。
    Step 4:运行MeanShift。获得Search Window新的位置和大小。
    Step 5:在下一帧视频图像中,用Step 3获得的值初始化Search Window的位置和大小。跳转到Step 3继续运行。
    OpenCV代码:
    在OpenCV中,有实现CamShift算法的函数,此函数的原型是:
    cvCamShift(IplImage* imgprob, CvRect windowIn,
    CvTermCriteria criteria,
    CvConnectedComp* out, CvBox2D* box=0);
    其中:
    imgprob:色彩概率分布图像。
    windowIn:Search Window的初始值。
    Criteria:用来判断搜寻是否停止的一个标准。
    out:保存运算结果,包括新的Search Window的位置和面积。
    box:包含被跟踪物体的最小矩形。
    更多参考:
    带有注释的camshift算法的opencv实现代码见:
    http://download.csdn.net/source/1663015
    做一件有意义的事是很容易的事,困难的是一直坚持做,坚持那颗用不服输的心,坚持学习,坚持。。。
  • 相关阅读:
    Delphi公用函数单元
    Delphi XE5 for Android (十一)
    Delphi XE5 for Android (十)
    Delphi XE5 for Android (九)
    Delphi XE5 for Android (八)
    Delphi XE5 for Android (七)
    Delphi XE5 for Android (五)
    Delphi XE5 for Android (四)
    Delphi XE5 for Android (三)
    Delphi XE5 for Android (二)
  • 原文地址:https://www.cnblogs.com/rosekin/p/2996474.html
Copyright © 2011-2022 走看看