Opencv中的大津阈值分割算法

 大津阈值分割算法,返回的阈值可以用于分割图像,对图像进行二值化处理、边缘检测等。

输入:

Mat 类型的地址(如Otsu(&src);)

输出:

返回一个int类型的阈值。

int  Otsu(Mat* src)
{
	int iHeight = src->rows;			 // 图片高度
	int iWidth = src->cols;             // 图片宽度
	long lSize = iHeight * iWidth;       // 图片大小

	float fHistogram[256] = { 0 };
	for (int i = 0; i < iHeight; i++) {
		unsigned char* p = (unsigned char*)src->data + src->step * i;
		for (int j = 0; j < iWidth; j++)
			fHistogram[int(*p++)]++;
	}

	int    iThreshold;                         // 返回的阈值
	long   lFrontgroundTotalGrayValue = 0,
		lBackgroundTotalGrayValue = 0;      // 存储前景的灰度总和和背景灰度总和  
	long   lFrontgroundTotalNum = 0,
		lBackgroundTotalNum = 0;            // 前景的总个数和背景的总个数  
	double dbFrontgroundRation = 0,
		dbBackgroundRation = 0;             // 前景和背景所占整幅图像的比例  
	double dbFrontgroundAveGrayValue = 0,
		dbBackgroundAveGrayValue = 0;       // 前景和背景的平均灰度  
	double dbVariance = 0;                     // 最大类间方差  
	double dbAveGrayValue = 0;
	double dbMaxVariance = 0;

	for (int i = 1; i < 256; i++) //一次遍历每个像素  
	{
		// 重新初始化
		lFrontgroundTotalGrayValue = 0;
		lBackgroundTotalGrayValue = 0;
		lFrontgroundTotalNum = 0;
		lBackgroundTotalNum = 0;
		dbFrontgroundRation = 0;
		dbBackgroundRation = 0;

		for (int j = 0; j < i; j++)
		{
			lFrontgroundTotalNum += (long)(fHistogram[j]);
			lFrontgroundTotalGrayValue += (long)(j * fHistogram[j]);
		}

		dbFrontgroundAveGrayValue = (double)lFrontgroundTotalGrayValue / lFrontgroundTotalNum;
		dbFrontgroundRation = (double)lFrontgroundTotalNum / lSize;

		for (int j = i; j < 256; j++)
		{
			lBackgroundTotalNum += (long)fHistogram[j];
			lBackgroundTotalGrayValue += (long)(j * fHistogram[j]);
		}

		dbBackgroundAveGrayValue = (double)lBackgroundTotalGrayValue / lBackgroundTotalNum;
		dbBackgroundRation = 1 - dbFrontgroundRation; // (double)lBackgroundTotalNum / size;  

		dbAveGrayValue = dbFrontgroundAveGrayValue * dbFrontgroundRation
			+ dbBackgroundAveGrayValue * dbBackgroundRation; //图像的平均灰度  
		dbVariance = dbFrontgroundRation * dbBackgroundRation * (dbFrontgroundAveGrayValue - dbBackgroundAveGrayValue)
			* (dbFrontgroundAveGrayValue - dbBackgroundAveGrayValue);
		if (dbVariance > dbMaxVariance)
		{
			dbMaxVariance = dbVariance;
			iThreshold = i;
		}
	}

	printf("iThreshold = %d\n", iThreshold);
	return iThreshold;
}

你可能感兴趣的:(opencv,算法,人工智能)