开头一下:
本篇博客主要介绍边缘检测所涉及的三大算子,分别是Sobel算子、Canny算子、Laplacian算子)。上篇博客python版CV也介绍了这三个算子的用法。


文章目录

  • 1、sobel算子
    • 1.1 sobel算子的基本概念
    • 1.2 sobel算子的计算过程
    • 1.3 使用Sobel算子:Sobel()函数
    • 1.4 示例程序
  • 2、canny算子
    • 2.1 Canny边缘检测的步骤
    • 2.2 Canny边缘检测:Canny()函数
    • 2.3 示例程序
  • 3、Laplacian算子
    • 3.1 Laplacian算子简介
    • 3.2 拉普拉斯变换:Laplacian()函数
    • 3.3 示例程序

首先介绍一下边缘检测的步骤:

(1)滤波

边缘检测的算法主要是基于图像强度的一阶和二阶导数,但导数通常对噪声很敏感,因此必须采用滤波器来改善与噪声有关的边缘检测器的性能。常见的滤波方法主要有高斯滤波,即采用离散化的高斯函数产生一组归一化的高斯核,然后基于高斯核函数对图像灰度矩阵的每一点进行加权求和。

(2)增强

增强边缘的基础是确定图像各点邻域强度的变化值。增强算法可以将图像灰度点邻域强度值有显著变化的点凸显出来。在具体编程通过梯度幅值来确定

(3)检测

经过增强的图像,往往邻域中有很多点的梯度值比较大,而在特定的应用中,这些点并不是要找的边缘点,所以应该采用某种方法来对这些点进行取舍。实际工程中,常用的方法是通过阈值化方法来检测


1、sobel算子

1.1 sobel算子的基本概念

Sobel算子是一个主要用于边缘检测的离散微分算子。它结合了高斯平滑核微分求导,用来计算图像灰度函数的近视似梯度。在图像的任何一点使用此算子,都将会产生对于的梯度矢量或其法矢量

1.2 sobel算子的计算过程

(1)分别在x和y两个方向求导

  • 水平变化:将I与一个奇数大小的内核Gx进行卷积。比如,当内核大小为3时,Gx的计算结果:
    Gx=I3−I1+2∗I6−2∗I4+I9−I7Gx=I3-I1+2*I6-2*I4+I9-I7 Gx=I3−I1+2∗I6−2∗I4+I9−I7

  • 垂直变化:将I与一个奇数大小的内核进行卷积。比如,当内核大小为3时,Gx的计算结果:
    Gy=I3−2∗I2−I1+I9+2∗I8+I7Gy=I3-2*I2-I1+I9+2*I8+I7 Gy=I3−2∗I2−I1+I9+2∗I8+I7

(2)在图像的每一点,结合以上两个今儿个求出近似梯度:
G=sqrt(Gx2+Gy2)G=sqrt(Gx^2+Gy^2) G=sqrt(Gx2+Gy2)
有时也可以用下面公式代替:
G=∣Gx∣+∣Gy∣G=|Gx|+|Gy| G=∣Gx∣+∣Gy∣

1.3 使用Sobel算子:Sobel()函数

void Sobel(InputArray src,OutputArray dst,int ddepth,int dx,int dy,int kszie=3,double scale=1,double delta=0,int borderType=BORDER_DEFAULT);
  • 第一个参数:输入图像,填Mat类型即可

  • 第二个参数:目标图像,函数的输出参数,需要和源图片有一样的尺寸和类型

  • 第三个参数:输出图像的深度,支持如下组合:

    • 若src.depth()=CV_8U,取ddepth=-1/CV_16S/CV_32F/CV_64F
    • 若src.depth()=CV_16U/CV_16S,取ddepth=-1/CV_32F/CV_64F
    • 若src.depth()=CV_32F,取ddepth=-1/CV_32F/CV_64F
    • 若src.depth()=CV_64F,取ddepth=-1/CV_64F
  • 第四个参数:x方向上的差分阶数

  • 第五个参数:y方向上的差分阶数

  • 第六个参数:核大小,取1,3,5,7

  • 第七个参数:double类型的scale,计算导数值时可选的缩放因子,默认值是1,表示默认情况下是没有应用缩放的。

  • 第八个参数:double类型的delta,表示存入目标图

  • 第九个参数:边界模式。有默认值:BORDER_DEFAULT

补充说明:

