C++ opencv 图片二值化最佳阈值确定(迭代法)

//opencv
#include "opencv2/opencv.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

/*************************************************
Function:       DetectThreshold
Description:    图片二值化最佳阈值确定(迭代法)
Input:          src:原图片
Return:         阈值
*************************************************/
int DetectThreshold(IplImage*src)
{
	uchar iThrehold;//阀值

	try
	{
		int height = src->height;
		int width = src->width;
		int step = src->widthStep / sizeof(uchar);
		uchar *data = (uchar*)src->imageData;

		int iDiffRec = 0;
		int F[256] = { 0 }; //直方图数组  
		int iTotalGray = 0;//灰度值和  
		int iTotalPixel = 0;//像素数和  
		uchar bt;//某点的像素值  

		uchar iNewThrehold;//新阀值
		uchar iMaxGrayValue = 0, iMinGrayValue = 255;//原图像中的最大灰度值和最小灰度值  
		uchar iMeanGrayValue1, iMeanGrayValue2;

		//获取(i,j)的值,存于直方图数组F  
		for (int i = 0; i < width; i++)
		{
			for (int j = 0; j < height; j++)
			{
				bt = data[i*step + j];
				if (bt < iMinGrayValue)
					iMinGrayValue = bt;
				if (bt > iMaxGrayValue)
					iMaxGrayValue = bt;
				F[bt]++;
			}
		}

		iThrehold = 0;
		iNewThrehold = (iMinGrayValue + iMaxGrayValue) / 2;//初始阀值  
		iDiffRec = iMaxGrayValue - iMinGrayValue;

		for (int a = 0; (abs(iThrehold - iNewThrehold) > 0.5); a++)//迭代中止条件  
		{
			iThrehold = iNewThrehold;
			//小于当前阀值部分的平均灰度值  
			for (int i = iMinGrayValue; i < iThrehold; i++)
			{
				iTotalGray += F[i] * i;//F[]存储图像信息  
				iTotalPixel += F[i];
			}
			iMeanGrayValue1 = (uchar)(iTotalGray / iTotalPixel);
			//大于当前阀值部分的平均灰度值  
			iTotalPixel = 0;
			iTotalGray = 0;
			for (int j = iThrehold + 1; j < iMaxGrayValue; j++)
			{
				iTotalGray += F[j] * j;//F[]存储图像信息  
				iTotalPixel += F[j];
			}
			iMeanGrayValue2 = (uchar)(iTotalGray / iTotalPixel);

			iNewThrehold = (iMeanGrayValue2 + iMeanGrayValue1) / 2; //新阀值  
			iDiffRec = abs(iMeanGrayValue2 - iMeanGrayValue1);
		}
	}
	catch (cv::Exception e)
	{
	}

	return iThrehold;
}

你可能感兴趣的:(C++,opencv)