【Emgu.CV教程】第17篇 、色彩处理之Threshold()二值化

        这篇讲的二值化的内容非常重要,需要仔细看呦。我在上一篇讲的是灰度图,在图像分析过程中,得到灰度图的下一步,常常是把其转换成二值化图像。什么是二值化图像呢,从直观上看,他就是这样的:

【Emgu.CV教程】第17篇 、色彩处理之Threshold()二值化_第1张图片

        这张   六角星.jpg  之前就用过,从视觉效果上看他就是二值化图像。 二值化图像就是一种特殊的灰度图,我们都知道灰度图是单通道的,其像素值在[0,255]的闭区间内分布。而二值化图形,就是只用0和255这两个数值,来表示一个灰度图,非黑即白,没有灰色地带。就像上面  六角星.jpg ,周围都是像素值为0的点,只有中间部分出现像素值为255的点,这些值为255的点组成了一个六角星。

       二值化图像,忽略了原始图像中的大部分细节,但是更容易提取出有用的区域。比如轮廓提取、图像分割、OCR识别。

        二值化的函数,在Emgu.CV中定义是Threshold(),其说明是这样的:

public static double Threshold(
    IInputArray src,  // 输入图像
    IOutputArray dst,  // 输出图像
    double threshold, // 设定阈值
    double maxValue, // 输出图像的最大值灰度值,一般设为255
    ThresholdType thresholdType // 二值化的类型
)

        其中ThresholdType共有8中,分别是:

  • ThresholdType.Binary,灰度值大于设定阈值threshold的设置为最大灰度值maxValue,其余设置为0。
  • ThresholdType.BinaryBinaryInv,灰度值不大于设定阈值threshold的设置为最大灰度值maxValue,其余设置为0
  • ThresholdType.Trunc,灰度值大于设定阈值threshold的设置为设定阈值threshold,其余部分保持不变,此时不需要maxValue这个参数。
  • ThresholdType.ToZero,灰度值小于设定阈值threshold的像素设为0,其余部分保持不变,此时不需要maxValue这个参数。
  • ThresholdType.ToZeroInv,灰度值大于设定阈值threshold的像素设为0,其余部分保持不变,此时不需要maxValue这个参数。
  • ThresholdType.Mask,带掩码。
  • ThresholdType.Otsu,使用大津算法来选择最佳阈值,并进行二值化,不需要threshold和maxValue这两个参数。
  • ThresholdType.Triangle,使用Triangle算法来算最佳阈值,并进行二值化,不需要threshold和maxValue这两个参数。

        下面对这8中用法举例说明,以 烟花.jpg  举例。

【Emgu.CV教程】第17篇 、色彩处理之Threshold()二值化_第2张图片

        转为灰度图是这样的:

【Emgu.CV教程】第17篇 、色彩处理之Threshold()二值化_第3张图片

1、ThresholdType.Binary

        假设输出两次二值化图像,第一次的设定阈值threshold = 100,最大灰度值maxValue = 255,第二次的设定阈值threshold = 180,最大灰度值maxValue = 255,代码如下:

CvInvoke.Threshold(srcMat, dstMat1, 100, 255, ThresholdType.Binary);
CvInvoke.Threshold(srcMat, dstMat2, 180, 255, ThresholdType.Binary);

       两次二值化结果如下图所示,是不是右边的图像白色部分比左边的少很多。为什么呢,因为第二幅图像的设定阈值threshold = 180,也就是函数会把大于180的部分转换成255。第一幅图片是大于100的部分就转换成了255,当然白色区域比第二幅的多。

【Emgu.CV教程】第17篇 、色彩处理之Threshold()二值化_第4张图片

2、ThresholdType.BinaryInv

        假设输出两次二值化图像,第一次的设定阈值threshold = 100,最大灰度值maxValue = 255,第二次的设定阈值threshold = 180,最大灰度值maxValue = 255,代码如下:

CvInvoke.Threshold(srcMat, dstMat1, 100, 255, ThresholdType.BinaryInv);
CvInvoke.Threshold(srcMat, dstMat2, 180, 255, ThresholdType.BinaryInv);

       两次二值化结果如下图所示,是不是右边的图像黑色部分比左边的少很多。为什么呢,因为第二幅图像的设定阈值threshold = 180,也就是函数会把不大于180的转换成255。第一幅图片是不大于100的部分转换成255,当然黑色区域比第二幅的多。

【Emgu.CV教程】第17篇 、色彩处理之Threshold()二值化_第5张图片

       其实ThresholdType.BinaryInv得到的结果,就是ThresholdType.Binary的结果反色。 

3、ThresholdType.Trunc

        假设输出两次二值化图像,第一次的设定阈值threshold = 100,最大灰度值maxValue = 255,第二次的设定阈值threshold = 180,最大灰度值maxValue = 255,代码如下:

CvInvoke.Threshold(srcMat, dstMat1, 100, 255, ThresholdType.Trunc);
CvInvoke.Threshold(srcMat, dstMat2, 180, 255, ThresholdType.Trunc);

       两次二值化结果如下图所示,是不是右边的图像烟花区域比左边图像烟花区域亮。为什么呢,因为第二幅图像的设定阈值threshold = 180,也就是函数会把大于180的部分转换成180,其余的保持不变。第一幅图片是大于100的部分转换成100,其余保持不变,结果就是这样。在这种模式下maxValue不起作用。

【Emgu.CV教程】第17篇 、色彩处理之Threshold()二值化_第6张图片

4、ThresholdType.ToZero

        假设输出两次二值化图像,第一次的设定阈值threshold = 100,最大灰度值maxValue = 255,第二次的设定阈值threshold = 180,最大灰度值maxValue = 255,代码如下:

CvInvoke.Threshold(srcMat, dstMat1, 100, 255, ThresholdType.ToZero);
CvInvoke.Threshold(srcMat, dstMat2, 180, 255, ThresholdType.ToZero);

       两次二值化结果如下图所示,第一幅图片是小于100的部分转换成0,其余保持不变。第二幅图片是小于180的部分转换成0,其余保持不变,maxValue这个参数其实是不起作用的。

 【Emgu.CV教程】第17篇 、色彩处理之Threshold()二值化_第7张图片

5、ThresholdType.ToZeroInv

        假设输出两次二值化图像,第一次的设定阈值threshold = 100,最大灰度值maxValue = 255,第二次的设定阈值threshold = 180,最大灰度值maxValue = 255,代码如下:

CvInvoke.Threshold(srcMat, dstMat1, 100, 255, ThresholdType.ToZeroInv);
CvInvoke.Threshold(srcMat, dstMat2, 180, 255, ThresholdType.ToZeroInv);

       两次二值化结果如下图所示,第一幅图片是大于100的部分转换成0,其余保持不变。第二幅图片是大于180的部分转换成0,其余保持不变,maxValue这个参数其实是不起作用的。

【Emgu.CV教程】第17篇 、色彩处理之Threshold()二值化_第8张图片

6、ThresholdType.Mask

        不知道怎么用... ...

7、ThresholdType.Otsu

        假设输出两次二值化图像,第一次的设定阈值threshold = 100,最大灰度值maxValue = 255,第二次的设定阈值threshold = 180,最大灰度值maxValue = 255,代码如下:

CvInvoke.Threshold(srcMat, dstMat1, 100, 255, ThresholdType.Otsu);
CvInvoke.Threshold(srcMat, dstMat2, 180, 255, ThresholdType.Otsu);

       两次二值化结果是一样的,因为它采用了Otsu算法,与设定阈值threshold和最大灰度值maxValue是无关的。

【Emgu.CV教程】第17篇 、色彩处理之Threshold()二值化_第9张图片

8、ThresholdType.Triangle

        假设输出两次二值化图像,第一次的设定阈值threshold = 100,最大灰度值maxValue = 255,第二次的设定阈值threshold = 180,最大灰度值maxValue = 255,代码如下:

CvInvoke.Threshold(srcMat, dstMat1, 100, 255, ThresholdType.Triangle);
CvInvoke.Threshold(srcMat, dstMat2, 180, 255, ThresholdType.Triangle);

       两次二值化结果是一样的,因为它采用了Triangle算法,与设定阈值threshold和最大灰度值maxValue也是无关的。

【Emgu.CV教程】第17篇 、色彩处理之Threshold()二值化_第10张图片

        总结: ThresholdType.Mask不会用,读者自己去试试吧。ThresholdType.Otsu和ThresholdType.Triangle算法,与参数无关,都是Emgu.CV自己完成的,具体是怎么做的,读者自己可以找一找资料。另外五种,ThresholdType.Binary和ThresholdType.BinaryInv是最常用的。五种算法怎么使用,需要读者自己理解概念。

        到现在还迷糊呢,那看看下面这张图:

【Emgu.CV教程】第17篇 、色彩处理之Threshold()二值化_第11张图片

        这几种用法的区分很清晰了吧,到胃不到胃,简单不简单。 

原创不易,请勿抄袭。共同进步,相互学习。

你可能感兴趣的:(Emgu.CV使用教程,计算机视觉,图像处理,c#,Emgu.CV)