当前位置: 首页 > news >正文

《图像梯度与常见算子全解析:原理、用法及效果展示》

在这里插入图片描述

简介:本文深入探讨图像梯度相关知识,详细介绍图像梯度是像素灰度值在不同方向的变化速度,并以 “pig.JPG” 图像为例,通过代码展示如何选取图像部分区域并分析其像素值以论证图像梯度与边缘信息的关联。接着全面阐述了 Sobel 算子,包括 ddepth 参数对边缘检测完整性的影响及 dx、dy 参数不同设置的效果差异;Scharr 算子的用法及其相较于 Sobel 算子在准确度上的优势;Laplacian 算子的特性,如在检测微小细节变化方面的优势、对噪声敏感及需先平滑处理的要点,并给出了各算子在图像边缘检测应用中的代码示例与实际效果展示,助力读者深入理解图像梯度与相关算子在图像处理中的作用。
如果本文对你的图像梯度学习有所帮助,请给我点赞收藏关注,我会为你持续提供与OpenCV学习相关的文章。

《图像梯度与常见算子全解析:原理、用法及效果展示》

  • 图像梯度
    • 什么是图像梯度?
  • sobel算子
    • ddepth的用法
    • dx dy参数设置(请记住这里有两个知识点)
  • Scharr算子
  • Laplacian算子(三个知识点)
  • 致谢

图像梯度

什么是图像梯度?

它是指像素灰度值在不同方向的变化速度。我通过OpenCV的代码把这张命名为pig.JPG的图像选择出一部分,给大家展示一下。
这是我项目的文件结构:
在这里插入图片描述
需要图片的可以直接复制,我把他放到文章里了
在这里插入图片描述
我用代码选择出猪猪侠的偏底部的部分展示一下

import numpy as np
import cv2
image = cv2.imread("pig.JPG")
print(image.shape)
image = image[800:850,229:250]
cv2.imshow("image",image)
cv2.waitKey()
cv2.destroyAllWindows()

在这里插入图片描述

我们现在已经把这个猪猪侠的腿部选出来了,我们去打印它的np像素值

import numpy as np
import cv2
image = cv2.imread("pig.JPG")
image = image[800:850,229:250]
print(image)

在这里插入图片描述
我们可以看到灰度值从几十变成一两百差别很大,而图片中的内容恰好对应的是腿部的轮廓。说明梯度变化大的时候针对的就是轮廓。一切都是为了论证这句话:一般情况下,图像梯度计算的是图像的边缘信息
再通过我用画图板画的一张图来证明一下(画的简陋多多包涵):

在这里插入图片描述
水平方向同理,请看下图:
在这里插入图片描述

sobel算子

语法 :
dst = cv2.Sobel(原始图像src,ddepth图像深度,dx 计算水平方向的偏导数 ,dy 计算垂直方向的偏导数,ksize算子大小)
因为不同的参数影响很大,所以要一个一个参数的用法讲

ddepth的用法

比如说我在画图板画出下面这个图,命名为so_1.JPG ,设置图像深度为 0 就是与原图像一致,ksize = 3 dx =1 dy =0
在这里插入图片描述

import numpy as np
so_1_img = cv2.imread("so_1.JPG",cv2.IMREAD_GRAYSCALE)
dst = cv2.Sobel(so_1_img,ddepth = 0,dx = 1,dy = 0,ksize = 3)
cv2.imshow('original',so_1_img)
cv2.imshow("sob",dst)
cv2.waitKey()
cv2.destroyAllWindows()

a
你观察图片可以发现,他只找到了一条的边,可是这个方向的边应该有两条。原因是因为白色是255,黑色是0 白右黑左的时候差值为255,而白左黑右的时候-255,被自动忽略了。
要解决这种方式需要提高ddepth,然后对计算结果取绝对值,因为我读入图片的时候选择的是八位灰度值的,所以我在使用sobel算子可以设置为64位,然后再使用cv2.convertScaleAbs()对图片取绝对值然后就可以出现两条边了。请看下面的代码:

import numpy as np
so_1_img = cv2.imread("so_1.JPG",cv2.IMREAD_GRAYSCALE)
dst = cv2.Sobel(so_1_img,ddepth = cv2.CV_64F,dx = 1,dy = 0,ksize = 3)
ddst = cv2.convertScaleAbs(dst)
cv2.imshow('original',so_1_img)
cv2.imshow("sob",dst)
cv2.imshow("abs_sob",ddst)
cv2.waitKey()
cv2.destroyAllWindows()

