//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;
}