(1)当内核大小为3时,Sobel内核可能产生比较明显的误差。所以OpenCV提供了Scharr函数,但该函数仅作用于大小为3的内核。比Sobel函数的结果更加精确

(2)Sobel算子结合了高斯平滑核分化,因此结果会具有更多的抗噪性:

计算图像X方向的导数,取【xorder=1,yorder=0,ksize=3】,对应内核:

计算图像Y方向的导数,取【xorder=0,yorder=1,ksize=3】,对应内核:

1.4 示例程序

#include<opencv2/opencv.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main()
{//创建grad_x和grad_y矩阵Mat grad_x, grad_y;Mat abs_grad_x, abs_grad_y, dst;//载入原始图Mat src = imread("E:\\Pec\\fushiyuan.jpg");imshow("【原始图】", src);//求X方向的梯度Sobel(src, grad_x, CV_16S, 1, 0, 3, 1, 1, BORDER_DEFAULT);//白到黑是正数,黑到白是负数,所有的负数都会截断成0,所以要取绝对值convertScaleAbs(grad_x, abs_grad_x);imshow("【效果图】X方向Sobel", abs_grad_x);//求Y方向的梯度Sobel(src, grad_y, CV_16S, 0, 1, 3, 1, 1, BORDER_DEFAULT);//白到黑是正数,黑到白是负数,所有的负数都会截断成0,所以要取绝对值convertScaleAbs(grad_y, abs_grad_y);imshow("【效果图】Y方向Sobel", abs_grad_y);//合并梯度addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, dst);imshow("【效果图】正题方向", dst);waitKey(0);
}

2、canny算子

2.1 Canny边缘检测的步骤

(1)【第一步】图像灰度化

canny算法处理的图像为灰度图,因此如果摄像机获取的是彩色图像,那首先就得进行灰度化。对一幅彩色图进行灰度化,就是根据图像各个通道的采样值进行加权平均。

Gary=(R+G+B)/3Gary=(R+G+B)/3 Gary=(R+G+B)/3
(2)【第二步】消除噪声

一般情况下,使用高斯平滑滤波器卷积降噪,以下显示一个size=5的高斯内核示例:

(3)【第三步】计算梯度幅值和方向

此处:按照Sobel滤波器的步骤来操作,索贝尔算子(Sobel
operator)是图像处理的算子之一,主要用作边缘检测。技术上是离散型差分算子,用来运算图像亮度函数的梯度之近视值。

  • 运用一对卷积阵列(分别作用于x和y方向)

  • 使用下列公式计算梯度赋值和方向,梯度方向取的角度一般是0°,45°,90°,135°

(3)【第三步】非极大值抑制

这一步排除边缘像素,仅仅保留了一些细线条(候选边缘)。在求出的幅值图像中,可能存在多个较大幅值临近的情况,但真正的边缘点只有一个,针对这样的情况进行非极大值抑制,找出局部最大值,从而可以剔除大部分非边缘点。

(4)【第四步】滞后阈值

这是最后一步,Canny使用滞后阈值,滞后阈值需要两个阈值(高阈值和低阈值):

  • 若某一像素位置的幅值超过高阈值,该像素被保留为边缘像素
  • 若某一像素位置的幅值小于低阈值,该像素排除
  • 若某一像素位置的幅值在两个阈值之间,该像素仅仅在连接到一个高于高阈值的像素时被保留

2.2 Canny边缘检测:Canny()函数

void Canny(InputArray image,OutputArray edges,double threshold1,double threshold2,int apertureSize=3,
bool L2gradient=false)
  • 第一个参数:输入图像,即源图像,填Mat类的对象即可,且需为单通道8为图像
  • 第二个参数:输出的边缘图,需要和源图片有一样的尺寸和类型
  • 第三个参数:第一个滞后阈值
  • 第四个参数:第二个滞后阈值
  • 第五个参数:int类型的 apertureSize,表示应用Sobel算子的孔径大小,其默认值3
  • 第六个参数:bool 类型的L2gradient,一个计算图像梯度幅值的标识,有默认值false

注意:函数阈值1和阈值2两者较小的值用于边缘连接,而较大的值用来控制强边缘的初始段,推荐的高低阈值比在2 :1到3 :1之间

2.3 示例程序

