OpenCV学习笔记之九——边缘检测(Canny算子,Sobel算子,Laplace算子,Scharr滤波)
发布日期:2025-06-18 16:32:38
浏览次数:3
分类:精选文章
本文共 3227 字,大约阅读时间需要 10 分钟。
OpenCV 边缘检测与图像变换技术
感谢 @浅墨_毛星云 的博客和书籍《OpenCV 3.0 编程入门》,我通过学习这些内容整理了本篇笔记及心得。由于自身水平有限,欢迎交流与指正。
Canny 算子
基本原理
Canny 算子是一种用于边缘检测的算法,通过计算图像的梯度来检测边缘。其核心思想是对图像进行滤波,提取强边缘,并通过双阈值分离背景噪声和真实边缘。
函数详情
C++ 实现如下:
void Canny(InputArray image, OutputArray edges, double threshold1, double threshold2, int apertureSize=3, bool L2gradient=false)
参数解释
- InputArray image:输入图像,需为单通道 8 位图像。
- OutputArray edges:输出边缘图,与输入图像尺寸和类型一致。
- double threshold1:第一个滞后性阈值。
- double threshold2:第二个滞后性阈值。
- int apertureSize:Sobel 算子孔径大小,默认为 3。
- bool L2gradient:计算梯度的类型,默认为
false。
注意事项
- 阈值 1 和 2 的比例通常在 2:1 到 3:1 之间,建议使用较高阈值来保留强边缘。
Sobel 算子
基本原理
Sobel 算子是一种计算图像梯度的滤波器,通过对图像进行一阶微分,检测边缘的方向和强度。
函数详情
C++ 实现如下:
void Sobel(InputArray src, OutputArray dst, int ddepth, int dx, int dy, int ksize=3, double scale=1, double delta=0, int borderType=BORDER_DEFAULT)
参数解释
- InputArray src:输入图像。
- OutputArray dst:输出图像,与输入图像尺寸和类型一致。
- int ddepth:输出图像的深度,需与输入图像匹配。
- int dx:x 方向差分阶数。
- int dy:y 方向差分阶数。
- int ksize:滤波器孔径大小,必须为奇数(1, 3, 5, 7)。
- double scale:缩放因子,默认为 1。
- double delta:存储到目标图之前的平移量,默认为 0。
- int borderType:边界模式,默认为
BORDER_DEFAULT。
Laplace 算子
基本原理
Laplace 算子通过计算图像的二阶导数(拉普拉斯变换),用于边缘检测和图像增强。
函数详情
C++ 实现如下:
void Laplacian(InputArray src, OutputArray dst, int ddepth, int ksize=1, double scale=1, double delta=0, int borderType=BORDER_DEFAULT)
参数解释
- InputArray src:输入图像。
- OutputArray dst:输出图像,与输入图像尺寸和类型一致。
- int ddepth:输出图像的深度。
- int ksize:滤波器孔径大小,必须为奇数,默认为 1。
- double scale:缩放因子,默认为 1。
- double delta:存储到目标图之前的平移量,默认为 0。
- int borderType:边界模式,默认为
BORDER_DEFAULT。
工作原理
Laplacian 算子通过计算 Sobel 算子的 x 和 y 分量之和,得到图像的拉普拉斯变换结果,常用于边缘检测和图像去模糊。
Scharr 滤波器
基本原理
Scharr 滤波器是一种用于计算图像梯度的滤波器,其原理类似于 Sobel 算子,但支持多个方向的梯度计算。
函数详情
C++ 实现如下:
void Scharr(InputArray src, OutputArray dst, int ddepth, int dx, int dy, double scale=1, double delta=0, int borderType=BORDER_DEFAULT)
参数解释
- InputArray src:输入图像。
- OutputArray dst:输出图像,与输入图像尺寸和类型一致。
- int ddepth:输出图像的深度。
- int dx:x 方向差分阶数。
- int dy:y 方向差分阶数。
- double scale:缩放因子,默认为 1。
- double delta:存储到目标图之前的平移量,默认为 0。
- int borderType:边界模式,默认为
BORDER_DEFAULT。
综合代码实现
#include#include #include #include using namespace std;using namespace cv;void process() { if (Way_num == 0) { // Canny 算子 Canny(Img_gray, Img_out, struct_size, struct_size * 5, 3); } else if (Way_num == 1) { // Sobel 算子 Mat grad_x, grad_y; Sobel(Img_gray, grad_x, CV_16U, 1, 0, 3, 1, 0, BORDER_DEFAULT); Sobel(Img_gray, grad_y, CV_16U, 0, 1, 3, 1, 0, BORDER_DEFAULT); addWeighted(grad_x, 0.5, grad_y, 0.5, 0, Img_out); } else if (Way_num == 2) { // Laplace 算子 Laplacian(Img_gray, Img_out, CV_16U, 3, 1, 0, BORDER_DEFAULT); convertScaleAbs(Img_out, Img_out); } else if (Way_num == 3) { // Scharr 滤波 Mat scharr_x, scharr_y; Scharr(Img_gray, scharr_x, CV_16U, 1, 0, 1, 0, BORDER_DEFAULT); Scharr(Img_gray, scharr_y, CV_16U, 0, 1, 1, 0, BORDER_DEFAULT); addWeighted(scharr_x, 0.5, scharr_y, 0.5, 0, Img_out); } imshow("【效果图】", Img_out);}
效果展示
通过不同算子的组合,可以实现多种边缘检测效果。以下是对原图和处理后图像的对比:
- Canny 算子:能够检测出图像的主要边缘,同时减少背景噪声。
- Sobel 算子:提供图像的水平和垂直方向的梯度信息,通常用于边缘检测和运动分析。
- Laplace 算子:通过二阶导数检测边缘,效果与 Canny 算子类似,但计算更复杂。
- Scharr 滤波:与 Sobel 算子类似,但支持多方向梯度计算,适合特定应用场景。
通过这些算子的组合和参数调整,可以根据具体需求定制边缘检测效果。
发表评论
最新留言
感谢大佬
[***.8.128.20]2026年06月16日 23时52分57秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
PHP中如何得到数组的长度
2023-02-28
php中引入文件几种方式的区别
2023-02-28
PHP中把stdClass Object转array的几个方法
2023-02-28
PHP中替换换行符
2023-02-28
PHP中有关正则表达式的函数集锦
2023-02-28
Redis 集群搭建详细指南
2023-02-28
php中的cookie用法
2023-02-28
php中的session用法
2023-02-28
php中级联,php实现三级级联下拉框_PHP
2023-02-28
PHP中获取星期的几种方法
2023-02-28
Redis 限速器及问题
2023-03-01
php中高级基础知识点
2023-03-01
php中,如何将编译后的代码,反编译回去。
2023-03-01
php之aop实践
2023-03-01
PHP之APC缓存详细介绍(转)
2023-03-01
php之memcache,memcached
2023-03-01
php之引用
2023-03-01
PHP之数组和函数的基本教程
2023-03-01
UVa 10465 - Homer Simpson
2023-03-01
php九九乘法表加粗,PHP九九乘法表
2023-03-01