本次笔记要整理记录一些常用的导数算子,包括一阶导数算子和二阶导数算子等,这些导数算子种类比较繁杂,统一记录起来会比较容易回顾。

- 常见一阶导数算子
对于图像求一阶导数,就是求图像灰度曲线的导数,所以在灰度曲线中变化较大的区域,在导数曲线中体现出绝对值比较大的值,而灰度曲线中变化平坦的区域,在导数曲线中体现出接近零的值,通过求一阶导数的处理,能突出图像中对象的边缘,并且还具有方向性。
常用的一阶导数算子主要有:Robert算子、prewitt算子、sobel算子。
下面分别给出这三个算子的代码实现:

  1. Robert算子
 Mat robertx_image;Mat robert_x = (Mat_<int>(2, 2) << 1, 0, 0, -1);             //robert_xfilter2D(image, robertx_image, CV_32F, robert_x);                     convertScaleAbs(robertx_image, robertx_image);                              //将输入数组均转化为uchar类型Mat roberty_image;Mat robert_y = (Mat_<int>(2, 2) << 0, -1, 1, 0);           //robert_yfilter2D(image, roberty_image, CV_32F, robert_y);convertScaleAbs(roberty_image, roberty_image);Mat robert_image;add(robertx_image, roberty_image, robert_image, Mat(), CV_16S);convertScaleAbs(robert_image, robert_image);imshow("robert_image", robert_image);

其中,定义了robert算子的x方向和y方向,分别是Mat robert_x = (Mat_<int>(2, 2) << 1, 0, 0, -1)Mat robert_y = (Mat_<int>(2, 2) << 0, -1, 1, 0),然后通过filter2D这个API对图像和算子分别卷积,要注意图像求梯度后存在浮点数,需要使用浮点(如CV_32F)类型,最后将x和y方向的两个结果进行相加,并且转换到CV_8UC类型,就可以显示出输出图像了。
效果如下(分别是x、y方向的梯度,以及完整图像梯度):


2.prewitt算子

 //prewitt算子Mat prewitt_x_image, prewitt_y_image, prewitt_image;Mat prewitt_x = (Mat_<int>(3, 3) << -1, 0, 1, -1, 0, 1, -1, 0, 1);filter2D(image, prewitt_x_image, CV_32F, prewitt_x);convertScaleAbs(prewitt_x_image, prewitt_x_image);Mat prewitt_y = (Mat_<int>(3, 3) << -1, -1, -1, 0, 0, 0, 1, 1, 1);filter2D(image, prewitt_y_image, CV_32F, prewitt_y);convertScaleAbs(prewitt_y_image, prewitt_y_image);add(prewitt_x_image, prewitt_y_image, prewitt_image, Mat(), CV_16S);convertScaleAbs(prewitt_image, prewitt_image);imshow("prewitt_image", prewitt_image);

其中同样分别定义了prewitt算子的x、y方向:Mat prewitt_x = (Mat_<int>(3, 3) << -1, 0, 1, -1, 0, 1, -1, 0, 1)Mat prewitt_y = (Mat_<int>(3, 3) << -1, -1, -1, 0, 0, 0, 1, 1, 1),分别与图像计算卷积后再进行相加,转换数据类型后显示输出图像。
效果如下:



3.sobel算子

 Mat x_grad, y_grad, image_grad;//Sobel算子求梯度后的值为浮点型且超过[0,  255]Sobel(image, x_grad, CV_32F, 1, 0, 3, 1, 0, 4);Sobel(image, y_grad, CV_32F, 0, 1, 3, 1, 0, 4);convertScaleAbs(x_grad, x_grad);            //转化至CV_8UCimshow("x_grad", x_grad);convertScaleAbs(y_grad, y_grad);          //转化至CV_8UCimshow("y_grad", y_grad);add(x_grad, y_grad, image_grad, Mat(), CV_16S);       //两个[0,255]范围的值相加,输出深度为CV_16S(16位有符号整型)convertScaleAbs(image_grad, image_grad);imshow("image_grad", image_grad);

Sobel算子的优势是,相比prewitt算子能更好的抑制噪声。而且不需要我们自定义卷积核,而是OpenCV提供了一个专门的APISobel(image, x_grad, CV_32F, 1, 0, 3, 1, 0, 4)
其第一个参数是要计算梯度的输入图像;
第二个参数是处理完的输出图像;
第三个参数是输出图像的深度;
第四个参数dx,为1时表示计算x方向梯度,为0表示不计算x方向梯度;
第五个参数dy,为1时表示计算y方向梯度,为0表示不计算y方向梯度;
第六个参数ksize是计算梯度的卷积核大小;
后面几个参数分别是缩放量(输出图像相比输入图像的缩放)、增加常量(输出图像相比输入图像增加的常量)、边缘填充方式,如果没有特殊需求都选用默认值即可。
效果如下:

