当前位置:   article > 正文

EmguCV学习笔记 C# 4.2 二值化

EmguCV学习笔记 C# 4.2 二值化

 版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。

教程VB.net版本请访问:
EmguCV学习笔记 VB.Net 目录-CSDN博客

教程C#版本请访问:EmguCV学习笔记 C# 目录-CSDN博客

笔者的博客网址:https://blog.csdn.net/uruseibest

教程配套文件及相关说明以及如何获得pdf教程和代码(博客上的教程内容会和pdf教程一致,教程中也会包含所有代码),请移步:EmguCV学习笔记

 

4.2 二值化

4.2.1 Threshold    

Threshold方法用于对图像进行二值化处理,将图像中的像素值转换为0或255,以便于后续的图像分割、形状检测等处理。该方法只能处理灰度图像,如果要对彩色图像进行二值化处理,需要先将其转换为灰度图像。此外,在使用Threshold方法时,还需要根据实际情况选择不同的二值化操作类型,以达到最佳的处理效果。

Threshold的声明如下:

public static double Threshold(

           IInputArray src,

                    IOutputArray dst,

                    double threshold,

                    double maxValue,

           ThresholdType thresholdType

)

参数说明:

  1. src:原始图像,通常是Mat类型。
  2. dst:输出图像,通常是Mat类型。
  3. thresh:阈值,Double类型。
  4. maxval:最大值,Double类型,在二值化操作中,将大于阈值的像素值设为该值。
  5. type:二值化操作的类型,ThresholdType类型,包括以下常量:
  1. Binary:二值化操作,将大于阈值的像素值设为maxval,小于等于阈值的像素值设为0。
  2. BinaryInv:反向二值化操作,将小于等于阈值的像素值设为maxval,大于阈值的像素值设为0。
  3. Trunc:截断操作,将大于阈值的像素值设为阈值,小于等于阈值的像素值不变。
  4. ToZero:零值操作,将小于等于阈值的像素值设为0,大于阈值的像素值不变。
  5. ToZeroInv:反向零值操作,将大于阈值的像素值设为0,小于等于阈值的像素值不变。
  6. Otsu:使用大津法,通过分析图像的灰度直方图,自动确定最佳的阈值,从而实现二值化,可以适用于大部分图像的二值化处理。如果使用了此类型,那么thresh参数将忽略。
  7. Triangle:使用Triangle算法,通过寻找直方图中的三角形区域,自动确定最佳的阈值,从而实现二值化。如果使用了此类型,那么thresh参数将忽略。

返回值:

返回ThresholdType为Otsu 或Triangle时,确定的最佳阈值(threshold的参数的值);如果ThresholdType不是Otsu 或Triangle,那么就返回设定的阈值。

【代码位置:frmChapter4】Button2_Click

        //Threshold

        private void Button2_Click(object sender, EventArgs e)

        {

            //可以直接使用ImreadModes.Grayscale,这里为了直观对比使用彩色图像

            Mat m = new Mat("C:\\learnEmgucv\\lena.jpg", ImreadModes.Color);

            ImageBox1.Image = m;

            //灰度转换

            Mat mgray = new Mat();

            CvInvoke.CvtColor(m, mgray, ColorConversion.Bgr2Gray);

            Mat mOut1 = new Mat();

            //使用Binary类型进行二值化

            CvInvoke.Threshold(mgray, mOut1, 125, 255, ThresholdType.Binary);

            ImageBox2.Image = mOut1;

            Mat mOut2 = new Mat();

            Double thresh;

            //使用大律法自动确定阈值进行二值化,并返回使用Otsu计算出的阈值

            thresh = CvInvoke.Threshold(mgray, mOut2, 0, 255, ThresholdType.Otsu);

            ImageBox3.Image = mOut2;

        }

运行后如下图所示:

 

图4-3 图像二值化

4.2.2 AdaptiveThreshold

AdaptiveThreshold方法用于对图像进行自适应阈值处理,将图像中的像素值转换为0或255,以便于后续的图像分割、形状检测等处理。该方法只能处理灰度图像,如果要对彩色图像进行自适应阈值处理,需要先将其转换为灰度图像。

AdaptiveThreshold方法的声明如下:

public static void AdaptiveThreshold(

           IInputArray src,

                    IOutputArray dst,

                    double maxValue,

                    AdaptiveThresholdType adaptiveType,

                    ThresholdType thresholdType,

           int blockSize,

           double param1

)

主要参数说明:

  1. maxValue:最大值,Double类型,在二值化操作中,将大于阈值的像素值设为该值。
  2. adaptiveMethod:自适应阈值处理的方法,AdaptiveThresholdTyp类型,包括以下常量:
    1. MeanC:阈值为邻域内的均值减去一个常数(param1)。
    2. GaussianC:阈值为邻域内的高斯加权平均值减去一个常数(param1)。
  3. thresholdType:二值化操作的类型,只能是ThresholdType类型的Binary或者BinaryInv。
  4. blockSize:邻域大小,必须为大于3的奇数。
  5. param1:常数,Double类型,表示从均值或高斯加权均值中减去的常数。

【代码位置:frmChapter4】Button3_Click

        //AdaptiveThreshold

        private void Button3_Click(object sender, EventArgs e)

        {

            Mat m = new Mat("C:\\learnEmgucv\\lena.jpg", ImreadModes.Color);

            ImageBox1.Image = m;

            //彩色转为灰度

            Mat mgray = new Mat();

            CvInvoke.CvtColor(m, mgray, ColorConversion.Bgr2Gray);

            Mat mOut1 = new Mat();

            //使用高斯加权平均值进行二值化

            CvInvoke.AdaptiveThreshold(mgray, mOut1, 255, AdaptiveThresholdType.GaussianC, ThresholdType.Binary, 3, 0);

            ImageBox2.Image = mOut1;

            Mat mOut2 = new Mat();

            //使用均值进行二值化

            CvInvoke.AdaptiveThreshold(mgray, mOut2, 255, AdaptiveThresholdType.MeanC, ThresholdType.Binary, 3, 0);

            ImageBox3.Image = mOut2;

        }

运行后如下图所示:

 

图4-4 使用AdaptiveThreshold进行图像二值化

4.2.3 图像通道分离和合并

图像通道的分离和合并分别使用到了CvInvoke的Split和Merge方法。Merge方法在2.3.11节【图像通道的分离与合并】有介绍,而CvInvoke.Split方法和该节的Mat.Split方法有所区别,详细请看代码说明。

【代码位置:frmChapter4】Button4_Click

        //通道分离和合并

        private void Button4_Click(object sender, EventArgs e)

        {

            Mat m = new Mat("C:\\learnEmgucv\\lena.jpg", ImreadModes.Color);

            ImageBox1.Image = m;

            //将图像通道分离到 VectorOfMat

            VectorOfMat vom = new VectorOfMat();

            CvInvoke.Split(m, vom);

            Mat mOut1 = new Mat();

            //输出分离后的第一个通道

            mOut1 = vom[0];

            ImageBox2.Image = mOut1;

            //注意和CvInvoke.Split的对比

            Mat[] channels = m.Split();

            //对三个通道分别进行二值化

            CvInvoke.Threshold(channels[0], channels[0], 100, 255, Emgu.CV.CvEnum.ThresholdType.Binary);

            CvInvoke.Threshold(channels[1], channels[0], 100, 255, Emgu.CV.CvEnum.ThresholdType.Binary);

            CvInvoke.Threshold(channels[2], channels[0], 100, 255, Emgu.CV.CvEnum.ThresholdType.Binary);

            //将处理后的三个通道推入 VectorOfMat

            VectorOfMat newm = new VectorOfMat();

            newm.Push(channels[0]);

            newm.Push(channels[1]);

            newm.Push(channels[2]);

            Mat mdst = new Mat();

            //合并通道

            CvInvoke.Merge(newm, mdst);

            ImageBox3.Image = mdst;

        }

运行后如下图所示:

 

图4-5 图像通道的分离和合并

4.2.4 按颜色分离

CvInvoke.InRange方法用于在图像中找到指定范围内的像素,并将其设置为白色,其余的像素设置为黑色。在使用CvInvoke.InRange方法时,需要根据实际情况选择合适的下限和上限,以达到最佳的处理效果。同时,CvInvoke.InRange方法只能处理单通道和三通道的图像。如果图像通道数不为1或3,需要先将其转换为单通道或三通道图像。

InRange方法的声明如下:

public static void InRange(

           IInputArray src,

                    IInputArray lower,

                    IInputArray upper,

           IOutputArray dst

)

主要参数说明:

lowerb参数是指定范围的下限。

upperb参数是指定范围的上限。

【代码位置:frmChapter4】Button5_Click

       //颜色分离

        private void Button5_Click(object sender, EventArgs e)

        {

            Mat m = new Mat("C:\\learnEmgucv\\wslt.jpg", ImreadModes.Color);

            ImageBox1.Image = m;

            Mat hsv = new Mat();

            //转为Hsv,更容易分离颜色

            CvInvoke.CvtColor(m, hsv, ColorConversion.Bgr2Hsv);

            //设置颜色范围下限和上限,需要根据实际慢慢修改

            ScalarArray lowerb1 = new ScalarArray(new MCvScalar(0, 10, 180));

            ScalarArray upperb1 = new ScalarArray(new MCvScalar(50, 160, 255));

            Mat dst = new Mat();

            //使用InRange分离颜色,返回二值图

            CvInvoke.InRange(hsv, lowerb1, upperb1, dst);

            ImageBox2.Image = dst;

            Mat dstchannel3 = new Mat();

            //转为3通道图像

            CvInvoke.CvtColor(dst, dstchannel3, ColorConversion.Gray2Bgr);

            Mat result = new Mat();

            //And运算,然后显示分离结果

            CvInvoke.BitwiseAnd(m, dstchannel3, result);

            ImageBox3.Image = result;

        }

运行后如下图所示:

 

图4-6 InRange方法分离出人脸

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/酷酷是懒虫/article/detail/1001604
推荐阅读
  

闽ICP备14008679号