OpenCV中的图像处理3.7-3.8(五)边缘检测、图像金字塔

目录

  • 3.7 边缘检测
      • 目标
      • 理论
      • OpenCV中的Canny边缘检测
      • 其他资源
      • 练习
  • 3.8 图像金字塔
      • 目标
      • 理论
      • 使用金字塔进行图像混合
      • 其他资源

翻译及二次校对:cvtutorials.com

编辑者:廿瓶鲸(和鲸社区Siby团队成员)

3.7 边缘检测

目标

在本章中,我们将了解到:

  • Canny边缘检测的概念
  • 用于检测的OpenCV函数:cv.Canny()

理论

Canny边缘检测是一种流行的边缘检测算法。它是由John F. Canny在2006年开发的。

1.它是一个多阶段的算法,我们将对每个阶段进行分析。

2.减少噪音

由于边缘检测容易受到图像中噪音的影响,第一步是用5x5高斯滤波器去除图像中的噪音。我们已经在前几章中看到了这一点。

3.寻找图像的灰度梯度

然后用Sobel核对水平和垂直方向的平滑图像进行过滤,得到水平方向(Gx)和垂直方向(Gy)的第一导数。从这两幅图像中,我们可以找到每个像素的边缘梯度和方向,如下所示。
E d g e _ G r a d i e n t    ( G ) = G x 2 + G y 2 A n g l e    ( θ ) = tan ⁡ − 1 ( G y G x ) Edge\_Gradient \; (G) = \sqrt{G_x^2 + G_y^2} \\ Angle \; (\theta) = \tan^{-1} \bigg(\frac{G_y}{G_x}\bigg) Edge_Gradient(G)=Gx2+Gy2 Angle(θ)=tan1(GxGy)

E d g e _ G r a d i e n t    ( G ) = G x 2 + G y 2 A n g l e    ( θ ) = tan ⁡ − 1 ( G y G x ) Edge\_Gradient \; (G) = \sqrt{G_x^2 + G_y^2} \\ Angle \; (\theta) = \tan^{-1} \bigg(\frac{G_y}{G_x}\bigg) Edge_Gradient(G)=Gx2+Gy2 Angle(θ)=tan1(GxGy)

梯度方向总是垂直于边缘。它被圆整为四个角度之一,代表垂直、水平和两个对角线方向。

4.非极大值抑制

在得到梯度大小和方向后,对图像进行全面扫描,以去除任何可能不构成边缘的不必要的像素。为此,在每一个像素点上,检查该像素点是否是梯度方向上其附近的局部最大值。请看下面的图片。

Image Name

A点在边缘上(垂直方向)。梯度方向是对边缘的法线。B点和C点在梯度方向上。因此,A点与B点和C点一起被检查,看它是否形成一个局部最大值。如果是,它将被考虑到下一阶段,否则,它将被抑制(归为零)。

简而言之,你得到的结果是一个具有 "薄边缘 "的二进制图像。

5.滞后阈值处理

这个阶段决定哪些是真正的边缘,哪些不是。为此,我们需要两个阈值,minVal和maxVal。任何灰度梯度大于maxVal的边缘都肯定是边缘,而那些低于minVal的边缘肯定是非边缘,所以被丢弃。那些位于这两个阈值之间的边,根据它们的连接性被分为边和非边。如果它们与 "确定的边缘 "像素相连,它们就被认为是边缘的一部分。否则,它们也会被丢弃。请看下面的图片。

Image Name

边缘A高于maxVal,所以被认为是 “确定边缘”。虽然边C低于maxVal,但它与边A相连,所以也被认为是有效的边,我们得到了那个完整的曲线。但是边B,尽管它高于minVal,并且与边C在同一区域,但它没有与任何 "确定的边 "相连,所以它被丢弃了。因此,我们必须相应地选择minVal和maxVal以获得正确的结果,这一点非常重要。

这个阶段还在假设边缘是长线的基础上去除小像素的噪音。

所以我们最终得到的是图像中的强边缘。

OpenCV中的Canny边缘检测