在这里插入图片描述

dx dy参数设置(请记住这里有两个知识点)

第一个知识点 设置一者为1 另一者为0可以计算单独方向的轮廓,如果想同时计算那么需要二者使用cv2.addweighted函数一者0.5对水平和竖直方向进行加权。
还是拿同一张图展示:

import numpy as np
so_1_img = cv2.imread("so_1.JPG",cv2.IMREAD_GRAYSCALE)
dst = cv2.Sobel(so_1_img,ddepth = cv2.CV_64F,dx = 1,dy = 0,ksize = 3)
ddst = cv2.convertScaleAbs(dst)
y_dst = cv2.Sobel(so_1_img,ddepth = cv2.CV_64F,dx = 0,dy = 1,ksize = 3)
y_ddst = cv2.convertScaleAbs(y_dst)
add = cv2.addWeighted(ddst,0.5,y_ddst,0.5,0)
cv2.imshow('original',so_1_img)
cv2.imshow("abs_x_sob",ddst)
cv2.imshow("abs_y_sob",y_ddst)
cv2.imshow("add",add)
cv2.waitKey()
cv2.destroyAllWindows()

在这里插入图片描述
第二个知识点是,同时设置dx =1 dy =1与第一个知识点的计算结果并不一致,因为
图像中的边缘并不总是简单的水平或垂直方向。在实际的图像中,边缘可能是倾斜的、弯曲的或者有噪声干扰。
当分别计算和方向梯度并加权相加时,可能会丢失一些复杂边缘的细节信息。而dx = 1、dy = 1的计算方式会以一种不同的角度来捕捉这些复杂边缘的变化,包括对角边缘等,所以结果会和简单加权相加的情况不一致。
我们拿猪猪侠这张图来验证一下

import numpy as np
so_1_img = cv2.imread("pig.JPG",cv2.IMREAD_GRAYSCALE)
dst = cv2.Sobel(so_1_img,ddepth = cv2.CV_64F,dx = 1,dy = 0,ksize = 3)
ddst = cv2.convertScaleAbs(dst)
y_dst = cv2.Sobel(so_1_img,ddepth = cv2.CV_64F,dx = 0,dy = 1,ksize = 3)
y_ddst = cv2.convertScaleAbs(y_dst)
add = cv2.addWeighted(ddst,0.5,y_ddst,0.5,0)
x_y_dst = cv2.Sobel(so_1_img,ddepth = cv2.CV_64F,dx = 1,dy =1,ksize = 3)
x_y_ddst = cv2.convertScaleAbs(x_y_dst)
cv2.imshow('original',so_1_img)
cv2.imshow("add",add)
cv2.imshow("dxdy11",x_y_ddst)
cv2.waitKey()
cv2.destroyAllWindows()

在这里插入图片描述

Scharr算子

用法与sobel一样就是函数名不一样 cv2.Scharr(),有两个区别就是

  1. scharr没有ksize这个参数。
  2. scharr不能同时设置dx dy为1

他比sobel算子准确度更高,是一种改良,我们还用pig.JPG来展示:

import numpy as np
so_1_img = cv2.imread("pig.JPG",cv2.IMREAD_GRAYSCALE)x_y_dst = cv2.Sobel(so_1_img,ddepth = cv2.CV_64F,dx = 1,dy =1,ksize = 3)
x_y_ddst = cv2.convertScaleAbs(x_y_dst)x_scharr = cv2.Scharr(so_1_img,ddepth = cv2.CV_64F,dx = 1,dy =0)
x_sscharr = cv2.convertScaleAbs(x_scharr)y_scharr = cv2.Scharr(so_1_img,ddepth = cv2.CV_64F,dx = 0,dy =1)
y_sscharr = cv2.convertScaleAbs(y_scharr)x_y_sscharr = cv2.addWeighted(x_sscharr,0.5,y_sscharr,0.5,0)cv2.imshow('original',so_1_img)
cv2.imshow("dxdy11",x_y_ddst)
cv2.imshow("scharr",x_y_sscharr)
cv2.waitKey()
cv2.destroyAllWindows()

在这里插入图片描述
明显看出来后者抓住了更多轮廓,下过更好

Laplacian算子(三个知识点)

