大津阈值OSTU函数实现方法对比, Mat转换为IplImage 类型,并复制数据

实现代码如下:


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



大津阈值OSTU函数实现方法对比, Mat转换为IplImage 类型,并复制数据_第1张图片



大津阈值OSTU函数实现方法对比, Mat转换为IplImage 类型,并复制数据_第2张图片




你可能感兴趣的:(C++,image,opencv)