因OpenCV里没有单独的OTSU算法(最大类间方差法)程序,所以用C写了OTSU算法程序,经测试,没有问题,和MATLAB的结果一致!欢迎大家加入图像识别技术交流群:271891601,另外,特别欢迎成都从事图像识别工作的朋友交流,我的QQ号248787278
程序中运用到的rice.png下载链接:
http://pan.baidu.com/s/1cDNVx8
C 源码如下:
#include <opencv2/opencv.hpp> #include <opencv2/legacy/compat.hpp> #include <opencv2/imgproc/types_c.h> #include <fstream> using namespace std; #pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"") int Otsu(IplImage* src) //运用OTSU法计算最佳阈值 { int height=src->height; int width=src->width; //histogram float histogram[256] = {0}; for(int i=0; i < height; i++) { unsigned char* p=(unsigned char*)src->imageData + src->widthStep * i; for(int j = 0; j < width; j++) { histogram[*p++]++; } } //normalize histogram int size = height * width; for(int i = 0; i < 256; i++) { histogram[i] = histogram[i] / size; } //average pixel value float avgValue=0; for(int i=0; i < 256; i++) { avgValue += i * histogram[i]; //整幅图像的平均灰度 } int threshold; float maxVariance=0; float w = 0, u = 0; for(int i = 0; i < 256; i++) { w += histogram[i]; //假设当前灰度i为阈值, 0~i 灰度的像素(假设像素值在此范围的像素叫做前景像素) 所占整幅图像的比例 u += i * histogram[i]; // 灰度i 之前的像素(0~i)的平均灰度值: 前景像素的平均灰度值 float t = avgValue * w - u; float variance = t * t / (w * (1 - w) ); if(variance > maxVariance) { maxVariance = variance; threshold = i; } } return threshold; } int main() //欢迎大家加入图像识别技术交流群:271891601 { // 从文件中加载原图 IplImage *pSrcImage = cvLoadImage("rice.png", CV_LOAD_IMAGE_UNCHANGED); //创建输出的图像 IplImage *pOutImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U,1); const char *pstrWindowsATitle = "经过二值化处理的图像(图像识别交流QQ2487872782)"; int Otsu_out_int; double Otsu_out_double; double maxVal255=255; Otsu_out_int=Otsu(pSrcImage); Otsu_out_double=double(Otsu_out_int); cvThreshold(pSrcImage, pOutImage, Otsu_out_double, maxVal255, CV_THRESH_BINARY); double cvThreshold_out[100]; int i; for(i=0;i<100;i++) { cvThreshold_out[i]=cvGet2D(pOutImage,0,i).val[0]; } cvNamedWindow(pstrWindowsATitle, CV_WINDOW_AUTOSIZE); cvShowImage(pstrWindowsATitle, pOutImage); cvWaitKey(0); //这里记得释放掉不用的资源哦,由于这是测试程序,就不写了,正式的程序一定要写上哦 return 0; }
MATLAB源码如下:
I=imread('rice.png'); thresh=graythresh(I); thresh_0to255=thresh*255; bw=im2bw(I,thresh); subplot(1,2,1);imshow(I);title('原图像'); subplot(1,2,2);imshow(bw);title('自动选择阈值');
OTSU算法计算出的阈值如下图所示:
------------------------------------------------------------------------------------------------------------------------------------------
欢迎大家加入图像识别技术交流群:271891601,另外,特别欢迎成都从事图像识别工作的朋友交流,我的QQ号248787278