OpenCV基础之常见的图像梯度算子

news2024/10/6 1:40:09

文章目录

  • OpenCV基础之常见的图像梯度
    • Roberts交叉算子
    • Prewitt算子
    • Sobel算子
    • Laplacian算子

OpenCV基础之常见的图像梯度

梯度是一个向量,梯度方向指向函数变化最快的方向,大小就是它的模,也是最大的变化率。
图像梯度是指在图像中某个位置处沿着某个方向的变化率,通常用于图像边缘检测和特征提取。
dst = cv2.addWeighted(src1, alpha, src2, beta, gamma, dtype=None)一个图像加权函数,可以将两个图像按照一定的权重进行加权叠加。

  • src1:表示第一个输入的图像;
  • alpha:表示第一个输入图像的权重系数;
  • src2:表示第二个输入的图像;
  • beta:表示第二个输入图像的权重系数;
  • gamma:表示一个加权值,一般为0;
  • dtype:表示输出图像的数据类型,一般为np.uint8或np.float32。

dst = cv2.normalize(src, dst=None, alpha=None, beta=None, norm_type=None, dtype=None, mask=None)一个图像归一化函数,可以将图像的像素值缩放到指定范围内。

  • src:表示输入的图像;
  • dst:表示输出的图像,如果为None,则输出的图像大小和类型与输入图像相同;
  • alpha:表示归一化的下界,一般为0;
  • beta:表示归一化的上界,一般为255;
  • norm_type:表示归一化的类型,一般为cv2.NORM_MINMAX;
  • dtype:表示输出图像的数据类型,一般为np.uint8或np.float32;
  • mask:表示掩膜图像,用于指定哪些像素需要进行归一化。

以下是典型的3*3模板,其模板中心对应要求梯度的原图像坐标(x,y),(x,y)对应的8邻域的像素灰度值如下表所示:

f(x-1,y+1)f(x,y+1)f(x+1,y+1)
f(x-1,y)f(x,y)f(x+1,y)
f(x-1,y-1)f(x,y-1)f(x+1,y-1)

Roberts交叉算子

Roberts交叉算子其本质是一个对角线方向的梯度算子,不是上面所示的33模板,而是33模板的右上角四个像素点,对应的水平方向和竖直方向的梯度分别为:

  • x轴梯度模板:[[0,1],[-1,0]]------>G(x) = f(x+1,y+1) - f(x,y)

  • y轴梯度模板:[[1,0],[0,-1]]------>G(y) = f(x,y+1) - f(x+1,y)

优点:边缘定位较准,适用于边缘明显且噪声较少的图像。

缺点:①没有描述水平和垂直方向的灰度变化,只关注了对角线方向,容易造成遗漏。②鲁棒性差,由于点本身参与了梯度计算,不能有效抑制噪声的干扰。

