【Opencv入门到项目实战】(四):图像梯度计算|Sobel算子|Scharr算子|Laplacian算子

文章目录

  • 0.引言
  • 1. Sobel算子
  • 2. Scharr算子
  • 3. Laplacian算子

0.引言

在图像处理中,梯度是指图像中像素灰度变化的速率或幅度,我们先来看下面这张图

假设我们想要计算出A点的梯度,我们可以发现A点位于边缘点,A点左边为黑色,右边为白色,而计算图像的梯度可以提取出图像中的边缘信息,我们常用的方法是使用Sobel算子Scharr算子进行梯度计算。接下来我们分别来看看具体是如何做的

1. Sobel算子

和我们之前介绍的各种图像计算的方法类似,我们利用某一个大小的卷积核来进行计算,我们这里也一样,Sobel算子有两个核,一个用于计算图像在水平方向上的差异(x方向梯度),另一个用于计算图像在垂直方向上的差异(y方向梯度)。这两个核可以在水平和垂直方向上检测出图像中的边缘信息。

下面是Sobel算子在x和y方向上的核矩阵:

image-20230801222810068

我们来看他这个是如何来识别边缘的,以x方向为例,如果两边相差太大了,那么结果的绝对值也会比较大,说明应该在边缘点附近,如果两边值非常接近,则结果也会趋于0,此时说明不在边缘地附近。y方向也是同理。接下来我们看一下如何在Opencv中实现,我们调用cv2.Sobel()函数,

dst = cv2.Sobel(src, ddepth, dx, dy, ksize)
  • ddepth:输出图像的深度(数据类型),一般我们指定为64位浮点数型,设为CV_64F
  • dx和dy分别表示水平和竖直方向
  • ksize是Sobel算子的大小

我们以下面这张图为例计算梯度,

# 导入原始图
img = cv2.imread('pie.png',cv2.IMREAD_GRAYSCALE)
cv2.imshow("img",img)
cv2.waitKey()
cv2.destroyAllWindows()

image-20230801224507395

x方向计算梯度

# 定义图像展示函数
def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()

sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
cv_show(sobelx,'sobelx')

image-20230801224706224

我们发现只有一半。我们来思考一个问题哈,从黑到白是正数,白到黑就是负数了,所有的负数会被截断成0,所以导致我们右半边的边缘无法显示,因此我们要取绝对值来解决这个问题。

我们调用cv2.convertScaleAbs(sobelx) 实现将结果转换为无符号8位整数

sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobelx = cv2.convertScaleAbs(sobelx) #实现将结果转换为无符号8位整数
cv_show(sobelx,'sobelx')

image-20230801224952929

现在我们基本找到了边缘,接下来我们还需要看y方向的情况

计算y方向的梯度

sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobely = cv2.convertScaleAbs(sobely)  
cv_show(sobely,'sobely')

image-20230801225145764

现在我们分别得到了x方向和y方向的边缘,接下来我们进行求和处理。

求和

调用cv2.addWeighted函数

sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
cv_show(sobelxy,'sobelxy')

image-20230801225247382

接下来,我们以之前小狗洋气的图片来看一下它的梯度结果

# 原始图像
img = cv2.imread('yangqi.jpg',cv2.IMREAD_GRAYSCALE)
cv_show(img,'img')

image-20230801230038445

接下来我们来看一下求梯度后的结果

img = cv2.imread('yangqi.jpg',cv2.IMREAD_GRAYSCALE)
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobely = cv2.convertScaleAbs(sobely)
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
cv_show(sobelxy,'sobelxy')

image-20230801230148282

可以看到,我们吧图片所有的轮廓都给提取出来了。

Sobel算子具有简单且易于实现的优点,它对噪声有一定的抑制作用,并可以快速检测出图像中的边缘。然而,Sobel算子也存在一些局限性,如对于较弱的边缘响应不敏感,并且可能会产生较粗的边缘。对于更复杂的场景,可能需要结合其他的边缘检测算法或采用更高级的技术。

2. Scharr算子

Scharr算子和Sobel算子很像,但在边缘检测方面具有更好的性能。Scharr算子也是基于一阶导数的近似,和Sobel算子一样,Scharr算子也有两个3x3的核、