OpenCV把上述所有的东西都放在一个函数中,即cv.Canny()。我们将看到如何使用它。第一个参数是我们的输入图像。第二个和第三个参数分别是我们的minVal和maxVal。第三个参数是aperture_size。它是用于寻找图像梯度的Sobel核的大小。最后一个参数是L2gradient,它指定了用于寻找梯度大小的方程式。如果它是True,它使用上面提到的更精确的方程,否则它使用这个函数。Edge_Gradient(G)=|Gx|+|Gy|。默认情况下,它是False。

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('messi5.jpg',0)
edges = cv.Canny(img,100,200)
plt.subplot(121),plt.imshow(img,cmap = 'gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(edges,cmap = 'gray')
plt.title('Edge Image'), plt.xticks([]), plt.yticks([])
plt.show()

结果如下:

Image Name

其他资源

1.维基百科上的Canny边缘检测器
2.《Canny边缘检测教程》,作者Bill Green,2002年。

练习

写一个小程序来寻找Canny边缘检测,其阈值可以用两个trackbar来改变。这样,你就可以了解阈值的影响。

3.8 图像金字塔

目标

在本章中:

  • 我们将学习图像金字塔的知识
  • 我们将使用图像金字塔来创建一个新的水果,“Orapple”。
  • 我们将看到这些函数:cv.pyrUp(), cv.pyrDown()

理论

通常情况下,我们习惯于使用一个恒定大小的图像。但在某些情况下,我们需要处理不同分辨率的(相同)图像。例如,当我们在图像中搜索某个东西时,比如人脸,我们不确定该物体会以何种尺寸出现在所述图像中。在这种情况下,我们需要创建一组具有不同分辨率的相同图像,并在所有这些图像中搜索物体。这些具有不同分辨率的图像集被称为图像金字塔(因为当它们被保存在一个堆栈中,最高分辨率的图像在底部,最低分辨率的图像在顶部,它看起来像一个金字塔)。

有两种图像金字塔。1)高斯金字塔和2)拉普拉斯金字塔

高斯金字塔中的高层次(低分辨率)是通过去除低层次(高分辨率)图像中的连续行和列而形成的。然后,高层的每个像素由底层的5个像素贡献高斯权重形成。通过这样做,M×N的图像变成了M/2×N/2的图像。因此,面积减少到原始面积的四分之一。这就是所谓的Octave。当我们在金字塔中往上走时,同样的模式会继续下去(即,分辨率下降)。同样地,在扩展时,每一级的面积都会变成4倍。我们可以使用cv.pyrDown()和cv.pyrUp()函数找到高斯金字塔。

img = cv.imread('messi5.jpg')
lower_reso = cv.pyrDown(higher_reso)

下面是图像金字塔中的4个层次。

Image Name

现在你可以用cv.pyrUp()函数往下看图像金字塔。

higher_reso2 = cv.pyrUp(lower_reso)

记住,higher_reso2不等于higher_reso,因为一旦你降低分辨率,你就失去了信息。下面的图片是在前面的情况下从最小的图片创建的金字塔的3级。将其与原始图像进行比较。

Image Name

拉普拉斯金字塔是由高斯金字塔形成的。这方面没有专属函数。拉普拉斯金字塔图像只像边缘图像。它的大部分元素都是零。它们被用于图像压缩。拉普拉斯金字塔中的一个层次是由高斯金字塔中该层次与高斯金字塔中其上层的扩展版本之间的差异形成的。一个拉普拉斯金字塔的三个层次看起来如下(对比度被调整以增强内容)。

Image Name

使用金字塔进行图像混合

金字塔的一个应用是图像混合。例如,在图像拼接中,你需要将两幅图像堆叠在一起,但由于图像之间的不连续性,可能看起来不好看。在这种情况下,用Pyramids进行图像混合,可以让你实现无缝混合,而不会在图像中留下很多数据。一个经典的例子是两个水果的混合,橙子和苹果的混合。请看现在的结果本身,以理解我所说的内容。

Image Name

请查看附加资源中的第一个参考资料,它有关于图像混合、拉普拉斯金字塔等的完整图示细节。简单地说,它是这样做的:

1.加载苹果和橙子的两张图片
2.找到苹果和橙子的高斯金字塔(在这个特定的例子中,级别数为6)。
3.从高斯金字塔中,找到它们的拉普拉斯金字塔
4.现在将苹果的左半边和橙子的右半边分别加入到拉普拉斯金字塔的各个层次中。
5.最后从这个联合图像金字塔中,重建原始图像。

下面是完整的代码。(为了简单起见,每个步骤都是单独完成的,这可能会占用更多的内存。如果你愿意的话,你可以优化它)