#include<opencv2/opencv.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main()
{//载入原始图Mat src = imread("E:\\Pec\\灭霸.jpg");Mat src1 = src.clone();imshow("【原始图】", src);Mat dst,dst1, edge, gray;//创建与src同样类型和大小的矩阵dst.create(src.size(), src1.type());//将原图转换为灰度图像cvtColor(src1, gray, COLOR_BGR2GRAY);//先使用3x3内核来降噪blur(gray, edge, Size(3, 3));//运行Canny算子Canny(gray, edge, 3, 9, 3);//将dst内的所有元素设置为0dst = Scalar::all(0);dst1 = Scalar::all(0);gray.copyTo(dst, edge);src1.copyTo(dst1, edge);imshow("【彩色检测图】", dst1);imshow("【灰度检测图】", dst);waitKey(0);return 0;
}

3、Laplacian算子

3.1 Laplacian算子简介

Laplacian算子是n维欧几里得空间中的一个二阶微分算子,定义为梯度grad的散度div。因此如果f是二阶可微的实函数,则f的拉普拉斯算子定义如下:

(1)f是拉普拉斯算子,也是笛卡坐标系xi中的所有非混合二阶偏导数求和

(2)作为一个二阶微分算子,拉普拉斯算子把C函数映射到C函数。根据图像处理的原理可知,二阶导数可以用来进行检测边缘。因为图像是“二维”,需要在两个方向进行求导。

3.2 拉普拉斯变换:Laplacian()函数

void Laplacian(InputArray src,OutputArray dst,int ddepth,int ksize=1,double scale=1,double delta=0,
intborderType=BORDER_DEFAULT);
  • 第一个参数:输入图像,填Mat类型即可

  • 第二个参数:目标图像,函数的输出参数,需要和源图片有一样的尺寸和类型

  • 第三个参数:目标图像的深度

    • 若src.depth()=CV_8U,取ddepth=-1/CV_16S/CV_32F/CV_64F
    • 若src.depth()=CV_16U/CV_16S,取ddepth=-1/CV_32F/CV_64F
    • 若src.depth()=CV_32F,取ddepth=-1/CV_32F/CV_64F
    • 若src.depth()=CV_64F,取ddepth=-1/CV_64F
  • 第四个参数:int类型的ksize,用于计算二阶导数的滤波器的孔径尺寸,大小必须为正奇数,默认值为1

  • 第五个参数:double类型的scale,计算拉普拉斯值的时候可选的比例因子,默认值1

  • 第六个参数:doubel类型的delta,表示在结果存入目标图,默认值0

  • 第七个参数:边界模式,默认值为BORDER_DEFAULT

注意:Laplacian()函数主要利用sobel算子的运算。

3.3 示例程序

#include<opencv2/opencv.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main()
{Mat src_gray,dst, abs_dst;//载入原始图Mat src = imread("E:\\Pec\\fushi.jpg");imshow("【原始图】", src);//使用高斯滤波消除噪声GaussianBlur(src, src, Size(3, 3), 0, 0, BORDER_DEFAULT);//转为灰度图cvtColor(src, src_gray, COLOR_RGB2GRAY);//使用拉普拉斯函数Laplacian(src_gray, dst, CV_16S, 3, 1, 0, BORDER_DEFAULT);//计算绝对值,并将结果转换成8位convertScaleAbs(dst, abs_dst);imshow("【效果图】", abs_dst);waitKey(0);return 0;
}