第一个知识点: 相比于sobel算子,Laplacian 算子在检测一些微小的细节变化(如噪点引起的小波动或者很细的线条)方面可能更有优势。
第二个知识点:由于 Laplacian 算子是二阶导数,它对噪声比较敏感。在图像存在噪声时,噪声点周围的像素值变化会被 Laplacian 算子放大,可能导致误检测出许多假边缘。所以在实际应用中,通常会先对图像进行平滑处理(如使用高斯滤波),然后再应用 Laplacian 算子进行边缘检测,以减少噪声的影响。
第三个知识点,他的语法:
dst = cv2.Laplacian(原始图像src,图像深度ddepth,ksize核尺寸大小,scale缩放因子,delta计算结果+delta说白了就是个附加值,borderType就是个边界样式一般不用修改)
还用pig.JPG这个图片做例子:

import numpy as np
import cv2
img = cv2.imread("pig.JPG",cv2.IMREAD_GRAYSCALE)
lap = cv2.Laplacian(img,cv2.CV_64F)
lap = cv2.convertScaleAbs(lap)
cv2.imshow("original",img)
cv2.imshow("laplacian",lap)
cv2.waitKey()
cv2.destroyAllWindows()

在这里插入图片描述

致谢

本文参考了一些博主的文章,博取了他们的长处,也结合了我的一些经验,对他们表达诚挚的感谢,使我对 图像梯度与算子 有更深入的了解,也推荐大家去阅读一下他们的文章。纸上学来终觉浅,明知此事要躬行:
OpenCV图像处理(十一)—图像梯度
一文讲解图像梯度

相关文章:

《图像梯度与常见算子全解析:原理、用法及效果展示》

简介:本文深入探讨图像梯度相关知识,详细介绍图像梯度是像素灰度值在不同方向的变化速度,并以 “pig.JPG” 图像为例,通过代码展示如何选取图像部分区域并分析其像素值以论证图像梯度与边缘信息的关联。接着全面阐述了 Sobel 算子&#xff0c…...

【c++篇】:探索c++中的std::string类--掌握字符串处理的精髓

✨感谢您阅读本篇文章,文章内容是个人学习笔记的整理,如果哪里有误的话还请您指正噢✨ ✨ 个人主页:余辉zmh–CSDN博客 ✨文章所属专栏:c篇–CSDN博客 文章目录 前言一.std::string对象的创建二.std::string对象的访问三.std::str…...

LlamaIndex ollama 搭建本地RAG应用,建立本地知识库

目录 简介安装前的准备下载ollama创建llamaindex conda环境,为后面编码作准备 环境变量迁移ollama到其他盘运行ollama方式一方式二禁止ollama开机自启动运行第一个模型 Chatbox聊天下载Chatbox配置ollama地址和模型验证 建立自身特定知识数据搭配大语言模型创建项目…...

draggable的el-dialog实现对话框标题可以选择

请看图 这个对话框使用了el-dialog并且draggable属性设置成了true,所以标题栏这里就可以拖动,现在用户想选中标题栏的文本进而复制。我看到这个需求头都大了。 我能想到的方案有三个:1. 取消draggable为true 2. 标题文案后面加一个复制按钮 …...

2024年Android面试总结

2024年Android面试总结 1.动画类型有哪些?插值器原理? 2.StringBuffer和StringBuilder区别? 3.jvm内存模型? 4.线程池7大核心参数及原理? 5.Android多进程通信方式有哪些?各自的优缺点? 6…...

树莓派3:64位系统串口(UART)使用问题的解决方法

前言 当我们要使用串口进行zigbee的短距离通信时,发现无法使用串口. 原因 树莓派3bCPU内部有两个串口,一个硬件串口(就是我们平时使用的UART),还有一个迷你串口(mini-uart),在老版本的树莓派中把硬件串口分配在GPIO上,可以单独使用.但是在新的树莓派中官方把硬件串口给了蓝牙…...

SemiDrive E3 硬件设计系列---唤醒电路设计

一、前言 E3 系列芯片是芯驰半导体高功能安全的车规级 MCU,对于 MCU 的硬件设计部分,本系列将会分模块进行讲解,旨在介绍 E3 系列芯片在硬件设计方面的注意事项与经验,本文主要讲解 E3 硬件设计中唤醒电路部分的设计。 二、RTC 模…...

淘宝接口高并发采集核心要点解读,开启电商数据智能应用新纪元

一、引言 在电商蓬勃发展的今天,淘宝作为全球知名的电商巨头,其平台上的数据犹如一座蕴藏无限价值的宝藏。准确且高效地采集淘宝接口数据,并通过高并发技术实现大规模数据获取,对于电商企业的精准营销、市场趋势分析、竞品监测以及…...

C#里怎么样快速使用LINQ实现查询?

C#里怎么样快速使用LINQ实现查询? 在C#里使用LINQ,是一个方便的功能, 不过,要学会使用这部分的功能,需要比较多的学习时间,否则,使用起就比较难。 因为它的表现方式,与编程语言通用的功能,还是差别比较大。 当数据量比较小,没有特定的顺序时,使用LINQ访问会比较好…...

2024新版微软edge浏览器输入百度网址时自动补全tn=68018901……小尾巴的解决

以前一直是Windows11 21h2版本,浏览器内输入baidu不会自动补全tnxx的百度推广小尾巴。然后前几天在BIOS内开启了tpm2.0,升级Windows11到了24h2版本。 发现在edge浏览器内只要输入b,就会自动补全为baidu.com?tnXXX的这么一个百度推广形式。开…...

uni-app打包H5自定义微信分享

1、配置分享信息 修改uni-app的index.html,添加Open Graph(OG)标签来配置分享信息。 <!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8" /><meta name="description" content="标题"/>…...

大模型专栏--大模型应用场景

紧接着第一篇&#xff0c;什么是大模型&#xff0c;这篇文章讨论一下大模型的应用场景和应用方式有哪些&#xff1f; 基础使用 随着 GPT 的出现&#xff0c;AI 大模型已经越来越多得出现在日常生活和学术研究&#xff0c;工作中。 按照使用方向有以下几种&#xff1a; 自然语…...

骑砍2霸主MOD开发(29)-顶点动画

一.定制化顶点动画(MorphAnimation) 定制化顶点动画用于人物Agent的面部表情. 1.创建MorphAnimation对应静态资源morph_animation.tpac 2.Agent设置对应MorphAnimation [EngineMethod("set_agent_facial_animation", false)] void SetAgentFacialAnimation(UIntPtr …...

-Dspring.profiles.active=dev与--spring.profiles.active=dev的区别

在Spring Boot应用程序中&#xff0c;-Dspring.profiles.activedev和--spring.profiles.activedev都用于指定要激活的Spring配置文件&#xff08;profile&#xff09;&#xff0c;但它们在不同的环境中使用&#xff0c;并且有不同的作用域。 -Dspring.profiles.activedev&#…...

面向对象高级(2)单例设计对象与代码块

面向对象高级&#xff08;2&#xff09; 单例设计模式、main方法与代码块 引言&#xff1b; 设计模式&#xff1a;特定环境下特定问题的处理方法。可理解为一种经典的可以参照的模板。单例设计模式则是只存在单个对象实例、且只有一种方法获取对象实例的一种设计模式。 单例设…...

47小型项目的规划与实施

每天五分钟学Linux | 第四十七课&#xff1a;小型项目的规划与实施 大家好&#xff01;欢迎再次来到我们的“每天五分钟学Linux”系列教程。在前面的课程中&#xff0c;我们学习了并发编程的知识&#xff0c;包括如何管理和使用进程与线程。今天&#xff0c;我们将探讨如何规划…...

堤防安全监测系统方案

一、背景情况 堤防是开发利用水资源和防治水灾害的重要工程措施之一&#xff0c;对防洪、供水、生态、发电、航运等至关重要。我国现有堤防9.8万多座&#xff0c;其中大中型堤防4700多座、小型堤防9.4万座&#xff0c;80%以上修建于上世纪50至70年代。由于堤防管护力量薄弱&am…...

聊聊Flink:这次把Flink的window分类(滚动、滑动、会话、全局)、窗口函数讲透

一、窗口 窗口&#xff08;Window&#xff09;是处理无界流的关键所在。窗口将流分成有限大小的“桶”&#xff0c;我们可以在其上应用算子计算。Flink可以使用window()和windowAll()定义一个窗口&#xff0c;二者都需要传入一个窗口分配器WindowAssigner&#xff0c;WindowAs…...

mysql-分析MVCC原理

一、MVCC简介 MVCC是一种用来解决读写冲读的无锁并发控制&#xff0c;也就是为事务分配单增长的时间戳&#xff0c;为每个修改保存一个版本&#xff0c;版本与事务时间戳关联&#xff0c;读操作只读该事务开始前的数据库的快照&#xff0c;所以MVCC可以为数据库解决一些问题。…...

由于答案过大,请对a取模。取模后的答案不是原问题的答案 取模有何意义呢 详解

在许多情况下&#xff0c;处理大数时会将 a 取模&#xff0c;即用 a m o d m a \mod m amodm的结果代替 a a a&#xff0c;然后继续计算。这种做法的核心问题是&#xff1a;取模后的值与原问题之间的关系是否保持一致。取模后的意义在于&#xff0c;它在不改变问题核心特性的前…...

【c++篇】掌握动态内存的奥妙

【C篇】动态内存 一、Static 关键字1.1函数内部的静态变量1.2 全局静态变量1.3静态成员变量1.4静态成员函数 二、内存管理2.1栈区(Stack)2.2堆区&#xff08;Heap&#xff09; 三、动态内存分配机制3.1、动态内存分配的两种方法c语言c 3.2new 和delete的用法3.3语法和类型安全性…...

5.4.2-3 编写Java程序读取HDFS文件

在本次实战中&#xff0c;我们通过Java程序实现了从Hadoop分布式文件系统&#xff08;HDFS&#xff09;读取文件的功能。首先&#xff0c;我们创建了ReadFileOnHDFS类&#xff0c;并在其中实现了两个方法&#xff1a;read1()和read1_()。read1()方法展示了如何打开HDFS文件并逐…...

@EnableConfigurationProperties @ConfigurationProperties

EnableConfigurationProperties && ConfigurationProperties的使用时机 今天在写properties时想到了这个问题&#xff0c;为什么有时候我需要写EnableConfigurationProperties有时候又不需要呢&#xff1f;下面就详细讲讲。 Data Component ConfigurationProperties(pr…...

RK3588适配MTK7921 USB接口WiFi驱动开发

在当前RK原厂提供的SDK里面已经适配的WiFi模组有不少,但是支持的模组大部分集中在realtek、正基、英飞凌等厂家。主要型号有Realtek的RTL8188系列、RTL8723系列、RTL8812系列、RTL8821系列、RTL8822系列和支持WiFi 6 的RTL8852系列,正基的AP6275系列、AP6276系列等。接下来将…...

【数据结构OJ】【图论】图综合练习--拓扑排序

题目描述 已知有向图&#xff0c;顶点从0开始编号&#xff0c;求它的求拓扑有序序列。 拓扑排序算法&#xff1a;给出有向图邻接矩阵 1.逐列扫描矩阵&#xff0c;找出入度为0且编号最小的顶点v 2.输出v&#xff0c;并标识v已访问 3.把矩阵第v行全清0 重复上述步骤&#xff0…...

模型 I/O 与 LangChain 实践

模型 I/O 与 LangChain 实践 本文是《LangChain 实战课》第 4 节——模型 I/O&#xff1a;输入提示、调用模型、解析输出的一些学习笔记与总结。这篇文章将围绕模型 I/O 的基本概念、LangChain 提供的最佳实践以及如何通过 LangChain 实现高效的结构化数据处理展开。 什么是模…...

C++:用红黑树封装map与set-1

文章目录 前言一、STL源码分析二、红黑树的构建三、map与set整体框架的搭建与解析四、如何取出进行比较&#xff1f;1. met与set的数据是不同的2. 取出数据进行比较1&#xff09;问题发现2&#xff09;仿函数解决 五、封装插入六、迭代器的实现1. operator* 与operator->2. …...

HBU算法设计与分析 贪心算法

1.最优会场调度 #include <bits/stdc.h> using namespace std; const int N1e55; typedef pair<int,int> PII; PII p[N]; priority_queue<int,vector<int>,greater<int>> q; //最小堆 存储最早结束的会场的结束时间 int n; //其实这个题可以理…...

python pycharm安装教程及基本使用,超详细

一.PyCharm下载及安装 1.1 进入pycharm官网&#xff0c;点击下载,下载社区版本&#xff08;日常学习使用够用了&#xff09;&#xff0c;专业版是收费的哦&#xff08;功能更强大&#xff09; Download PyCharm: The Python IDE for data science and web development by Jet…...

变量提升函数提升

示例 1&#xff1a;变量提升 原始代码&#xff1a; console.log(x); // 输出: undefined var x 5; console.log(x); // 输出: 5提升后的代码&#xff08;理解为&#xff09;&#xff1a; var x; // 变量声明被提升 console.log(x); // 输出: undefined x 5; // 赋值 conso…...