# 读取图像
img = cv2.imread('img/lena.jpg')
# 转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 定义Prewitt算子的卷积核
roberts_x = np.array([[0, 1], [-1, 0]], dtype=np.float32)
roberts_y = np.array([[1, 0], [ 0, 1]], dtype=np.float32)
# 函数cv2.filter2D()来实现卷积操作,可以使用该函数来实现Roberts交叉算子
roberts_img_x = cv2.filter2D(gray, -1, roberts_x)
roberts_img_y = cv2.filter2D(gray, -1, roberts_y)
# 将图像的像素值缩放到指定范围内
roberts_img = cv2.addWeighted(roberts_img_x, 0.5, roberts_img_y, 0.5, 0)
# 显示Roberts交叉算子的梯度图
cv2.imshow('Roberts Gradient', roberts_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

Prewitt算子

对应的水平方向和竖直方向的梯度分别为:

  • x轴梯度模板:[[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]]------>G(x) = f(x+1,y+1) - f(x-1,y+1)+f(x+1,y)-f(x-1,y)+f(x+1,y-1)-f(x-1,y-1)

  • y轴梯度模板:[[ 1, 1, 1], [ 0, 0, 0], [-1, -1, -1]]------>G(y) = f(x-1,y+1) - f(x-1,y-1)+f(x,y+1)-f(x,y+1)+f(x+1,y+1)-f(x+1,y-1)
    Prewitt算子引入了类似局部平均的运算,对噪声具有平滑作用,较Roberts算子更能抑制噪声。

# 读取图像
img = cv2.imread('img/lena.jpg')
# 转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 定义Prewitt算子的卷积核
prewitt_x = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]], dtype=np.float32)
prewitt_y = np.array([[ 1, 1, 1], [ 0, 0, 0], [-1, -1, -1]], dtype=np.float32)
# 函数cv2.filter2D()来实现卷积操作,可以使用该函数来实现Prewitt算子
prewitt_img_x = cv2.filter2D(gray, -1, prewitt_x)
prewitt_img_y = cv2.filter2D(gray, -1, prewitt_y)
prewitt_img = cv2.addWeighted(prewitt_img_x, 0.5, prewitt_img_y, 0.5, 0)
# 显示Prewitt算子的梯度图
cv2.imshow('Prewitt Gradient', prewitt_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

Sobel算子

1.定义两个3*3的卷积核,分别表示水平和垂直方向上的梯度变化

2.将卷积核通过中心点与图像中的像素点进行卷积运算,得到图像中各个像素点在水平和垂直方向上的梯度值:

  • x轴梯度模板:[[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]]------>G(x) = f(x+1,y+1) - f(x-1,y+1) + 2*f(x+1,y) - 2* f(x-1,y)+f(x+1,y-1)-f(x-1,y-1)

  • y轴梯度模板:[[1, 2, 1], [0, 0, 0], [-1, -2, -1]]------>G(y) = f(x-1,y+1) - f(x-1,y-1) + 2*f(x,y+1) - 2*f(x,y-1)+f(x+1,y+1)-f(x+1,y-1)

dst = cv2.Sobel(src, ddepth, dx, dy, ksize=None, scale=None, delta=None, borderType=None)

  • src:表示输入的图像;

  • ddepth:表示输出图像的深度,通常为-1,表示与输入图像的深度相同;

  • dx:表示在x方向上求导的阶数,一般为0、1或2;

  • dy:表示在y方向上求导的阶数,一般为0、1或2;

  • ksize:表示Sobel算子的大小,一般为3、5、7等;

  • scale:表示缩放因子,一般为1;

  • delta:表示偏移量,一般为0;

  • borderType:表示边界处理方式,一般为cv2.BORDER_DEFAULT。

3.梯度大小(也称为梯度幅值)可以使用以下公式计算: |G| = sqrt(Gx^2 + Gy^2)

注:Sobel算子其实就是增加了权重系数的Prewitt算子,且Sobel算子引入了类似局部加权平均的运算,对边缘的定位比Prewitt算子好。

# 读入图像
img = cv2.imread('img/lena.jpg', cv2.IMREAD_GRAYSCALE)
# 使用Sobel算子在x方向上求导
sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3)
# 使用Sobel算子在y方向上求导
sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3)
# 计算每个像素的梯度大小
sobel = np.sqrt(sobelx ** 2 + sobely ** 2)
# 将梯度大小映射到0-255之间,并转换为8位无符号整型
sobel = cv2.normalize(sobel, None, 0, 255, cv2.NORM_MINMAX)
sobel = np.uint8(sobel)
# 显示结果
cv2.imshow('Sobel', sobel)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

Laplacian算子

laplacian 是利用二阶导数来检测边缘

卷积核为[[0,1,0],[1,-4,1],[0,1,0]]

dst = cv2.Laplacian(src, ddepth, ksize=None, scale=None, delta=None, borderType=None)

  • src1:表示输入的图像;
  • ddepth:表示输出图像的深度,通常为-1,表示与输入图像的深度相同;
  • ksize:表示Laplacian算子的大小,一般为3、5、7等;
  • scale:表示缩放因子,一般为1;
  • delta:表示偏移量,一般为0;
  • borderType:表示边界处理方式,一般为cv2.BORDER_DEFAULT。
# 读入图像
img = cv2.imread('img/lena.jpg', cv2.IMREAD_GRAYSCALE)
# 使用Laplacian算子计算图像的拉普拉斯值
laplacian = cv2.Laplacian(img, cv2.CV_64F, ksize=3)
# 将梯度大小映射到0-255之间,并转换为8位无符号整型
laplacian = cv2.normalize(laplacian, None, 0, 255, cv2.NORM_MINMAX)
laplacian = np.uint8(laplacian)
# 显示结果
cv2.imshow('Laplacian', laplacian)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述
还有之前发布的OpenCV基础之边缘检测与轮廓描绘中的Canny边缘检测方法。当然,我们也可以自定义x,y轴梯度模板,进行卷积后展示。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关于容器(Docker)的形象比喻

1 将容器比喻为样板间 容器是一种特殊的进程 容器依赖与Linux操作系统内核的几项技术:namespace、cgroup、chroot namespace 与编程语言里的 namespace 有点类似,它可以创建出独立的文件系统、主机名、进程号、网络等资源空间,相当于给进程…

回归问题(Regression)

Regression 前言Dependent vs. Explanatory VariablesHandle Numerical Labelssquared error和variance什么区别 Linear RegressionLinear Regression in 1 Dimension Least Squares (最小二乘,重点)Least Squares ObjectiveMinimizing a Dif…

确保软件项目成功——验收测试指南

确保软件项目成功——验收测试指南 在软件项目验收测试中,软件测试报告是非常重要的一部分,需要准备和提交。以山东省在2021印发的《政府采购履约验收管理办法》为例: 省级各国家机关、事业单位和团体组织(以下统称“采购人”&…

会话跟踪——JWT令牌

会话指的是浏览器与服务器之间的一次连接,我们称之为一次会话。 在用户打开浏览器第一个访问服务器的时候,这个会话就建立了,只要有任何一方断开连接,此时会话就结束了。再一次会话中是可以包含多次请求和相应。那什么是会话跟踪呢…

动力节点springsecurity笔记14~18SpringSecurity 集成thymeleaf

15 SpringSecurity 集成thymeleaf 此项目是在springsecurity-12-database-authorization-method 的基础上进行 复制springsecurity-12-database-authorization-method 并重命名为springsecurity-13-thymeleaf 15.1 添加thymeleaf依赖 | <groupId>org.springframewor…

vue3+vite3+typescript使用wangEditor编辑器

文章目录 ⭐写在前面⭐步入正题&#x1f680;1.安装&#x1f680;2.配置2.1 存数据2.2 读数据 &#x1f680;3.跨域及其他问题3.1 跨域3.2 其他问题 &#x1f680;4.写在最后 ⭐写在前面 &#x1f680; 框架Vue3 Vite3 TypeScript&#xff1a; &#x1f449; Vue3&#xff…

地铁站人流检测硬件部分

目录 一、概述 二、驱动程序 2.1debug串口 2.2体重传感器HX711 2.3滴答定时器 2.4ESP8266 2.5人体检测 2.6 IIC的GPIO 2.7 OLED的IIC 2.8 LED 三、应用 四、中断 一、概述 使用STM32C8T6作为主控 A9 ---> tx&#xff08;调试串口&#xff09; A10 ---> …

算法训练 Day41 | 动态规划

343. 整数拆分 思路&#xff1a; 确定dp数组&#xff08;dp table&#xff09;以及下标的含义&#xff1a;dp[i]&#xff1a;分拆数字i&#xff0c;可以得到的最大乘积为dp[i]。 确定递推公式&#xff1a;dp[i] max(dp[i], max((i - j) * j, dp[i - j] * j)) 可以想 dp[i]最…

【python装饰器:看懂这10个例子你就掌握了!】

基本说明 Python 装饰器是一种函数&#xff0c;它可以用来修改其他函数的功能。它是 Python 中的一项高级编程技术&#xff0c;也是 Python 中比较重要的语法之一。 简单来说&#xff0c;装饰器就是一个函数&#xff0c;它可以接受一个函数作为参数&#xff0c;并返回一个函数…

Obsidian+坚果云+FolderSync解决电脑端和安卓端同步方案

目录1.Obsidian电脑端准备 2.Obsidian安卓端准备 3.坚果云电脑端准备 4.坚果云手机端准备 5.FolderSync手机端准备 6.百度云冗余备份 1.Obsidian电脑端准备 这里以windows版本为例&#xff0c;下载后安装 1.Obsidian官网&#xff1a;https://obsidian.md/ 官网下载有时候…

电力电网行业IT运维方案

智能电网背景下&#xff0c;电力、电网企业信息化逐渐渗透到其业务链的各个环节&#xff0c;云计算、物联网、移动互联网等新技术的应用&#xff0c;更驱动信息化与业务创新深度融合。电力、电网企业集团信息系统群逐渐朝着一体化方向发展&#xff0c;信息链越来越长&#xff0…

银行数字化转型导师坚鹏:宏观经济趋势与资本行业机遇和挑战

2023年宏观经济趋势与资本行业机遇和挑战 课程背景&#xff1a; 很多学员存在以下问题&#xff1a; 不知道我国目前的宏观经济形势&#xff1f; 不清楚宏观环境对我国经济的影响&#xff1f; 不知道资本行业未来主要发展趋势&#xff1f; 课程特色&#xff1a; 精彩解…

基于php的校园校园兼职网站的设计与实现

摘要 近年来&#xff0c;信息技术在大学校园中得到了广泛的应用&#xff0c;主要体现在两个方面&#xff1a;一是学校管理系统&#xff0c;包括教务管理、行政管理和分校管理&#xff0c;是我国大学管理和信息传递的主要渠道。二是学生生活服务平台。而随着大学生毕业人数的年…

leetcode重点题目分类别记录(四)图论深入

文章目录 入度出度最大网络秩可以到达所有点的最少点数目 并查集省份数量等式方程的可满足性按字典序排列最小的等效字符串以图判树 二分图判断二分图 深度优先搜索封闭岛屿数量太平洋大西洋水流问题 广度优先搜索树上逃逸最短路径多源最短路径 拓扑排序DFS解决拓扑排序BFS解决…

MIPS指令集-mars-cpu

MIPS通用寄存器 MIPS有32个通用寄存器&#xff08;$0-$31&#xff09;&#xff0c;各寄存器的功能及汇编程序中使用约定如下&#xff1a; 下表描述32个通用寄存器的别名和用途 REGISTER NAME USAGE $0 $zero 常量0(constant value 0) $1 $at 保留给汇编器(Reserved f…

K近邻算法(手写代码+图像识别实践)

k近邻算法作为一个分类算法&#xff0c;他通过计算不同特征值之间的距离来进行分类&#xff0c;它的工作原理是存在一个样本集合作为训练样本集&#xff0c;且每个样本都存在一个标签&#xff0c;此时&#xff0c;输入一个新的样本不存在标签&#xff0c;我们通过计算这个新样本…

【Android车载系列】第10章 系统服务-SystemServer源码分析(API28)

1 SystemServer启动 &emps;&emps;SystemServer进程启动&#xff0c;首先从SystemServer.java文件的main()方法开始。 290 /** 291 * The main entry point from zygote. 292 */ 293 public static void main(String[] args) { 294 new SystemSe…

S32K3系列单片机开发笔记(SIUL是什么/配置引脚复用的功能·)

前言 今天花时间看了一下&#xff0c;SIUL2模块的相关内容&#xff0c;并参照文档&#xff0c;以及例程作了一些小记录&#xff0c;知道该如何使用这个外设&#xff0c;包括引脚的配置&#xff0c;中断配置&#xff0c;以及常用函数的使用等&#xff0c;但对其中的一些细节还需…

如何利用代码快速生成mapper.xml的<resultMap>

一&#xff0c;问题引入 当我们开发 mapper.xml ---->dao接层 ---->service接口---->serviceImp ---->controller层&#xff0c; 其中在mapper.xml编写查询语句的sql时会遇到sql查询到的结果 涉及到多张表的字段&#xff0c;或者单张表的字段过多时&#xff0c; 这…

Python文件处理

文章目录 1️⃣基本语法2️⃣读取文件⚜️读取整个文件read()⚜️with 关键词⚜️逐行读取 3️⃣写入文件⚜️写入文件write()⚜️写入数字⚜️追加内容到文件 4️⃣读取和写入二进制文件 简介 读完本篇你将学会文件的创建、读取、写入等。 1️⃣基本语法 在Python中使用文件的…