计算机视觉

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

2018-07-01  本文已影响0人  刘千予

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

}

上一篇下一篇

猜你喜欢

热点阅读