大津法的详细讲解后面更新。现在先贴出代码:
#include <iostream>
#include <opencv2\opencv.hpp>
using namespace std;
using namespace cv;
int OTSU(Mat image)
{
int weight=image.rows;//获取图像宽度
int height=image.cols;//获取图像长度
int pre_value=0;//前景像素的总值
int back_value=0;//后景像素的总值
int pre_num=0;
int back_num=0;
int all_num=weight*height;
int all_value=0;
double pre_num_average=0;
double back_num_average=0;
double pre_value_average=0;
double back_value_average=0;
int value_num_list[256]={0};
double variance=0;
double variance_max=-1;
int threshold_otsu=0;
for(int x=0;x<weight;x++)
{
for(int y=0;y<height;y++)
{
value_num_list[image.at<uchar>(x,y)]++;
}
}
for(int i=0;i<256;i++)
{
all_value+=value_num_list[i]*i;
}
for(int i=0;i<256;i++)
{
pre_num+=value_num_list[i];
back_num=all_num-pre_num;
pre_value+=value_num_list[i]*i;
back_value=all_value-pre_value;
pre_num_average=(double)pre_num/all_num;
back_num_average=(double)back_num/all_num;
pre_value_average=(double)pre_value/pre_num;
back_value_average=(double)back_value/back_num;
variance=pre_num_average*back_num_average*(pre_value_average-back_value_average)*(pre_value_average-back_value_average);
if(variance>variance_max)
{
variance_max=variance;
threshold_otsu=i;
}
}
return threshold_otsu;
}
int main(void)
{
Mat image = imread("D:\\360\\test.jpg", IMREAD_GRAYSCALE);
if (image.data != NULL)
{
imshow("0", image);
}
else
{
cout << "can't open the file!" << endl;
getchar();
}
Mat otsu_show;
threshold(image,otsu_show,OTSU(image),255,THRESH_BINARY);
imshow("otsu_show_window",otsu_show);
waitKey(0);
}