#include "opencv2/opencv.hpp"
#include <iostream>
using namespace std;
using namespace cv;
int otsu(Mat src,Mat dst)
{
int width=src.cols;
int height=src.rows;
long N = height * width;
int h[256];
double p[256],u[256],w[256];
for(int i = 0; i < 256; i++)
{
h[i] = 0;
p[i] = 0;
u[i] = 0;
w[i] = 0;
}
for(int i = 0; i < height; i++)
{
for(int j = 0; j < width; j++)
{
for(int k = 0; k < 256; k++)
{
if(src.at<uchar>(i,j) == k)
{
h[k]++;
}
}
}
}
for(int i = 0; i < 256; i++)
p[i] = h[i] / double(N);
int T = 0;
double uT,thegma2fang;
double thegma2fang_max = -10000;
for(int k = 0; k < 256; k++)
{
uT = 0;
for(int i = 0; i <= k; i++)
{
u[k] += i*p[i];
w[k] += p[i];
}
for(int i = 0; i < 256; i++)
uT += i*p[i];
thegma2fang = (uT*w[k] - u[k])*(uT*w[k] - u[k]) / (w[k]*(1-w[k]));
if(thegma2fang > thegma2fang_max)
{
thegma2fang_max = thegma2fang;
T = k;
}
}
for(int i = 0; i < height; i++)
{
for(int j = 0; j < width; j++)
{
if(src.at<uchar>(i,j) > T)
dst.at<uchar>(i,j) = 255;
else
dst.at<uchar>(i,j) = 0;
}
}
return T;
}
int main(int argc, char** argv)
{
string filename = ".\\12.20\\g0003.bmp";
Mat src=imread(filename,0);
Mat dst=Mat(src.rows,src.cols,CV_8UC1);
int threshold=otsu(src,dst);
cout<<threshold<<endl;
imshow("dst",dst);
waitKey();
return 0;
}