ostu大津法 自动阈值分割

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


 

你可能感兴趣的:(算法,opencv,图像处理)