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

2023-08-06 13:59:50

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')

在这里插入图片描述

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

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入门到项目实战》

更多推荐

短视频矩阵系统,短视频矩阵源码技术开发

开发短视频矩阵系统的源码需要以下步骤:确定系统需求:根据客户的需求,确定系统的功能和特点,例如用户注册登录、视频上传、视频浏览、评论点赞等。设计系统架构:根据系统需求,设计系统的整体架构,包括前端、后端、数据库等组件的功能和交互方式。选择技术栈:根据系统的特点和需求,选择适合的技术栈,包括前端框架、后端语言、数据库等。

【每日一题】74. 搜索二维矩阵

74.搜索二维矩阵-力扣(LeetCode)给你一个满足下述两条属性的mxn整数矩阵:每行中的整数从左到右按非递减顺序排列。每行的第一个整数大于前一行的最后一个整数。给你一个整数target,如果target在矩阵中,返回true;否则,返回false。示例1:输入:matrix=[[1,3,5,7],[10,11,1

旅游旺季,酒店要如何做好报修管理工作?

随着旅游业的蓬勃发展,每年的旅游旺季都会带来大量的游客涌入各个城市和景区,这也使得酒店行业的客流量激增。为了满足客人的需求,酒店必须提供高质量的服务和舒适的住宿环境。然而,由于客流量的增加,酒店的设备使用频率也随之增加,容易出现故障和损坏的情况。这不仅会影响客人的入住体验,还可能引发安全隐患。因此,酒店管理者需要高度关

快速用Python进行数据分析技巧详解

概要一些小提示和小技巧可能是非常有用的,特别是在编程领域。有时候使用一点点黑客技术,既可以节省时间,还可能挽救“生命”。一个小小的快捷方式或附加组件有时真是天赐之物,并且可以成为真正的生产力助推器。所以,这里有一些小提示和小技巧,有些可能是新的,但我相信在下一个数据分析项目中会让你非常方便。Pandas中数据框数据的P

基于JAVA+SSM+微信小程序+MySql的图书捐赠管理系统设计与实现

✌全网粉丝20W+,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌🍅文末获取项目下载方式🍅一、项目背景介绍:在当今社会,图书捐赠是一种普遍而有益的行为,旨在促进阅读、教育和知识传播。图书捐赠可

手动模式配置链路聚合

以下图配置为例:各PC配置如下配置LSW1#划分vlan1030<Huawei>sysEntersystemview,returnuserviewwithCtrl+Z.[Huawei]sysnameLSW1[LSW1]diSep16202314:23:44-08:00LSW1DS/4/DATASYNC_CFGCHANG

记:sx1278芯片

目录lora数字接口静态配置寄存器状态寄存器lora模式FIFO数据缓存数字IO引脚映射FIFO操作原理lora调制解调器操作模式LoRa调制解调器状态机序列数据发送序列数据接收序列单一接收操作模式连续接收操作模式从FIFO数据缓存提取有效负载数据基于前导码起始的数据包过滤lora数字接口lora调制解调器有三种数字接

计算物理专题----随机游走实战

计算物理专题----随机游走实战Problem1Implementthe3Drandomwalk拟合线自旋的拟合函数(没有数学意义)参数:0.627,3.336,0.603,-3.234自由程满足在一定范围内的均匀分布以标准自由程为单位长度,可得到均匀分布的统计特征方均根距离与平均自由程的比值满足P1-a.pyimpo

【Redis】深入探索 Redis 的哨兵(Sentinel)机制原理,基于 Docker 模拟搭建 Redis 主从结构和哨兵分布式架构

文章目录一、对RedisSentinel的认识1.1什么是RedisSentinel1.2为什么要使用RedisSentinel1.2.1主从复制问题1.2.2人工恢复主节点故障二、RedisSentinel原理剖析2.1RedisSentinel架构2.2Raft算法和领袖节点2.3哨兵节点2.4故障检测2.5故障切

JimuReport积木报表 v1.6.2 版本正式发布—开源免费的低代码报表

项目介绍一款免费的数据可视化报表,含报表和大屏设计,像搭建积木一样在线设计报表!功能涵盖,数据报表、打印设计、图表报表、大屏设计等!Web版报表设计器,类似于excel操作风格,通过拖拽完成报表设计。秉承“简单、易用、专业”的产品理念,极大的降低报表开发难度、缩短开发周期、节省成本、解决各类报表难题。领先的企业级Web

BIO AIO NIO 的区别

BIOAIONIO是Java中用于I/O操作的三种不同的编程模型。它们的区别在于它们执行I/O操作的方式和效率。在讲BIO,NIO,AIO之前先来回顾一下这样几个概念:同步与异步,阻塞与非阻塞。同步与异步同步:同步就是发起一个调用后,被调用者未处理完请求之前,调用不返回。异步:异步就是发起一个调用后,立刻得到被调用者的

热文推荐