import cv2 as cv
import numpy as np,sys
A = cv.imread('apple.jpg')
B = cv.imread('orange.jpg')
# 为A生成高斯金字塔
G = A.copy()
gpA = [G]
for i in range(6):
    G = cv.pyrDown(G)
    gpA.append(G)
# 为B生成高斯金字塔
G = B.copy()
gpB = [G]
for i in range(6):
    G = cv.pyrDown(G)
    gpB.append(G)
# 为A生成拉普拉斯金字塔
lpA = [gpA[5]]for i in range(5,0,-1):
    GE = cv.pyrUp(gpA[i])
    L = cv.subtract(gpA[i-1],GE)
    lpA.append(L)
# 为B生成拉普拉斯金字塔
lpB = [gpB[5]]
for i in range(5,0,-1):
    GE = cv.pyrUp(gpB[i])
    L = cv.subtract(gpB[i-1],GE)
    lpB.append(L)
# 现在在每个层次中添加左右两半的图像
LS = []
for la,lb in zip(lpA,lpB):
    rows,cols,dpt = la.shape
    ls = np.hstack((la[:,0:cols/2], lb[:,cols/2:])
    LS.append(ls)
# 现在重构
ls_ = LS[0]
for i in range(1,6):
    ls_ = cv.pyrUp(ls_)
    ls_ = cv.add(ls_, LS[i])
# 将图像的两半拼接在一起
real = np.hstack((A[:,:cols/2],B[:, cols/2:])
cv.imwrite('Pyramid_blending2.jpg',ls_)
cv.imwrite('Direct_blending.jpg',real)

其他资源

  • 图像混合

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

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

相关文章

ChatGPT在智能外呼机器人领域的应用

随着人工智能技术的不断发展,自然语言处理(NLP)技术也逐渐成为各行各业的热门技术。其中,ChatGPT技术是近年来备受关注的技术之一。ChatGPT技术是一种基于自然语言处理和深度学习的人工智能技术,它可以处理自然语言文本,实现自动化…

智能排班系统 【管理系统功能、操作说明——上篇】

文章目录 功能设计共有功能系统管理员企业管理员门店管理员门店员工 页面与功能展示用户登录企业注册系统首页系统管理员首页企业管理员首页门店管理员首页 个人中心菜单管理日志管理操作日志登录日志 功能设计 不同的角色关注的任务和功能不同,针对不同的角色&…

Docker安装OpenWrt

我笔记本MacOs安装Docker OpenWrt 失败了,网络一直容器内外无法访问. 今天使用虚拟机安装一下,虚拟机使用Parallels,系统使用kali 一、安装docker sudo apt install docker.io 二、把网卡混杂模式打开 根据您当前的ip查看网卡!!! 在您的liu…

【Python json】零基础也能轻松掌握的学习路线与参考资料

Python中的JSON模块主要用于将Python对象序列化成JSON数据或解析包含JSON数据的字符串。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。由于JSON在Web应用中的广泛使用…

pdf怎么压缩得小一点?软件压缩更高效

PDF可以在不同操作系统和设备上实现高保真的排版和格式化。然而,随着文档的不断增多和文件大小的增加,传输和存储PDF文件也变得越来越困难。为了解决这个问题,可以使用PDF压缩技术来减小文件大小,提高传输效率。本文将介绍PDF压缩…

自动驾驶汽车的安全技术特点

“安全第一”是自动驾驶的核心理念和价值观。 自动驾驶车辆的整体系统安全设计是一项复杂的系统工程, 涉及车载自动驾驶系统的核心算法策略设计、 硬件和软件冗余安全设计、远程云代驾技术、 全流程测试验证技术等, 并遵循功能安全(ISO 2626…

git代码回滚是使用reset还是revert

时光不能回退,Git却允许我们改变历史。 想要让Git回退历史,有以下步骤: 使用git log命令,查看分支提交历史,确认需要回退的版本 使用git reset --hard commit_id命令,进行版本回退 使用git push origin命…

华为OD机试之完美走位(Java源码)

完美走位 题目描述 在第一人称射击游戏中,玩家通过键盘的A、S、D、W四个按键控制游戏人物分别向左、向后、向右、向前进行移动,从而完成走位。 假设玩家每按动一次键盘,游戏任务会向某个方向移动一步,如果玩家在操作一定次数的键…

2023年上半年系统集成项目管理工程师上午真题及答案解析

1.在( )领域我国远末达到世界先进水平,需要发挥新型国家体制优势,集中政府和市场两方面的力量全力发展。 A.卫星导航 B.航天 C.集成电路 D.高铁 2.ChatGPT 于2022年11月30日发布,他是人工智能驱动( )。 …

计算机组成原理-中央处理器-控制器功能和原理

目录 一、硬布线控制器 二、硬布线控制器的设计(硬件) 2.1分析每个阶段的微操作序列(取址、间址、执行、中断) 2.2选择cpu的控制方式 2.3 安排微操作时序 2.4电路设计 2.4.1列出操作时间表 2.4.2 写出微操作命令的最简表达式 2.4.3画出电路图 *三、微程序控制器基本原理 四…

日撸 Java 三百行day56-57

文章目录 day56-57 kMeans 聚类1.kMeans聚类理解2.代码理解2.1代码中变量的理解2.2代码理解 day56-57 kMeans 聚类 1.kMeans聚类理解 无监督的机器学习算法,其中k是划分为几个簇,并且选择k个数据作为不同簇的聚类中心,计算每个数据样本和聚…

【大学物理实验】绪论

《大学物理实验》实验报告册的封面,以下说法不正确的是: A. 应正确填写完整的学号 B. 预习前应写好姓名等相关信息 C. 报告册左上角应填写本班级报告箱编号 D. 除了姓名,其他信息可写可不写 正确答案: D 某同学完成某个实验&…

CSS入门学习笔记+案例【一】

目录 一、CSS 是什么 二、引入方式 2.2 行内样式表 2.3 外部样式 三、 代码风格 3.1 样式格式 3.2 样式大小写 3.3 空格规范 四、 选择器 4.1 选择器的功能 4.2 选择器的种类 复合选择器小结 看完这篇博客 你将 掌握 CSS 基本语法规范和代码书写风格 掌握 CSS 选择…

美团面试:接口被恶意狂刷,怎么办?

如果Java接口被恶意狂刷,我们一般可以采取以下措施: 用TimeStamp (兵不厌诈) 比如给客户端提供一个timestamp参数,值是13位的毫秒级时间戳,可以在第12位或者13位做一个校验位,通过一定的算法给…

中国人民大学与加拿大女王大学金融硕士——每天都要优于过去的自己,加油!

职场中拉开人与人之间差距的,往往是日复一日微小的积累。满足已取得的成就会让人停滞不前,一旦停止学习,人就会止步不前。懂得持续学习、终生成长的人,能保持积极进取的状态。金融行业的你有计划来人民大学与加拿大女王大学金融硕…

Redis之高可用方案浅析

在工程项目中,系统应用的高可用性越来越重要,业主越来越重视。其实高可用可以分为应用层高可用和数据层高可用,数据层高可用中常见的有关系型数据库mysql的高可用、非关系型NoSQl数据库redis的高可用等,下面聊聊典型的NoSQL数据库…

深入理解Linux虚拟内存管理

系列文章目录 Linux 内核设计与实现 深入理解 Linux 内核(一) 深入理解 Linux 内核(二) Linux 设备驱动程序(一) Linux 设备驱动程序(二) Linux 设备驱动程序(三&#xf…

yolov5-7.0 添加BiFPN

1. BiFPN特征融合 BiFPN是目标检测中神经网络架构设计的选择之一,为了优化目标检测性能而提出。主要用来进行多尺度特征融合,对神经网络性能进行优化。来自EfficientDet: Scalable and Efficient Object Detection这篇论文。 在这篇论文中,作…

Linux的学习

学习笔记,只写重点,不连贯,写得很水。 视频from:2021韩顺平 一周学会Linux。学习地址:https://www.bilibili.com/video/BV1Sv411r7vd 老师说明:后面我们的Redis、ginx包括项目都会使用到Linux,也是和我讲解的Linux版本…

Seata AT模式源码解析二(Seata Client端启动流程)

文章目录 初始化TM和RM数据源代理 由于我们一般都是在springboot中使用的,而与springboot集成的我们一般就先看starter的spring.factories文件,看看它的自动装配 这里面主要关注SeataAutoConfiguration和SeataDataSourceAutoConfiguration。 SeataAutoCo…