2、阈值分割(为提高算法的实时性,我们下面的算法至对采集到的图像的奇数场进行处理)
这里采用灰度图像下的阈值化方法进行阈值分割,具体使用的算法是迭代阈值分割。
迭代阈值分割是一种针对复杂图像的分割方法。首先根据图像的全局直方图,将取了阈值后得到的区域看成是子图像,在此对各子图像作直方图选峰值点及区域值,不断重复上述过程,直到找不到新的峰值点或区域变得太小为止。这种算法利用不断更新的子图像直方图,随着循环的增加,越来越细的考虑了图像的局部特性。
其具体实现代码如下:
int DetectThreshold(unsigned int Image,int intALines,int intAPixels, int intDLines,int intDPixels) { unsigned int data; //循环变量 int i, j; //像素值 unsigned char pixel; //直方图数组 int lHistogram[256]; //阈值,最大灰度值与最小灰度值,两个区域的平均灰度值 unsigned char iThreshold, iNewThreshold, iMaxGrayValue, iMinGrayValue, iMean1GrayValue, iMean2GrayValue; //用于计算区域灰度平均值的中间变量 int lP1,lP2,lS1,lS2; //迭代次数 int iIterationTimes; int numPixels; //直方图数组赋初值0 for (i = 0; i < 256;i++) lHistogram[i]=0; //获得源图像的直方图、最大与最小灰度值 iMaxGrayValue = 0; iMinGrayValue = 255; numPixels = 720; data = Image; //统计每个灰度级中像素的个数 for(i = intALines; i < intDLines; i++) { for(j = intAPixels;j < intDPixels;j+=2) { pixel = *(Uint8 *)(data + i*numPixels + j); //修改最大,最小灰度值 iMinGrayValue = (iMinGrayValue > pixel?pixel:iMinGrayValue); iMaxGrayValue = (iMaxGrayValue < pixel?pixel:iMaxGrayValue); lHistogram[pixel]++; // pixel = *(Uint8 *)(data + (i+288)*numPixels + j); // iMinGrayValue = (iMinGrayValue > pixel?pixel:iMinGrayValue); // iMaxGrayValue = (iMaxGrayValue < pixel?pixel:iMaxGrayValue); // lHistogram[pixel]++; pixel = *(Uint8 *)(data + i*numPixels + j+1); //修改最大,最小灰度值 iMinGrayValue = (iMinGrayValue > pixel?pixel:iMinGrayValue); iMaxGrayValue = (iMaxGrayValue < pixel?pixel:iMaxGrayValue); lHistogram[pixel]++; // pixel = *(Uint8 *)(data + (i+288)*numPixels + j+1); // iMinGrayValue = (iMinGrayValue > pixel?pixel:iMinGrayValue); // iMaxGrayValue = (iMaxGrayValue < pixel?pixel:iMaxGrayValue); // lHistogram[pixel]++; } } //迭代求最佳阈值 iNewThreshold = (iMinGrayValue + iMaxGrayValue)/2; iThreshold = 0; for(iIterationTimes = 0; iThreshold != iNewThreshold && iIterationTimes < 100;iIterationTimes ++) { iThreshold = iNewThreshold; lP1 =0; lP2 =0; lS1 = 1; lS2 = 1; //求两个区域的灰度平均值 for (i = iMinGrayValue;i < iThreshold;i++) { lP1 += lHistogram[i]*i; //像素值之和 lS1 += lHistogram[i]; //像素个数 } iMean1GrayValue = (unsigned char)(lP1 / lS1); //第一个区域的灰度平均值 for (i = iThreshold+1;i < iMaxGrayValue;i++) { lP2 += lHistogram[i]*i; //像素值之和 lS2 += lHistogram[i]; //像素个数 } iMean2GrayValue = (unsigned char)(lP2 / lS2); //第一个区域的灰度平均值 iNewThreshold = (iMean1GrayValue + iMean2GrayValue)/2; //更新阈值 } return iThreshold; }3、二值化
根据步骤2中得到的阈值,对图像进行二值化处理。
cvThreshold(tempYbuffer, Threshold, intALines,intAPixels,intDLines,intDPixels);4、确定形心
形心,即图像目标的几何中心,对于准确的定位目标具有很重要的意义[。形心获取通常采用形心识别算法,又称形心跟踪算法,它是波门跟踪算法的一种。采用形心识别算法时要求目标的灰度级一致,无明显的纹理变化,目标灰度与背景灰度差异较大。这样,目标能够从背景中清晰的提取出来。形心算法的计算方法简单,计算量较小,在短时间内就可以完成计算,输出目标的位置,速度上能满足系统的要求。但形心跟踪算法只适用于目标和背景相对简单的系统。在简单背景模式下,形心算法比较有效,不论速度还是精度都能达到要求,但在复杂背景下,由于目标的提取有一定的困难,所以跟踪的性能会有所下降.这是它的局限性。所以形心跟踪算法对简单背景的运动目标有效,而对于背景复杂的目标跟踪效果不够理想。
形心的计算格式如下:
处理函数为:
objectDection(tempYbuffer,&rect);5、目标跟踪
利用步骤4中得到目标的形心,以形心为中心扩展一个跟踪框,框住目标,如选用40*40pixels或其他矩阵框。接下来对每一帧图像都采取以上步骤,便可以实现简单背景下的目标跟踪。
以下是DM642上形心跟踪的效果图: