本文测试环境:
win10 64位
vistual studio 2019
Emgu CV 4.6.0
环境配置准备:
1 新增控制台项目,.net framework为4.7.2
2 把win-x64目录的native目录下的文件全部拷贝到项目的运行目录Debug目录下
3 项目选择x64
4 添加项目引用Emgu.CV.dll、Emgu.CV.Platform.NetFramework.dll、System.Drawing.dll和System.Runtime.InteropServices.RuntimeInformation.dll
具体配置参考:
Emgu CV4图像处理之环境搭建1(C#)_zxy2847225301的博客-CSDN博客
1 Canny边缘检测
1 实现Canny算法需要以下五个步骤:

高斯模糊:使用高斯滤波进行图像去噪,这很好理解,为了更好的提取轮廓
灰度转换:提取轮廓一般都是灰度图
计算梯度和方向:使用soble算子,不知这个soble算子是咋来的,梯度方向怎么来的,看了几篇博文,不是很懂

非最大值信号抑制:

上图好像有点明白
高低阈值输出二值图像:

函数原型如下:

例子代码:
pic_noise.png原图如下:

- using Emgu.CV;
- using Emgu.CV.Structure;
- using Emgu.CV.Util;
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
-
- namespace EmguCVDemo2
- {
- class Program
- {
- static void Main(string[] args)
- {
-
- Image
srcPic = new Image("pic_noise.png"); - ImgCanny(srcPic);
- CvInvoke.WaitKey(0);
- Console.ReadLine();
- }
-
- ///
- /// Canny边缘检测
- ///
- ///
- private static void ImgCanny(Image
srcPic ) - {
- Mat dstMat = new Mat();
- CvInvoke.Canny(srcPic, dstMat, 110, 220);
- CvInvoke.Imshow("srcPic", srcPic);
- CvInvoke.Imshow("dstMat", dstMat);
- CvInvoke.WaitKey(0);
- }
-
-
- }
- }
运行结果如下:

2 图像阈值化(提取轮廓)

2.1 固定阈值:Threshold函数原型如下:

第一个参数src为输入图像
第二个参数dst为输出图像
第三个参数threshold是给定的阈值,当第五个参数theasholdType为Binary时,则:
value>threshold时,取maxValue
value<=threshold时,取0
第四个参数maxValue,当theasholdType为Binary或BinaryInv时才有效
第五个参数取值如下:

例子代码如下:
- using Emgu.CV;
- using Emgu.CV.Structure;
- using Emgu.CV.Util;
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
-
- namespace EmguCVDemo2
- {
- class Program
- {
- static void Main(string[] args)
- {
-
- Image
srcPic = new Image("pic_noise.png"); - ImgThreshold(srcPic);
- CvInvoke.WaitKey(0);
- Console.ReadLine();
- }
-
-
-
- ///
- /// 固定阈值
- ///
- ///
- private static void ImgThreshold(Image
srcPic ) - {
- //原图先转灰度图
- CvInvoke.CvtColor(srcPic, srcPic, Emgu.CV.CvEnum.ColorConversion.Bgr2Gray);
- Mat dstMat = new Mat();
- //当值灰度值高于100,则取255,其他情况取0(二值化为0,255)
- CvInvoke.Threshold(srcPic, dstMat, 100, 255, Emgu.CV.CvEnum.ThresholdType.Binary);
- CvInvoke.Imshow("srcPic", srcPic);
- CvInvoke.Imshow("dstMat", dstMat);
- CvInvoke.WaitKey(0);
- }
-
- }
- }
运行结果如下:

2.2 自适应阈值AdaptiveThreshold
函数原型如下:

各个参数含义如下:
src:源图像
dst:输出图像,与源图像大小一致
adaptiveType:在一个邻域内计算阈值所采用的算法,有两个取值,分别为 MeanC 和 GaussianC。
MeanC的计算方法是计算出领域的平均值再减去第七个参数double param1的值。
GaussianC的计算方法是计算出领域的高斯均值再减去第七个参数double param1的值。
thresholdType:这是阈值类型,有 BINARY 和BINARY_INV等 具体的请看官方的说明,这里不多做解释。
blockSize:adaptiveThreshold的计算单位是像素的邻域块,这是局部邻域大小,3、5、7等。
param1:这个参数实际上是一个偏移值调整量,用均值和高斯计算阈值后,再减或加这个值就是最终阈值。
参考代码如下:
- using Emgu.CV;
- using Emgu.CV.Structure;
- using Emgu.CV.Util;
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
-
- namespace EmguCVDemo2
- {
- class Program
- {
- static void Main(string[] args)
- {
-
- Image
srcPic = new Image("pic_noise.png"); - ImgAdaptiveThreshold(srcPic);
- CvInvoke.WaitKey(0);
- Console.ReadLine();
- }
-
-
- ///
- /// 自适应阈值
- ///
- ///
- private static void ImgAdaptiveThreshold(Image
srcPic ) - {
- //原图先转灰度图
- CvInvoke.CvtColor(srcPic, srcPic, Emgu.CV.CvEnum.ColorConversion.Bgr2Gray);
- Mat dstMat = new Mat();
-
- CvInvoke.AdaptiveThreshold(srcPic, dstMat, 255, Emgu.CV.CvEnum.AdaptiveThresholdType.GaussianC, Emgu.CV.CvEnum.ThresholdType.Binary, 7, 5);
- CvInvoke.Imshow("srcPic", srcPic);
- CvInvoke.Imshow("dstMat", dstMat);
- CvInvoke.WaitKey(0);
- }
- }
- }
运行结果如下:
