OpenCV-camShift 算法

OpenCV-CamShift 算法

1.概述

CamShift 算法 (Continuously AdaptiveMeanSifit),是对 MeanShift 算法 的改进,能够自动调节搜索窗口大小来适应目标的大小,可以跟踪视频中尺寸变化的目标。它也是一种 半自动跟踪算法 ,需要手动标定跟踪目标。基本思想是以视频图像中运动物体的颜色信息作为特征,对输入图像的每一帧分别作 MeanShift 运算,并将上一帧的目标中心和搜索窗口大小作为下一帧 MeanShift 算法的中心和搜索窗口大小的初始值,如此迭代下去,就可以实现对目标的跟踪。因为在每次搜索前将搜索窗口的位置和大小设置为运动目标当前中心的位置和大小,而运动目标通常在这区域附近,缩短了搜索时间;另外,在目标运动过程中,颜色变化不大,故该算法具有良好的鲁棒性。

/**@brief Finds an object center,size,and orientation.
 *@param probImage Back projection of the object histogram.
 *@param window Initial search window.
 *@parma criteria Stop criteria for the underlying meanShift.
 returns(in old interfaces) Number of iterations CAMSHIFT took to converge
 The function implement the CAMSHIFT object tracking algorithm @cite Bradski98.First,it finds an
 objec center using meanShift and hen adjusts the window size and finds the optimal rotation.
 The function returns the rotated rectangle structure that includes the object position,size,and orientation.The next position of the search window can be obtained with RotatedRect::boundingRect()
 */
 CV_EXPORTS_W RotatedRect CamShift(InputArray probImage, CV_IN_OUT Rect &window, TermCriteria criteria);

其中 probImage 为输入图像直方图的反向投影图,window 为要跟踪目标的初始位置矩形框,criteria 为算法结束条件。函数返回一个有方向角度的旋转矩阵。该函数的实现首先是利用 MeanShift 算法计算出要跟踪的中心,然后调整初始窗口的大小位置和方向角度。在 CamShift 内部调用了 MeanShift 算法计算目标的重心。

2.算法

2.1 算法流程图

Created with Raphaël 2.2.0 选择初始化搜索窗口的大小和位置 在搜索窗口位置设置比 搜索窗口大一点的计算区域 计算目标区域内 色调H的直方图 将直方图作反向投影, 得到色调H的概率分布图 得到搜索窗口的 质心位置 根据窗口中 像素值综合 调整窗口大小, 将搜索窗口 中心移动到 质心位置 收敛? 得到目标中心位置(x,y), 迭代的次数 用当前目标的质心(x,y) 和搜索窗口的大小初始化 下一帧搜索窗口 yes no

2.2 具体步骤

步骤一:计算目标区域内的颜色直方图。
通常是将输入图像转换到HSV颜色空间,目标区域为初始设定的搜索窗口范围,分离出色调H分量做该区域的色调直方图计算。因为 RGB 颜色空间对光线条件的改变较为敏感,要减小该因素对跟踪效果的影响,CamShift 算法通常采用 HSV 色彩空间进行处理,当然也可以用其它颜色空间计算。这样即得到目标模板的颜色直方图。
步骤二:根据获得的颜色直方图将原始输入图像转化成颜色概率分布图像,该过程称为“反向投影"。所谓直方图反向投影,就是输入图像在已知目标颜色直方图的条件下的颜色概率密度分布图,包含了目标在当前帧中的相干信息。对于输入图像中的每一个像素,查询目标模型颜色直方图,对于目标区域内的像素,可得到该像素属于目标像素的概率,而对于非目标区域内的像素,该概率为0。
步骤三:Mean Shift迭代过程。目的在于找到目标中心在当前帧中的位置。首先在颜色概率分布图中选择搜索窗口的大小和初始位置,然后计算搜索窗口的质心位置。设像素点(i, j)位于搜索窗口内,I(i, j)是颜色直方图的反向投影图中该像素点对应的值,定义搜索窗口的零阶矩 M00 和一阶矩M10,M01如下:

Alt
Alt
Alt
则搜索窗口的质心位置为:
Alt

接着调整搜索窗口中心到质心。零阶矩反映了搜索窗口尺寸,依据它调整窗口大小,并将搜索窗口的中心移到质心,如果移动距离大于设定的阈值,则重新计算调整后的窗口质心,进行新一轮的窗口位置和尺寸调整。直到窗口中心与质心之间的移动距离小于阈值,或者迭代次数达到某一最大值,认为收敛条件满足,将搜索窗口位置和大小作为下一帧的目标位置输入,开始对下一帧图像进行新的目标搜索。

3.程序

3.1 打开摄像头

VidelCapture cap;
cap.open(0);
if(!cap.isOpened())
{
     
	cout<<"Could not initialize camera"<<endl;
	return -1;
}

3.2 鼠标响应

static void onMouse(int event, int x, int y, int, void *)
{
     
	if(selectObject)
	{
     
		selection.x = MIN(x, origin.x);
        selection.y = MIN(y, origin.y);
        selection.width = std::abs(x - origin.x);
        selection.height = std::abs(y - origin.y);
        selection &= Rect(0, 0, image.cols, image.rows);
	}
	switch(event)
	{
     
	case EVENT_LBUTTONDOWN:
        origin = Point(x, y);
        selection = Rect(x, y, 0, 0);
        selectObject = true;
        break;
     case EVENT_LBUTTONUP:
        selectObject = false;
        if (selection.width > 0 && selection.height > 0)
            trackObject = -1;
        break;
	}
}
setMouseCallback("CamShift", onMouse, 0);

3.3 图像类型转换及阈值化

cvtColor(image, hsv, COLOR_BGR2HSV);
inRange(hsv, Scalar(0, smin, MIN(_vmin, _vmax)), Scalar(180, 256, MAX(_vmin, _vmax)), mask);

3.4 计算、归一化、绘制直方图

calcHist(&roi, 1, 0, maskroi, hist, 1, &hsize, &phranges);
normalize(hist, hist, 0, 255, NORM_MINMAX, -1);
for(int i=0; i<hsize; i++)
{
     
	int val = saturate_cast<int>(hist.at<float>(i)*histImg.rows/255);
	rectangle(histImg, Point(i*binW, histImg.rows), Point((i+1)*binW, histImg.rows-val), Scalar(buff.at<Vec3b>(i)), -1, 8);
}

3.5 反向投影

calcBackProject(&hue, 1, 0, hist, backproject, &phranges);

3.6 目标跟踪

RotatedRect trackBox=CamShift(backproject, trackWindow, TermCriteria(TermCriteria::EPS | TermCriteria::CONT, 10, 1));
ellipse(image, trackBox, Scalar(255,0,0), 3, LINE_AA);

4. 总结

CamShift算法改进了 MeanShift 跟踪算法的第二个缺陷,在跟踪过程中能够依据目标的尺寸调节搜索窗口大小,对 有尺寸变化的目标可准确定位。但是,一方面 CamShfit 算法在计算目标模板直方图分布时,没有使用核函数进行加权处理,也就是说目标区域内的每个像素点在目标模型中有着相同的权重,故 CamShfit 算法的抗噪能力低于MeanShift跟踪算法。另一方面,CamShift 算法中没有定义候选目标,直接利用目标模板进行跟踪。除此以外,CamShift 算法采用 HSV 色彩空间的H分量建立目标直方图模型,仍然只是依据目标的色彩信息来进行跟踪,当目标与背景颜色接近或者被其他物体遮挡时,CamShift 会自动将其包括在内,导致跟踪窗口扩大,有时甚至会将跟踪窗口扩大到整个视频大小,导致目标定位的不准确,连续跟踪下去造成目标的丢失。

你可能感兴趣的:(opencv)