OpenCV和MATLAB下运用OTSU法(最大类间方差法)对图像作二值化处理的源程序!

因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算法计算出的阈值如下图所示:

OpenCV和MATLAB下运用OTSU法(最大类间方差法)对图像作二值化处理的源程序!_第1张图片


------------------------------------------------------------------------------------------------------------------------------------------
欢迎大家加入图像识别技术交流群:271891601,另外,特别欢迎成都从事图像识别工作的朋友交流,我的QQ号248787278

你可能感兴趣的:(otsu,大律法,最大类间方差法)