opencv1.0版本
#include "stdio.h"
#include "cv.h"
#include "highgui.h"
#include "Math.h"
int Otsu(IplImage* src);
int main(int argc, char*argv[])
{
IplImage* img = cvLoadImage("D:\\chengxu\\opencv\\Desert.jpg", );
IplImage* dst = cvCreateImage(cvGetSize(img), , );
int threshold = Otsu(img);
printf("threshold = %d\n", threshold);
cvThreshold(img, dst, threshold, , CV_THRESH_BINARY);
cvNamedWindow("img", );
cvShowImage("img", dst);
cvWaitKey(-);
cvReleaseImage(&img);
cvReleaseImage(&dst);
cvDestroyWindow("dst");
return ;
}
int Otsu(IplImage* src)
{
int height = src->height;
int width = src->width;
//histogram
float histogram[] = { };
for (int i = ; i < height; i++)
{
unsigned char* p = (unsigned char*)src->imageData + src->widthStep * i;
for (int j = ; j < width; j++)
{
histogram[*p++]++;
}
}
//normalize histogram
int size = height * width;
for (int i = ; i < ; i++)
{
histogram[i] = histogram[i] / size;
}
//average pixel value
float avgValue = ;
for (int i = ; i < ; i++)
{
avgValue += i * histogram[i]; //整幅圖像的平均灰階
}
int threshold;
float maxVariance = ;
float w = , u = ;
for (int i = ; i < ; i++)
{
w += histogram[i]; //假設目前灰階i為門檻值, 0~i 灰階的像素(假設像素值在此範圍的像素叫做前景像素) 所占整幅圖像的比例
u += i * histogram[i]; // 灰階i 之前的像素(0~i)的平均灰階值: 前景像素的平均灰階值
float t = avgValue * w - u;
float variance = t * t / (w * ( - w));
if (variance > maxVariance)
{
maxVariance = variance;
threshold = i;
}
}
return threshold;
}
opencv2.0版本
#include<opencv2/opencv.hpp>
#include"cv.h"
#include"highgui.h"
#include <stdlib.h>
#include <stdio.h>
using namespace cv;
using namespace std;
int otsu(const Mat &img)//最大類間方差門檻值分割
{
float histogram[] = { };
for (int i = ; i<img.rows; i++)
{
const unsigned char* p = (const unsigned char*)img.ptr(i);
for (int j = ; j<img.cols; j++)
{
histogram[p[j]]++;
}
}
float avgValue = ;
int numPixel = img.cols*img.rows;
for (int i = ; i<; i++)
{
histogram[i] = histogram[i] / numPixel;
avgValue += i*histogram[i];
}
int threshold = ;
float gmax = ;
float wk = , uk = ;
for (int i = ; i<; i++) {
wk += histogram[i];
uk += i*histogram[i];
float ut = avgValue*wk - uk;
float g = ut*ut / (wk*( - wk));
if (g > gmax)
{
gmax = g;
threshold = i;
}
}
return threshold;
}
int main( int, char** argv )
{
Mat src,gray;
int width = ;
int height = ;
int channels = ;
const char* window_name = "erzhitu";
src = imread("C:\\Program Files (x86)\\MesaImaging\\Swissranger\\matlab\\swissranger\\xx.jpg");
if (src.empty())
{
return -;
}
width = src.cols;//求圖像的行列及通道
height = src.rows;
channels = src.channels();
cvtColor(new_src, gray, CV_BGR2GRAY);//灰階化
int gray_threshold = ;//門檻值分割
gray_threshold = otsu(gray);
cout << gray_threshold << endl;
Mat erzhitu;
threshold(gray, erzhitu, gray_threshold, ,);
namedWindow(window_name, WINDOW_AUTOSIZE);
imshow(window_name, erzhitu);