【OpenCV】-算子(Sobel、Canny、Laplacian)学习相关推荐

  1. 图像梯度算子——Sobel/scharr/Laplacian

    1.sobel算子 sobel算子可以计算图像梯度,计算图像梯度的作用是提取边界. (1)X方向的梯度 以3x3的卷积核计算sobel算子为例: 图中左边就是计算水平梯度时的卷积核,简单来说就是右边减 ...

  2. 一文解决Opencv四大经典算子——sobel算子、scharr算子、laplacian算子、canny算子

    Opencv四大算子 Sobel算子 Scharr算子 laplacian算子 canny算子 总结 边缘是像素值发生跃迁的位置,是图像的显著特征之一,在图像特征提取,对象检测,模式识别等方面都有重要 ...

  3. Opencv 笔记5 边缘处理-canny、sobel、Laplacian、Prewitt

    一.边缘检测概述 边缘检测是计算视觉中的基本问题,边缘检测的目的是标识图像中亮度变换明显的点.边缘检测大幅度的减少了图像的数据量(分为两种:灰度图像边缘检测和彩色图像边缘检测),并且剔除了不相关的信息 ...

  4. 【OpenCV入门教程之十二】OpenCV边缘检测:Canny算子,Sobel算子,Laplace算子,Scharr滤波器合辑

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/25560901 作者:毛星云(浅墨) ...

  5. python opencv sobel_OpenCV实战(一): Sobel、Laplacian、Canny 边缘检测

    简述 OpenCV边缘检测的一般步骤为: 滤波 增强 检测 常用的边缘检测的算子和滤波器有: Sobel算子 Laplacian算子 Canny算子 Scharr滤波器 以下使用Sobel.Lapla ...

  6. Roberts、Prewitt、Sobel、Laplacian、LoG 和 Canny 边缘检测算子(MATLAB自写函数实现)

    文章目录 Roberts.Prewitt.Sobel.Laplacian.LoG 和 Canny 边缘检测算子(MATLAB自写函数实现) 1理论 1.1 知识引入 1.1.1 图像边缘边缘[1] 1 ...

  7. 【OpenCV入门学习--python】索贝尔算子Sobel operator提取边缘

    例子源于OpenCV官网手册(https://docs.opencv.org/4.x/d2/d2c/tutorial_sobel_derivatives.html) 使用OpenCV函数Sobel() ...

  8. [Python图像处理] 四十二.Python图像锐化及边缘检测万字详解(Roberts、Prewitt、Sobel、Laplacian、Canny、LOG)

    该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门.OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子.图像增强技术.图像分割等,后期结合深度学习研究图像识别 ...

  9. [Python从零到壹] 五十八.图像增强及运算篇之图像锐化Sobel、Laplacian算子实现边缘检测

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  10. opencv for python的图像梯度算子以及canny边缘检测

    opencv for python的图像梯度算子以及canny边缘检测 一.图像梯度算子: 二.Canny边缘检测(一个多级边缘检测算法): 一.图像梯度算子: 1.概念简介(部分引自百度百科): 图 ...

最新文章

  1. 2021全国高校计算机能力挑战赛(初赛)C语言试题一
  2. Jupyter官方神器:可视化 Debug 工具!
  3. 解决tomcat控制台乱码问题
  4. hdu 5504(枚举+找规律)
  5. python之sys模块【获取参数】
  6. Shell多线程操作及线程数控制实例
  7. 微服务API设计的实践与思考总结
  8. 【BZOJ3252】攻略【闵可夫斯基和】【堆启发式合并】
  9. 【渝粤教育】国家开放大学2019年春季 2773特种动物养殖 参考试题
  10. Linux Shell脚本专栏_批量主机远程执行命令脚本_08
  11. 梦想与现实之间的距离
  12. 不同修饰符的访问权限(private,缺省(默认即default),protected,public)
  13. 总结1---CPU之上
  14. opc服务器的时间怎么修改,OPC服务器是否允许在其逻辑中使用源时间戳?(Is OPC server allowed to use source timestamp in its logic?)...
  15. 下docfetcher先下Java,docfetcher怎么用-docfetcher的使用教程 - 河东软件园
  16. 天翼网关如何开启虚拟服务器,天翼网关怎么设置wifi密码?天翼网关如何开启或关闭WIFI...
  17. Gateway统一网关(2021-11-14)
  18. 人生有三重境界:看山是山,看水是水;看山不是山,看水不是水;看山还是山,看水还是水
  19. 创建OMF(Oracle Managed Files,Oracle管理的文件)
  20. 第三批更新鸿蒙系统,emui11第三批更新名单-emui11第三批更新名单介绍 - 系统家园...

热门文章

  1. 远程服务器桌面配置iis6,windows 2003服务器安装 IIS6.0和IIS自带FTP服务器图文教程...
  2. HR人力资源系统软件价格?哪家HR人力管理系统好
  3. java爬虫实例_Java爬虫完整实例源码
  4. c语言程序设计辅导资料pdf,C语言程序设计辅导资料(修订版).pdf
  5. 美区苹果id被禁用原因和解除限制方法
  6. egret农场游戏源码
  7. wifi密码本 字典(免费)
  8. 使用JAVA实现邮件发送功能
  9. proteus元件图片_Proteus模型,元件库
  10. cad细等线体不显示_cad字体cass cass如何修改字体