S0.4 二值图

来源:互联网 发布:js两数字相加 编辑:程序博客网 时间:2024/06/16 13:37

    • 二值图的定义
    • 二值图的应用
  • 二值化方法
    • 1无脑简单判断
      • opencv3函数threshold实现
    • 2Otsu算法大律法或最大类间方差法
      • 改进版本
      • OpenCV3函数adaptiveThreshold实现大津法

二值图的定义

二值图是一种特殊的灰度图,即每个像素点要么是白(0),要么是黑(1)

Lena

二值图的应用

图像的二值化使图像中数据量大为减少,从而能凸显出目标的轮廓。

二值化方法

1,无脑简单判断

通过搜索灰度图每个像素,判断灰度值是否大于127 [(255+0)/2 = 127.5]

//二值化 一#include<opencv2/highgui/highgui.hpp>#include<opencv2/core/core.hpp>#include<opencv2/imgproc/imgproc.hpp>using namespace cv;int main(){    Mat srcImage = imread("images/favorite/Lena.jpg", 0);    Mat dstImage;    srcImage.copyTo(dstImage);    int rows = srcImage.rows;    int cols = srcImage.cols * srcImage.channels();    for(int i = 0; i < rows; i++)    {        uchar* data = dstImage.ptr<uchar>(i);        for(int j = 0; j < cols; j++)        {            if(data[j] > 127)                data[j] = 255;            else                data[j] = 0;        }    }    imshow("Lena", dstImage);    waitKey(30000);    return 0;}

opencv3函数threshold()实现

在imgproc.hpp中可以看到形参

//看函数参数CV_EXPORTS_W double threshold(     InputArray src,   //第一个参数表示输入图像,必须为单通道灰度图。    OutputArray dst,  //第二个参数表示输出图像,为单通道黑白图。    double thresh,    //第三个参数表示阈值,例如127    double maxval,    //第四个参数表示最大值,例如255    int type          //第五个参数表示运算方法。);

在OpenCV的imgproc\types_c.h中可以找到运算方法的定义。

/** Threshold types */enum{    CV_THRESH_BINARY      =0,  /**< value = value > threshold ? max_value : 0       */    CV_THRESH_BINARY_INV  =1,  /**< value = value > threshold ? 0 : max_value       */    CV_THRESH_TRUNC       =2,  /**< value = value > threshold ? threshold : value   */    CV_THRESH_TOZERO      =3,  /**< value = value > threshold ? value : 0           */    CV_THRESH_TOZERO_INV  =4,  /**< value = value > threshold ? 0 : value           */    CV_THRESH_MASK        =7,    CV_THRESH_OTSU        =8, /**< use Otsu algorithm to choose the optimal threshold value;                                 combine the flag with one of the above CV_THRESH_* values */    CV_THRESH_TRIANGLE    =16  /**< use Triangle algorithm to choose the optimal threshold value;                                 combine the flag with one of the above CV_THRESH_* values, but not                                 with CV_THRESH_OTSU */};

实例:

#include<opencv2/highgui/highgui.hpp>#include<opencv2/imgproc/imgproc.hpp>#include<opencv2/core/core.hpp>using namespace cv;int main(){    Mat srcImage = imread("images/favorite/Lena.jpg", 0);    Mat dstImage;    threshold(srcImage, dstImage, 127, 255, 0);    imshow("Lena", dstImage);    waitKey(30000);    return 0;}

2,Otsu算法(大律法或最大类间方差法)

大津法由大津(日本学者,名叫OTSU)于1979年提出,对图像Image,记t为前景与背景的分割阈值,前景点数占图像比例为w0,平均灰度为u0;背景点数占图像比例为w1,平均灰度为u1。图像的总平均灰度为:u=w0*u0+w1*u1。我们的目标是从最小灰度值到最大灰度值找到一个合适的分隔值t(即阈值),遍历t,当t使得值g=w0*(u0-u)2+w1*(u1-u)2 最大时t即为分割的最佳阈值。对大津法可作如下理解:该式实际上就是类间方差值,阈值t分割出的前景和背景两部分构成了整幅图像,而前景取值u0,概率为 w0,背景取值u1,概率为w1,总均值为u,根据方差的定义即得该式。因方差是灰度分布均匀性的一种度量,方差值越大,说明构成图像的两部分差别越大, 当部分目标错分为背景或部分背景错分为目标都会导致两部分差别变小,因此使类间方差最大的分割意味着错分概率最小。

直接应用大津法计算量较大,因此我们在实现时采用了等价的公式g=w0*w1*(u0-u1)2。

改进版本

OTSU 算法可以说是自适应计算单阈值(用来转换灰度图像为二值图像)的简单高效方法。下面的代码最早由 Ryan Dibble提供,此后经过多人Joerg.Schulenburg, R.Z.Liu 等修改,补正。

算法对输入的灰度图像的直方图进行分析,将直方图分成两个部分,使得两部分之间的距离最大。划分点就是求得的阈值。


-。-
如何用直方图来改进算法还不清楚。。待补充


OpenCV3函数adaptiveThreshold实现大津法

在imgproc.hpp中找到adaptiveThreshold的形参

CV_EXPORTS_W void adaptiveThreshold(     InputArray src,                //输入图像    OutputArray dst,               //输出图像    double maxValue,               //最大值,一般为255    int adaptiveMethod,            //0或1    int thresholdType,     int blockSize,     double C );
原创粉丝点击