OpenCV算法实现:
根据大津法思路编写程序:
代码一:
#include
#include
#include
#include
using namespace std;
using namespace cv;
int OtsuThreshold(IplImage *frame);
void main()
{
IplImage *raw_img = cvLoadImage("4-1.jpg",0);
cvShowImage("0",raw_img);
double t = (double)getTickCount();
int m_threshold = OtsuThreshold(raw_img);
//返回该处代码执行所耗的时间,单位为秒
t = ((double)getTickCount() - t)/getTickFrequency();
cout<
for (int j=0; jwidth;j++)//lie
{
for (int i=0;iheight;i++)
{
unsigned char *p_data = (unsigned char*)raw_img->imageData + i*raw_img->widthStep;
if (p_data[j] < m_threshold)
{
p_data[j] = 0;
}
else
p_data[j]=255;
}
}
cvShowImage("1",raw_img);
cvWaitKey(0);
}
int OtsuThreshold(IplImage *frame)
{
int width = frame->width;//lie
int height = frame->height;//hang
const int GrayScale = 256;
int pixelCount[GrayScale];
float pixelPro[GrayScale];
int i;
for (i = 0; i < GrayScale; i++)//数组初始化
{
pixelCount[i] = 0;
pixelPro[i] = 0;
}
int j, pixelSum = width * height, threshold = 0;
unsigned char* data = (unsigned char*)frame->imageData; //指向像素数据的指针
for (i = 0; i < height; i++)//统计灰度级中每个像素在整幅图像中的个数
{
for (j = 0; j < width; j++)
{
pixelCount[(int)data[i * width + j]]++; //将像素值作为计数数组的下标
}
}
//计算每个像素在整幅图像中的比例
float maxPro = 0.0;
int kk = 0;
for (i = 0; i < GrayScale; i++)
{
pixelPro[i] = (float)pixelCount[i] / pixelSum;
if (pixelPro[i] > maxPro)
{
maxPro = pixelPro[i];//最大比例
kk = i;
}
}
//遍历灰度级[0,255]
float w0, w1, u0tmp, u1tmp, u0, u1, u, deltaTmp, deltaMax = 0;
for (i = 0; i < GrayScale; i++) //遍历灰度等级,i为阈值
{
w0 = w1 = u0tmp = u1tmp = u0 = u1 = u = deltaTmp = 0;
for (j = 0; j < GrayScale; j++)
{
if (j <= i) //背景部分
{
w0 += pixelPro[j];//背景像素点占整个图像的比例
u0tmp += j * pixelPro[j];
}
else //前景部分
{
w1 += pixelPro[j];//前景像素点占整个图像的比例
u1tmp += j * pixelPro[j];
}
}
u0 = u0tmp / w0;//背景平均灰度μ0
u1 = u1tmp / w1;//前景平均灰度μ1
u = u0tmp + u1tmp;
deltaTmp = w0 * pow((u0 - u), 2) + w1 * pow((u1 - u), 2);//g =ω0(μ0-μ)^2+ω1(μ1-μ)^2;类间方差
if (deltaTmp > deltaMax)
{
deltaMax = deltaTmp;
threshold = i;
}
}
return threshold;
}