具体核矩阵如下:

image-20230801230310957

在Opencv中,我们调用cv2.Scharr()函数实现。

scharrx = cv2.Scharr(img,cv2.CV_64F,1,0)
scharry = cv2.Scharr(img,cv2.CV_64F,0,1)
scharrx = cv2.convertScaleAbs(scharrx)   
scharry = cv2.convertScaleAbs(scharry)  
scharrxy =  cv2.addWeighted(scharrx,0.5,scharry,0.5,0) cv_show(scharrxy,'scharr')

image-20230801232322062

从结果来看,与Sobel算子相比,检测出来的边缘更多,因为Scharr算子具有更高的方向敏感性和更好的旋转不变性,能够更准确地检测到边缘,并且在边缘方向变化较大的情况下效果更好。因此,在很多应用中,Scharr算子常常被用作替代Sobel算子的选择。

3. Laplacian算子

Laplacian算子常用于检测图像中的边缘和纹理,但是它计算图像的二阶导数,以此捕捉到图像中的灰度变化,它只有一个核

image-20230801232016698

在Opencv中,我们调用cv2.Laplacian()函数实现,因为这里只有一个核,因此不用分别计算x方向和y方向,直接计算一个即可

laplacian = cv2.Laplacian(img,cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian)   

image-20230801232556834

从结果来看,Laplacian单独使用对边缘检测的效果一般,因为它是一个二阶导数运算,所以图像中的噪声会被放大。因此,在应用Laplacian算子之前,可能需要对图像进行预处理,例如平滑/模糊来降低噪声的影响,我们一般不会单独使用Laplacian算子,而是结合其他的方法使用。

🔎本章的介绍到此介绍,如果文章对你有帮助,请多多点赞、收藏、评论、订阅支持!!《Opencv入门到项目实战》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/61463.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

74. 搜索二维矩阵

题目链接:力扣 解题思路:因为矩阵整体上是有序的,所以可以先二分查找target在哪一行中,然后再次二分查找target在当前行的哪一列中。 具体算法如下: 对行使用二分查找: 初始值: int m matrix…

Mr. Cappuccino的第55杯咖啡——Mybatis一级缓存二级缓存