- 常见二阶导数算子
二阶导数算子是对图像灰度曲线的导数求导,也就是在一阶导数的基础上再次求导,对灰度值的剧烈变化敏感,能突出图像的纹理结构,并且不具有方向性。
常见的二阶导数算子主要有拉普拉斯算子和canny边缘检测算子。

1.拉普拉斯算子

 ////拉普拉斯算子Mat gaussianBlur_image, laplacian_image_4, laplacian_image_8;GaussianBlur(image, gaussianBlur_image, Size(), 1, 1);Laplacian(gaussianBlur_image, laplacian_image_4, CV_32F, 1, 1, 127);           convertScaleAbs(laplacian_image_4, laplacian_image_4);Laplacian(gaussianBlur_image, laplacian_image_8, CV_32F, 3, 1, 127);          convertScaleAbs(laplacian_image_8, laplacian_image_8);imshow("laplacian_image_4", laplacian_image_4);imshow("laplacian_image_8", laplacian_image_8);

拉普拉斯算子对于噪声非常敏感,所以需要先对原图进行高斯模糊后再提取梯度,在某些场合下会将高斯模糊和拉普拉斯边缘提取合并起来,即为LOG算子。
OpenCV中提供一个API实现拉普拉斯算子的运算:Laplacian(gaussianBlur_image, laplacian_image_4, CV_32F, 1, 1, 127)
第一个参数是经过高斯模糊后的图像;
第二个参数是输出图像;
第三个参数是输出图像的深度;
第四个参数是ksize,当ksize = 1 使用4邻域的拉普拉斯算子;当ksize > 1 使用8邻域的拉普拉斯算子;
第五个参数是缩放值;
第六个参数是输出图像加上的常量,因为二阶导数求得值很小,为了便于观察可以加上一个delta值来提高显示亮度。
效果如下:

左边是四邻域的拉普拉斯算子,右边是八邻域的拉普拉斯算子提取,可见使用八邻域的拉普拉斯算子的纹理提取效果比四邻域要好得多,能看得到更多的细节,轮廓也更加清晰。

2.Canny边缘检测
Canny边缘检测的主要步骤:
1、 高斯模糊 – 抑制噪声;
2、梯度提取得到候选边缘;
3、角度计算与非最大信号抑制;
4、高低阈值链接、获取完整边缘;
5. 输出边缘;
其中,第一、二步骤可以采用LOG算子实现,或使用高斯模糊加Sobel算子实现;第三步计算每个像素点的边缘幅值和角度,并进行非最大信号抑制,主要目的是实现边缘细化,使得边缘像素进一步减少(个人对非最大信号抑制的理解:对已经提取出的离散的边缘像素,与其邻域内的像素进行比较,若不是邻域的最大值则将其从边缘像素中剔除,若为最大值则保留为边缘像素);第四步是在边缘像素点集中进行筛选,将小于低阈值的像素点除去,将大于高阈值的像素点保留,对介于高低阈值区间的像素点则进行判断:该像素点是否与位于高阈值及以上的像素点相连通,若有连通域则在边缘像素点集中保留该像素点,若没有连通域则剔除该像素点;最后第五步以二值图像输出边缘。
当然了在OpenCV中已经封装好了这些功能,不需要我们自己实现,我们可以调用相关API即可,下面是代码:

Mat image_canny; Canny(image, image_canny, 200, 500, 5, false);imshow("image_canny", image_canny);Mat image_and, image_add;bitwise_and(image, image, image_and, image_canny);      imshow("image_and", image_and);addWeighted(image, 1, image_and, 0.2, 0, image_add, CV_16S);   convertScaleAbs(image_add, image_add);imshow("image_add", image_add);

主要APICanny(image, image_canny, 200, 500, 5, false)
第一个参数是输入图像;
第二个参数是输出图像;
第三和第四个参数:参数threshold1表示低阈值,参数threshold2表示高阈值(上限尽量不超过500);经验值是设置threshold1:threshold2 = 1:2到1:3之间效果较好
第五个参数apertureSize:进行梯度运算(Sobel算子)的窗口大小,默认值为3
第六个参数L2gradient:布尔类型,表示是否使用L2计算梯度,即使用矢量和计算;默认为false,即默认使用平方和计算梯度。
上述代码中,将canny边缘检测提取出的边缘与原图像进行求与(and)运算,得到有色彩的边缘,再将边缘和原图像按权重相加,最后的输出结果增强了原图像细节纹理,但视觉感受上存在撕裂感。效果如下:

最左边是进行canny提取后的边缘图像,中间是和原图像求与(and)运算后的彩色边缘,最右边是彩色和原图像按权重相加的结果,可见虽然纹理部分变得明显了,但是却显得很不自然。

本次关于图像导数算子的整理就到此结束啦,谢谢~

PS:本人的注释比较杂,既有自己的心得体会也有网上查阅资料时摘抄下的知识内容,所以如有雷同,纯属我向前辈学习的致敬,如果有前辈觉得我的笔记内容侵犯了您的知识产权,请和我联系,我会将涉及到的博文内容删除,谢谢!

OpenCV4学习笔记(17)——常用导数算子相关推荐

  1. Python学习笔记:常用内建模块6 (urllib)

    前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...

  2. jquery学习笔记及常用函数封装

    二.JQuery 学习笔记及常用函数封装 https://download.csdn.net/download/weixin_42530002/13087988 1.JQuery入门 (1).css选 ...

  3. OpenCV4学习笔记(41)——ORB特征提取描述算法

    今天要整理记录的笔记内容是特征算法中比较常用的一种--ORB特征提取描述算法,顾名思义,ORB算法包含了对特征点的提取和描述这两个部分.而在上次的博文<OpenCV4学习笔记(39)>中, ...

  4. Python学习笔记:常用第三方模块3

    前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...

  5. Python学习笔记:常用第三方模块(1)

    前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...

  6. Python学习笔记:常用内建模块4:hmac

    前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...

  7. Python学习笔记:常用内建模块3:struct

    前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...

  8. springmvc学习笔记(17)-上传图片

    2019独角兽企业重金招聘Python工程师标准>>> springmvc学习笔记(17)-上传图片 标签: springmvc [TOC] 本文展示如何在springmvc中上传图 ...

  9. OPENCV-4 学习笔记

    OPENCV-4 学习笔记 ROI-设定感兴趣的区域(region of interest) 定义: Mat imageROI; //方法一:通过Rect指定矩形区域 imageROI=image(R ...

  10. OpenCV4学习笔记(57)——基于GrabCut图像分割算法实现背景替换与背景虚化效果

    在上一篇笔记<OpenCV4学习笔记(56)>中,整理了关于在OpenCV中使用GrabCut图像分割算法的相关内容,那么本次笔记就以GrabCut算法为基础来实现对图像的背景替换和背景虚 ...

最新文章

  1. Ubuntu 上创建常用磁盘阵列
  2. 《编写可维护的JavaScript》——1.7 直接量
  3. SpringBoot2.0配置redis相关
  4. Hibernate关联关系配置(一对多,一对一,多对多)
  5. oracle中直方图的使用
  6. Java EE之Hibernate异常总结【5】java.lang.StackOverflowError[栈溢出]
  7. 03、了解自动配置原理笔记
  8. 選大學了﹖請看“上大學”網
  9. 冒死曝光这个软件,希望不要被封杀!
  10. 计算广告学 学习资料
  11. 18位身份证校验代码
  12. 基于服务的多源异构数据整合平台解决方案
  13. 武汉代茜2017级计算机科学与技术,毕业论文致谢拾贝(二)
  14. 腾讯云PCDN:从P2P到万物互联服务框架
  15. Unity5权威讲解 笔记
  16. 【Python2】使用python中的turtle模块学习海龟绘图(有趣的python初体验)(最全最详细的turtle介绍使用)
  17. 分布式理论分布式ID生成大全
  18. tc流量控制原理和实现
  19. 初学GWT-安装GWT
  20. 信息技术时代杂志信息技术时代杂志社信息技术时代编辑部2022年第9期目录

热门文章

  1. HKC PG27P3评测 HKC PG27P3怎么样
  2. HTML怎么消除链接下划线,HTML怎么去掉超链接的下划线
  3. MSC-VO: 基于曼哈顿和结构约束的视觉里程计(CVPR 2021)
  4. 聊聊测试覆盖率的六大门派
  5. 微信小程序中如何有效的修改app.js中全局变量的值,并能在页面中进行动态响应
  6. ajax2 cors跨域,Koa2框架应用CORS完成跨域ajax要求
  7. C/C++ abs 函数 - C语言零基础入门教程
  8. html中图片一角的卷起效果,CSS3实现图片折角效果例子
  9. 重装系统之制作U盘启动盘 - 一盘通装
  10. 华为云文字识别关键技术和特别需要注意的事宜