【Emgu CV教程】11.2、Scharr边缘检测

文章目录


一、背景知识

前面讲的是Sobel和Canny两种边缘检测算法,这两种算法都要定义滤波核的大小,一般是3、5、7这种奇数,下面要介绍的Scharr边缘检测,就去掉了这一步,直接使用定义好的滤波核进行操作。

Scharr滤波核的尺寸大小是固定的3*3,其在X方向上的一阶算子是:

在Y方向上的一阶算子是:

发现有什么特点???需要记笔记的地方来了:

  • X方向的一阶算子,水平方向三个值相加等于0,这就会抑制水平方向的边缘,尽可能多的保留垂直方向的边缘。
  • Y方向的一阶算子,垂直方向三个值相加等于0,这就会抑制垂直方向的边缘,尽可能多的保留水平方向的边缘。

二、Scharr()函数

Emgu CV中,Scharr()函数定义如下:

csharp 复制代码
public static void Scharr(
	IInputArray src,   // 输入图像
	IOutputArray dst,  // 输出图像
	DepthType ddepth,  // 输出的图像深度,Cv8U、Cv16S、Cv32U这种
	int dx,  // 0是不在X方向(水平方向)求导,1是在X方向(水平方向)求导
	int dy,   // 0是不在Y方向(垂直方向)求导,1是在Y方向(垂直方向)求导
	double scale = 1.0,  // 计算可选比例因子,默认值1,不知道干什么用的
	double delta = 0.0,  // 加到输出像素的偏值,默认为0
	BorderType borderType = BorderType.Reflect101 // 边界类型,默认值BorderType.Reflect101
)

注意了,在X方向求导,就是抑制水平边缘;在Y方向求导,就是抑制垂直边缘。

三、演示

1.原始素材

原始素材srcMat如下图:

这张图片水平、垂直方向边缘很明显,十分适合Scharr函数演示。

2.只在X方向检测

只在X方向检测就是只在水平方向求导,不在垂直方向求导,因此会抑制水平方向边缘,保留垂直方向边缘,代码如下:

csharp 复制代码
Mat tempMat = srcMat.Clone();
Mat dstMat = new Mat();
Mat directionX = new Mat();

// 转成灰度图
CvInvoke.CvtColor(tempMat, tempMat, ColorConversion.Bgr2Gray);

// 求X方向
CvInvoke.Scharr(tempMat, directionX, DepthType.Cv16S, 1, 0, 1, 0, BorderType.Default);

// 计算绝对值,并将结果转换为8位
CvInvoke.ConvertScaleAbs(directionX, dstMat, 1, 0);
CvInvoke.Imshow("Scharr X, " + dstMat.Size.ToString(), dstMat);

最终输出的图像如下:

3.只在Y方向检测

只在Y方向检测就是只在垂直方向求导,不在水平方向求导,因此会抑制垂直方向边缘,保留水平方向边缘,代码如下:

csharp 复制代码
Mat tempMat = srcMat.Clone();
Mat dstMat = new Mat();
Mat directionX = new Mat();

// 转成灰度图
CvInvoke.CvtColor(tempMat, tempMat, ColorConversion.Bgr2Gray);

// 求Y方向
CvInvoke.Scharr(tempMat, directionY, DepthType.Cv16S, 0, 1, 1, 0, BorderType.Default);

// 计算绝对值,并将结果转换为8位
CvInvoke.ConvertScaleAbs(directionX, dstMat, 1, 0);
CvInvoke.Imshow("Scharr Y, " + dstMat.Size.ToString(), dstMat);

最终输出的图像如下:

3.X、Y方向同时检测

这时会同时保留水平、垂直方向的边缘,代码如下:

csharp 复制代码
Mat tempMat = srcMat.Clone();
Mat dstMat = new Mat();
Mat directionX = new Mat();
Mat directionY = new Mat();
Mat absX = new Mat();
Mat absY = new Mat();

// 转成灰度图
CvInvoke.CvtColor(tempMat, tempMat, ColorConversion.Bgr2Gray);

// 求X方向
CvInvoke.Scharr(tempMat, directionX, DepthType.Cv16S, 1, 0, 1, 0, BorderType.Default);
CvInvoke.ConvertScaleAbs(directionX, absX, 1, 0); // 计算绝对值,并将结果转换为8位

// 求Y方向
CvInvoke.Scharr(tempMat, directionY, DepthType.Cv16S, 0, 1, 1, 0, BorderType.Default);
CvInvoke.ConvertScaleAbs(directionY, absY, 1, 0); // 计算绝对值,并将结果转换为8位

// X轴加Y轴,权重都是50%
CvInvoke.AddWeighted(absX, 0.5, absY, 0.5, 0, dstMat);
CvInvoke.Imshow("Scharr X and Y, " + dstMat.Size.ToString(), dstMat);

四、最后总结

在Emgu.CV中,Scharr函数和Sobel函数的运行速度差不多,但是Scharr函数更能提取出细节和纹理丰富的部位,童鞋们可以用我的代码去试试。


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

相关推荐
Xin_ye1008634 分钟前
C# 零基础到精通教程 - 第八章:面向对象编程(进阶)——继承与多态
开发语言·c#
Hua-Jay2 小时前
OpenCV联合C++/Qt 学习笔记(二十二)----相机模型与投影及单目相机标定
c++·笔记·qt·opencv·学习·计算机视觉
asdzx672 小时前
使用 C# 打印 Excel 文档(详细教程)
c#·excel
凌峰的博客2 小时前
T2SMark:在扩散模型噪声水印中寻找鲁棒性与多样性的平衡
人工智能·深度学习·计算机视觉
小白|3 小时前
CANN目标检测实战:自定义检测算子开发(插件机制)
人工智能·目标检测·计算机视觉
伽蓝_游戏4 小时前
第四章:AssetBundle 核心机制与文件结构
unity·c#·游戏引擎·游戏程序
乐迪信息4 小时前
乐迪信息:港口夜间船舶巡查难,AI摄像机法全天候监测
人工智能·物联网·算法·计算机视觉·目标跟踪
sali-tec4 小时前
C# 基于OpenCv的视觉工作流-章74-线-线距离
图像处理·人工智能·opencv·算法·计算机视觉
2501_930707784 小时前
使用C#代码拆分 PowerPoint 演示文稿
开发语言·c#·powerpoint
问窗4 小时前
计算机视觉入门案例 高速公路车辆计数系统技术解析
python·opencv·计算机视觉