Mybatis一级缓存&二级缓存 概述一级缓存特点演示前准备效果演示在同一个SqlSession中在不同的SqlSession中 源代码怎么禁止使用一级缓存一级缓存在什么情况下会被清除 二级缓存特点演示前准备效果演示在不同的SqlSession中 源代码怎么关闭二级缓存 一级缓存(Spr…

ad+硬件每日学习十个知识点(18)23.7.29 (LDO原理、LDO的补偿引脚)

文章目录 1.LDO名字介绍2.LDO的应用范围3.LDO的原理4.LDO输出端和输入端的差值至少满足多少V?怎么计算的?5.输出的误差和输出电流👆(右下角图像)6.LDO一般会有个引脚是做补偿之用,datasheet会说明一个器件的…

C++20 协程(coroutine)入门

文章目录 C20 协程(coroutine)入门什么是协程无栈协程和有栈协程有栈协程的例子例 1例 2 对称协程与非对称协程无栈协程的模型无栈协程的调度器朴素的单线程调度器让协程学会等待Python 中的异步函数可等待对象M:N 调度器——C# 中的异步函数 小结 C20 中…

如何在 Ubuntu 上部署 ONLYOFFICE 协作空间社区版?

ONLYOFFICE 协作空间是一个在线协作平台,帮助您更好地与客户、业务合作伙伴、承包商及第三方进行文档协作。今天我们来介绍一下,如何在 Ubuntu 上安装协作空间的自托管版。 ONLYOFFICE 协作空间主要功能 使用 ONLYOFFICE 协作空间,您可以&am…

安全文件传输的重要性及其对企业的影响

在当今的信息时代,企业之间的文件传输已经成为日常工作的重要组成部分。无论是在商务合作、人力资源还是财务审计等方面,文件传输都发挥着关键的作用。然而,随着网络技术的发展,网络安全问题也日益突出,泄漏、篡改、丢…

复习之selinux的管理

一、什么是selinux? SELinux,Security Enhanced Linux 的缩写,也就是安全强化的 Linux,是由美国国家安全局(NSA)联合其他安全机构(比如 SCC 公司)共同开发的,旨在增强传统 Linux 操…

Jmeter 压测工具使用手册[详细]

1. jemter 简介 jmeter 是 apache 公司基于 java 开发的一款开源压力测试工具,体积小,功能全,使用方便,是一个比较轻量级的测试工具,使用起来非常简 单。因为 jmeter 是 java 开发的,所以运行的时候必须先…

paddlenlp:社交网络中多模态虚假媒体内容核查

初赛之环境配置篇 一、背景二、任务三、数据集1、初赛阶段2、评分标准 四、环境操作五、写在最后 一、背景 随着新媒体时代信息媒介的多元化发展,各种内容大量活跃在媒体内中,与此同时各类虚假信息也充斥着社交媒体,影响着公众的判断和决策。…

vue3—SCSS的安装、配置与使用

SCSS 安装 使用npm安装scss: npm install sass sass-loader --save-dev 配置 配置到全局 🌟附赠代码🌟 css: {preprocessorOptions: {scss: {additionalData:import "./src/Function/Easy_I_Function/Echarts/ToSeeEcharts/utill.…

防火墙规则分析管理

防火墙规则在高效的网络安全管理中起着至关重要的作用,在添加规则之前,确保提议的新规则不会对网络产生负面影响至关重要。 通过防火墙规则影响分析,安全管理员可以详细了解添加新规则的可能影响,防火墙规则影响分析的一个重要方…

智能卡通用安全检测指南 思度文库

范围 本标准规定了智能卡类产品进行安全性检测的一般性过程和方法。 本标准适用于智能卡安全性检测评估和认证。 规范性引用文件 下列文件对于本文件的应用是必不可少的。凡是注日期的引用文件,仅注日期的版本适用于本文件。凡是不注日期的引用文件,…

git仓库与本地暂存区的同步问题

向下同步 对于远程仓库的项目,初始化一个配置文件,配置远程仓库及相关信息,赋值远程仓库的地址,使用git pull命令即可拉取仓库代码。 git pull [remote_addr] 该部分完成向下同步 向上同步 向上同步时会遇到很多的问题&#xf…

6.3 填充和步幅

一.填充 1.作用: 为了防止丢失边缘像素。如240x240的像素图像,经过10层5x5卷积,变成了200x200像素。可以根据输出形状计算公式 (w-k1) x (h-k1)计算得出。 2.方法: 最常用的方法是填充0。如下: 3.公式:计算填充原…

matlab计算基础

目录 1. 创建矩阵和向量 2. 矩阵的基本运算 2.1 数乘 2.2 转秩 2.3 求逆 2.4 点积 2.5 拼接 3. 复数 4. 矩阵元素的引用 5.工作区中数据的保存和使用 1. 创建矩阵和向量 向量包括行向量和列向量,向量就是个特殊的矩阵,向量可看作C语言中的一维…

SpringBoot手撕登陆验证码-【JSB项目实战】

SpringBoot系列文章目录 SpringBoot知识范围-学习步骤【JSB系列之000】 文章目录 SpringBoot系列文章目录本系列校训 SpringBoot技术很多很多环境及工具:上效果图目前流行的验证码技术介绍在springBoot项目里如果手撕验证码然后private void createCaptch(String …

SpringBoot第31讲:SpringBoot集成ShardingJDBC - Sharding-JDBC简介和基于MyBatis的单库分表

SpringBoot第31讲:SpringBoot集成ShardingJDBC - Sharding-JDBC简介和基于MyBatis的单库分表 本文是SpringBoot第31讲,主要介绍分表分库,以及SpringBoot集成基于ShardingJDBCMyBatis的单库分表实践 文章目录 SpringBoot第31讲:Spr…

continue有什么作用

学习算法以来&#xff0c;break使用的比较多&#xff0c;continue使用的比较少&#xff0c;只知道break是跳出循环的作用,不知道continue有什么作用。 continue可以跳过本次循环&#xff0c;强制执行下一次循环。 比如这个代码 #include<iostream>using namespace std…