实现代码如下:
#include <iostream>
#include <time.h>//图像处理时间
#include <cmath>//图像对象厚度计算
#include <iomanip> //使用setw必须使用该预编译命令
#include "cv.h"
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace std;
using namespace cv;
void help()
{
printf("------------------------------------------------------------------\n");
printf("This demo shows how to operate image use Mat !\n");
printf("Edit:John_Tian\n");
printf("Date:2013.7.1\n");
printf("------------------------------------------------------------------\n");
}
Mat& BinaryimageUseOSTU(Mat& src_gray, Mat&src_binary);
int main(int argc,char *argv[])
{
//Demo说明
help();
double start_time,end_time;
Mat src,src_gray;
#pragma region OSTU
//读入图像
src=imread("D:\\lena.bmp");
//转换为灰度图像
cvtColor(src,src_gray,CV_RGB2GRAY);
//程序开始计时
start_time=clock();
//OSTU提取对象
Mat src_binary=src_gray;//赋值为灰度图像
BinaryimageUseOSTU(src_gray,src_binary);
end_time = (clock() - start_time) / CLOCKS_PER_SEC;
printf( "the time used is :%lf\n", end_time );
imshow("OSTU_IMAGE1",src_binary);
waitKey(3000);//显示3秒
#pragma endregion
src_binary=src_gray;//赋值为灰度图像
//程序开始计时
start_time=clock();
threshold(src_gray,src_binary,0,255,THRESH_OTSU);//opencv2.4.5自带OSTU函数二值化
end_time = (clock() - start_time) / CLOCKS_PER_SEC;
printf( "the time used is :%lf\n", end_time );
imshow("OSTU_IMAGE2",src_binary);
waitKey(3000);//显示3秒
//src_binary二值化图像 dst_image原始输入图像
//---Mat转换为IplImage类型,并复制数据---
Mat dst_image=src;
int height=src_binary.rows;
int width =src_binary.cols;
CvSize size={width,height};
Mat src_binary_data,dst_image_data;
IplImage *src_gray1,*dst;
src_binary_data=src_binary.clone();
dst_image_data=dst_image.clone();//拷贝Mat类型的数据
src_gray1=cvCreateImage(size,8,1);
dst =cvCreateImage(size,8,3);
src_gray1->imageData=(char*)src_binary_data.data;//存储的是二值化后图像
dst->imageData=(char*)dst_image_data.data; //存储的是原始输入图像
cvNamedWindow("src_gray1",CV_WINDOW_AUTOSIZE);
cvShowImage("src_gray1",src_gray1);
waitKey(3000);//测试转换结果
cvNamedWindow("src",CV_WINDOW_AUTOSIZE);
cvShowImage("src",dst);
cvWaitKey(3000);//测试转换结果
cvReleaseImage(&src_gray1);
cvReleaseImage(&dst);
//-----------------------------------------------------------
return 0;
}
Mat& BinaryimageUseOSTU(Mat& src_gray, Mat&src_binary)
{
// accept only char type matrices
CV_Assert(src_gray.depth() != sizeof(uchar));
int height=src_gray.rows;
int width =src_gray.cols;
long N=height*width;
int h[256]={0};
double p[256]={0},u[256]={0},w[256]={0};
for(int i = 0; i < height; i++)
{
for(int j = 0; j < width; j++)
{
h[(int)src_gray.at<uchar>(i,j)]++;//统计每个灰度级的数目
}
}
for(int i = 0; i < 256; i++)
p[i] = h[i] / double(N);
int T = 0;
double T1,S1;
double S1_max = -10000;
for(int k = 0; k < 256; k++)
{
T1 = 0;
for(int i = 0; i <= k; i++)
{
u[k] += i*p[i];
w[k] += p[i];
}
for(int i = 0; i < 256; i++)
T1 += i*p[i];
S1 = (T1*w[k] - u[k])*(T1*w[k] - u[k]) / (w[k]*(1-w[k]));
if(S1 > S1_max)
{
S1_max = S1;
T = k;
}
}
for(int i = 0; i < height; i++)
{
for(int j = 0; j < width; j++)
{
if(src_binary.at<uchar>(i,j) > T)
{
src_binary.at<uchar>(i,j) = 255;
}
else
{
src_binary.at<uchar>(i,j) = 0;
}
}
}
return src_binary;
}