小念子

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

   Otsu是图像处理中最常用的二值化算法,原理如下:

  

   

 下面是用ostu算法对灰度图进行二值化处理的代码,用opencv写的

#include "opencv2/opencv.hpp"
#include "opencv2/highgui/highgui.hpp"   
#include "opencv2/imgproc/imgproc.hpp" 
using namespace cv;

int main()
{
    Mat src = imread("D:\\picture\\1.jpg");
    if(!src.data)
        return -1;
    imshow("original",src);
    Mat gray ;
    cv::cvtColor(src,gray,CV_BGR2GRAY);
    imshow("gray",gray);
    int rows = gray.rows;
    int cols = gray.cols;
    float count[256] = {0};//每个灰度值[0,255]的计数
    for(int i = 0;i<rows;i++)
        for(int j = 0;j<cols;j++)
        {
            int index = (int)gray.at<uchar>(i,j);
            count[index]++;
        }
    float P[256];  //每个灰度值[0,255]的概率密度
    for(int i = 0;i<256;i++)
        P[i] = count[i]/(rows*cols);
    int threshold= 0;
    float deltaMax = 0;
    float w0,w1,u0tmp,u1tmp,u0,u1,ut,deltaTmp;
    for(int i = 1;i<256;i++)
    {
        w0 = w1 = u0tmp = u1tmp = u0 = u1 = ut = deltaTmp = 0;
        for(int j = 0;j<256;j++)
        {
            if(j<i)//背景
            {
                w0 = w0+P[j];//背景像素占整幅图的比例
                u0tmp = u0tmp + j*P[j];
            }
            else //前景
            {
                w1 = w1+P[j];//前景占整幅图的比例
                u1tmp = u1tmp + j*P[j];
            }
        }
        u0 = u0tmp/w0;//背景像素点的平均灰度
        u1 = u1tmp/w1;//前景像素点的平均灰度
        ut = w0*u0 + w1*u1; //整幅图像的平均灰度
        for(int k = 0;k<256;k++)
            deltaTmp = deltaTmp + (k-ut)*(k-ut)*P[k];//全局方差
        deltaTmp = w0*w1*(u1-u0)*(u1-u0)/deltaTmp;//类间方差除以全局方差
        if (deltaTmp>deltaMax)
        {
            deltaMax = deltaTmp;
            threshold = i;
        }
    }
    Mat binary_gray = gray.clone();
    for(int i = 0;i<rows;i++)
        for(int j = 0;j<cols;j++)
            if((int)gray.at<uchar>(i,j)<threshold)
                binary_gray.at<uchar>(i,j) = (uchar)0;
            else
                binary_gray.at<uchar>(i,j) = (uchar)255;
    imshow("binary_gray",binary_gray);
    waitKey(0);
    return 0;
}

接下来是运行的结果

 

 

posted on 2014-04-06 14:49  小念子  阅读(527)  评论(0编辑  收藏  举报