OpenCV基础(2)

目录

滤波处理

均值滤波

基本原理

函数用法

程序示例

高斯滤波 

基本原理

函数用法

程序示例

中值滤波

基本原理

函数用法

程序示例

形态学

腐蚀

膨胀

通用形态学函数


前言:本部分是上一篇文章的延续,前面部分请查看:OpenCV基础(1)

滤波处理

在尽量保留图像原有信息的情况下,过滤掉图像内部的噪声的过程称为对图像的平滑处理(又称滤波处理),所得图像称为平滑图像。
一般来说,图像平滑处理是指在一幅图像中若一个像素点与周围像素点的像素值差异较大,则将其值调整为周围邻近像素点像素值的近似值(如均值等),因此图像平滑处理通常也伴随图像模糊操作。由于近似值的取值方式不同,滤波也分为多种方式,这里对3种常用的滤波进行说明。

均值滤波

均值滤波是指用当前像素点周围 N×N 个像素值的均值代替当前像素值。使用该方法遍历处理图像内的每一个像素点,即可完成整幅图像的均值滤波。

基本原理

如果我现在想要对5行4列的像素点进行滤波。首先要考虑需要对周围多少个像素点取平均值。通常情况下,会以当前像素点为中心,求行数和列数相等的一块区域内的所有像素点的像素值的平均值。以上图中第 5 行第 4 列的像素点为中心,可以对其周围 3× 3 区域内所有像素点的像素值求平均值,也可以对其周围 5× 5 区域内所有像素点的像素值求平均值。我们对其周围 5× 5 区域内的像素点的像素值求平均,计算方法为

其实这也相当于将该像素点的 5× 5 邻域像素值与一个内部值都是 1/25 的 5× 5 矩阵相乘,得到均值滤波的结果 126。

这里可以把这个矩阵简化为以下形式

而简化后的矩阵也被叫做卷积核,一般形式为

其中,M和N是矩阵的高和宽,比较常用的有 3× 3、5× 5、7× 7 等。M N 的值越大,参与运算的像素点越多,当前像素点的计算结果受到越多的周围像素点影响。

函数用法

均值滤波的函数是 cv2.blur(),其语法格式为
dst = cv2.blur( src, ksize, anchor, borderType )

其中:

  • dst 是返回值,表示进行均值滤波后得到的处理结果。
  • src 是需要处理的图像,即原始图像。
  • ksize 是滤波核的大小。(就是卷积核)
  • anchor 是锚点,默认值是(-1,-1),表示当前计算均值的像素点位于滤波核的中心点位置。该值使用默认值即可,在特殊情况下可以指定不同的点作为锚点。
  • borderType 是边界样式,该值决定了以何种方式处理边界。OpenCV 提供了多种填充边界的方式,如用边缘值填充、用 0 填充、用 255 填充、用特定值填充等。

一般来说,anchor 和borderType 都不需要修改,因此只需要传入3个参数即可。

程序示例

import cv2
o=cv2.imread("Colnoiselena.jpg")
r3=cv2.blur(o,(3,3))
r11=cv2.blur(o,(7,7))
cv2.imshow("original",o)
cv2.imshow("result3",r3)
cv2.imshow("result7",r11)
cv2.waitKey()
cv2.destroyAllWindows()

上图中白色的点即为噪声,使用3× 3的卷积核时噪声明显有所改善,图像失真不太严重;使用7× 7 的卷积核时图像噪声大幅减少,但是图像失真很严重。

补充:失真表示与原图像的偏差,这里也就是模糊度。

卷积核越大,参与均值运算的像素点越多,即当前像素点计算的是周围更多点的像素点的像素值的均值。因此,卷积核越大,去噪效果越好,花费的计算时间越长,图像失真越严重。在实际处理中,要在失真和去噪效果之间取得平衡,选取合适大小的卷积核。

高斯滤波 

在高斯滤波中,会将邻近中心像素点的权重值加大,远离中心像素点的权重值减小,在此基础上计算邻域内各像素值不同权重的和。

基本原理

高斯滤波中,卷积核的值不再相等,但卷积核的大小一定要是奇数。不同大小的卷积核如下图示:

计算方式如下:

函数用法

高斯滤波的函数是 cv2.GaussianBlur(),该函数的语法格式是

dst = cv2.GaussianBlur( src, ksize, sigmaX, sigmaY, borderType )

其中:

  • dst 是返回值,表示滤波后的图像。
  • src 是需要处理的图像,即原始图像。
  • ksize 是滤波核的大小。滤波核大小是指在滤波处理过程中邻域图像的高度和宽度。滤波核的大小必须是奇数。
  • sigmaX 是卷积核在水平方向(X 轴方向)上的标准差,其控制的是权重比。
  • sigmaY是卷积核在垂直方向(Y轴方向)上的标准差。若将该值设置为0,则只采用sigmaX 的值;如果 sigmaX 和 sigmaY 都是 0,则通过 ksize.width 和 ksize.height 计算得到。其中:
  • borderType 是边界样式,该值决定了以何种方式处理边界。一般情况下,该值采用默认值即可。

补充:这里可能会有不理解标准差和权重比的,我简单说一下:标准差就是方差开根,表示数据的离散程度,换句话说就是标准差越大,表示所有数据离均值越远,越小离均值越近。而权重比就是卷积核内的数求和取倒数。

在这里,sigmaY 和 borderType 是可选参数。sigmaX 是必选参数,但是可以将该参数设置为 0,让函数自己去计算 sigmaX 的具体值。所以至少需要传入3个参数

一般来说当卷积核确定时,sigma 越大图像的去噪效果越好,但相应的图像也变得更为模糊,反之亦是如此。为了简便,我们一般不会手动去设置这个值,由函数自己计算,因此函数的一般形式为

dst = cv2.GaussianBlur( src, ksize, 0, 0 )

程序示例

import cv2
o=cv2.imread(r"Colnoiselena.jpg")
r1=cv2.GaussianBlur(o,(5,5),0,0)
r2=cv2.GaussianBlur(o,(5,5),0.1,0.1)
r3=cv2.GaussianBlur(o,(5,5),1,1)
cv2.imshow("original",o)
cv2.imshow("result1",r1)
cv2.imshow("result2",r2)
cv2.imshow("result3",r3)
cv2.waitKey()
cv2.destroyAllWindows()

可以明显看出,使用相同的卷积核时函数自己计算和标准差为1得到的去噪效果相差不大,但是由于标准差较大表现出模糊的现象。所以有时我们手动设置值得到的效果图不一定比默认的好啊。

中值滤波

中值滤波采用邻域内所有像素值的中间值来替代当前像素点的像素值。

基本原理

中值滤波会取当前像素点及其周围邻近像素点的像素值,先将这些像素值排序,然后将位于中间位置的像素值作为当前像素点的像素值。
对图中4行4列的像素点进行滤波,将其邻域设置为 3× 3 大小,对 3× 3 邻域内像素点的像素值进行排序,按升序排序后得到序列值为[66,78,90,91,93,94,95,97,101]。在该序列中,处于中心位置的值是“93”,用该值作为新像素值替换原来的像素值 78。

函数用法

中值滤波的函数是 cv2.medianBlur(),语法格式如下:
dst = cv2.medianBlur( src, ksize)

其中:

  • dst 是返回值,表示进行中值滤波后得到的处理结果。
  • src 是需要处理的图像,即原始图像。
  • ksize 是滤波核的大小。滤波核大小是指在滤波处理过程中邻域图像的高度和宽度。滤波核的大小必须是比 1 大的奇数,如 3、5、7 等。
注意: 均值和高斯滤波中卷积核都是元组,而中值滤波是一个奇数值。

程序示例

import cv2
o=cv2.imread("Colnoiselena.jpg")
r=cv2.medianBlur(o,3)
cv2.imshow("original",o)
cv2.imshow("result",r)
cv2.waitKey()
cv2.destroyAllWindows()

可以看出,中值滤波不存在其他滤波方式带来的细节模糊问题。中值滤波处理使用邻域像素点中间的像素值作为当前像素点的像素值。一般情况下噪声的像素值是一个特殊值,因此噪声成分很难被选作替代当前像素点的像素值,从而实现在不影响原有图像的情况下去除全部噪声。但是由于需要进行排序等操作,中值滤波的运算量较大

形态学

形态学主要从图像内提取分量信息,该分量信息通常是图像理解时所使用的最本质的形状特征。

腐蚀

腐蚀能够消除图像的边界点,使图像沿着边界向内收缩,也可以去除小于指定结构元的部分。
在腐蚀过程中,通常使用一个结构元逐个像素地扫描要被腐蚀的图像,并根据结构元和被腐蚀图像的关系来确定腐蚀结果。同时,该操作是逐个像素点地来决定像素值的,每次判定的像素点都是腐蚀结果图像中与结构元中心点所对应的像素点。

图中,黑色方块是结构元(又称核),白色圆形是前景

  • 如果结构元完全处于前景对象中,就将结构元中心点对应的腐蚀结果图像中的像素点处理为前景色(白色,像素点的像素值为 1)。
  • 如果结构元未完全处于前景对象中(可能部分在,也可能完全不在),就将结构元中心点对应的腐蚀结果图像中的像素点处理为背景色(黑色,像素点的 像素值为 0)。

最后得到的图像就会向内部收缩。下面我们用一个具体的示例进行说明。

图中

  • (a)表示待腐蚀图像 img。
  • (b)是核 kernel。
  • (c)中的阴影部分是核 kernel 在遍历 img 时,完全位于前景对象内部时的 3 个全部可能位置。也就是说,当核 kernel 处于任何其他位置时都不能完全位于前景对象中。
  • (d)是腐蚀结果 rst,即在核 kernel 完全位于前景对象中时,将其中心点对应的rst 中像素点的像素值置为 1;当核 kernel 不完全位于前景对象中时,将其中心点对应的rst 中像素点的像素值置为 0。
函数 cv2.erode()实现腐蚀操作,其语法格式为
dst = cv2.erode( src, kernel[, anchor[, iterations[, borderType[, borderValue]]]] )

其中:

  • dst 是腐蚀后输出的目标图像,该图像和原始图像的类型和大小相同。
  • src 是需要进行腐蚀的原始图像。
  • kernel 代表腐蚀操作时采用的结构类型,一般会输入一个元组。
  • anchor 代表结构元中锚点的位置。该值默认为(-1,-1),在核的中心位置。
  • iterations 是腐蚀操作迭代的次数,该值默认为 1,即只进行一次腐蚀操作。
import cv2
import numpy as np
o=cv2.imread("1.png")
kernel1 = np.ones((3,3),np.uint8)
erosion1 = cv2.erode(o,kernel1)
kernel2 = np.ones((5,5),np.uint8)
erosion2 = cv2.erode(o,kernel2, iterations=5)
cv2.imshow("orriginal",o)
cv2.imshow("erosion1",erosion1)
cv2.imshow("erosion2",erosion2)
cv2.waitKey()
cv2.destroyAllWindows()

可以看出,腐蚀操作具有腐蚀去噪功能,核越大腐蚀效果越明显。

膨胀

膨胀操作和腐蚀操作的作用是相反的,膨胀操作能对图像的边界进行扩张。膨胀操作将与当前对象(前景)接触到的背景点合并到当前对象内,从而实现将图像的边界点向外扩张。如果图像内两个对象的距离较近,那么经膨胀操作后,两个对象可能会连通在一起。膨胀操作有利于填补图像分割后图像内的空白处。

  • 如果结构元中任意一点处于前景对象中,就将膨胀结果图像中对应像素点处理为前景色。
  • 如果结构元完全处于背景对象外,就将膨胀结果图像中对应像素点处理为背景色。
膨胀结果就是前景对象的白色圆直径变大。同样,下面用一个示例进行说明。

图中:

  • (a)表示待膨胀图像 img。
  • (b)是核 kernel。
  • (c)中的阴影部分是核 kernel 在遍历 img 时,核 kernel 中心像素点位于 img[1,1]、 img[3,3]时与前景对象存在重合像素点的两种可能情况。
  • (d)是膨胀结果图像 rst。在核 kernel 内,当任意一个像素点与前景对象重合时,其中心点对应的膨胀结果图像内的像素点的像素值为 1;当核 kernel 与前景对象完全无重合时,其中心点对应的膨胀结果图像内的像素点值为 0。
函数 cv2.dilate()实现对图像的膨胀操作,该函数的语法结构为
dst = cv2.dilate( src, kernel[, anchor[, iterations[, borderType[, borderValue]]]])
其中:
  • dst 代表膨胀后输出的目标图像,该图像和原始图像类型和大小相同。
  • src 代表需要进行膨胀操作的原始图像。
  • kernel 代表膨胀操作采用的结构类型,一般是元组。
  • anchor 代表结构元中锚点的位置。该值默认为(-1,-1),在核的中心位置。
  • iterations 是膨胀操作迭代的次数,该值默认为 1,即只进行一次膨胀操作。
import cv2
import numpy as np
o=cv2.imread("erode2.jpg")
kernel = np.ones((5,5),np.uint8)
dilation1 = cv2.dilate(o,kernel)
dilation2 = cv2.dilate(o,kernel,iterations = 9)
cv2.imshow("original",o)
cv2.imshow("dilation1",dilation1)
cv2.imshow("dilation2",dilation2)
cv2.waitKey()
cv2.destroyAllWindows()

通用形态学函数

腐蚀操作和膨胀操作是形态学运算的基础,将腐蚀操作和膨胀操作进行组合,就可以实现开运算、闭运算、形态学梯度运算、顶帽运算(礼帽运算)、黑帽运算、击中击不中等多种不同形式的运算。
函数 cv2.morphologyEx()来实现上述形态学运算,其语法结构如下:
dst = cv2.morphologyEx( src, op, kernel[, anchor[, iterations[, borderType[, borderValue]]]] )
其中:
  • dst 代表经过形态学处理后输出的目标图像,该图像和原始图像的类型和大小相同。
  • src 代表待进行形态学操作的原始图像。
  • op 代表操作类型。各种形态学运算的操作规则均是将腐蚀操作和膨胀操作进行组合得到的。

形态学运算的主要含义及作用如下:
  • 开运算操作先将图像腐蚀,再对腐蚀的结果进行膨胀,可以用于去噪、计数等。
  • 闭运算是先膨胀、后腐蚀的操作,有助于关闭前景物体内部的小孔,或去除物体上的小黑点,还可以将不同的前景对象进行连接。
  • 形态学梯度运算是用原始图像的膨胀图像减腐蚀图像的操作,该操作可以获取原始图像中前景对象的边缘。
  • 顶帽运算是用原始图像减去其开运算图像的操作。该操作能够获取图像的噪声信息,或者得到比原始图像的边缘更亮的边缘信息。
  • 黑帽运算是用闭运算图像减去原始图像的操作。该运算能够获取图像内部的小孔,或前景色中的小黑点,或者得到比原始图像的边缘更暗的边缘部分。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

航模插头篇

一、常见的电池插头(电调端 是公头 电池端 是母头) 电池总是被插的 1.XT60头 过流大 安全系数高 难插拔 2.T插 插拔轻松 过流比较小 容易发烫 电调端 是公头 电池端 是母头 3.香蕉头插孔 过流够 插拔轻松 但 容易插反 爆炸 4.TX90(和XT60差…

命令行升级ubuntu版本过程中出现的grub问题 解决

1、问题描述 使用命令行升级ubuntu18到20版本后,系统提示重启,使用reboot命令重启后,不显示服务器ip,或是显示但无法ssh远程连接服务器了,使用屏幕连接服务器后发现出现grub问题。 2、问题经过 命令行输入如下升级u…

腾讯云函数部署环境[使用函数URL]

使用函数URL 之前使用的是网关API,最近腾讯云的网关API说要关闭了,所以没有办法这里改成函数URL,使用后发现只要不是在浏览器直接访问的情况,函数URL都可以满足! 这里结合腾讯云函数node.js返回自动带反斜杠这篇文章来做说明,比如这里的URL如下: 结合文章腾讯云函数node.js返…

Altium Designer专业PCB设计软件下载安装 Altium Designer安装包下载获取

在电子设计的广袤领域中,PCB设计无疑占据着重要的地位。而Altium Designer作为一款业界领先的电子设计自动化软件,其提供的先进布局工具,无疑为设计师们打开了一扇通往高效、精确设计的大门。 在PCB设计的核心环节——布局中,Alti…

初出茅庐的小李博客之C语言文件操作

C语言文件操作 在C语言中,文件操作主要是通过标准库函数来实现的。 今天有时间就来学习下一些常用的文件操作函数: C 语言提供了一个 FILE 数据结构,记录了操作一个文件所需要的信息。该结构定义在头文件stdio.h,所有文件操作函…

tampermonkey插件下载国家标准文件

#创作灵感# 最近在一个系统招标正文中看到了一些国家标准,想要把文章下载下来,方便查阅,但是“国家标准全文公开系统”网站只提供了在线预览功能,没有提供下载功能,但是公司又需要文件,在网上找了一些办法&…

眼动追踪技术 | 眼动的分类和模型

摘要 灵长类动物用于调整中央凹位置的正常眼动,几乎都可以归结为五种基本类型的组合:扫视、平稳追踪、聚散、前庭眼震和生理性眼震(与注视相关的微小运动)。聚散运动用于将双眼聚焦于远处的目标(深度知觉)。其他运动(如适应和聚焦)指的是眼动的非位置变…

Spring学习03-[Spring容器核心技术IOC学习进阶]

IOC学习进阶 Order使用Order改变注入顺序实现Ordered接口,重写getOrder方法来改变自动注入顺序 DependsOn使用 Lazy全局设置-设置所有bean启动时候懒加载 Scopebean是单例的,会不会有线程安全问题 Order 可以改变自动注入的顺序 比如有个animal的接口&a…

Java实现单点登录(SSO)详解:从理论到实践

✨✨谢谢大家捧场,祝屏幕前的小伙伴们每天都有好运相伴左右,一定要天天开心哦!✨✨ 🎈🎈作者主页: 喔的嘛呀🎈🎈 ✨✨ 帅哥美女们,我们共同加油!一起进步&am…

miniprogram-to-uniapp-微信小程序转换成uniapp项目

文章目录 参考:miniprogram-to-uniapp使用指南第一步第二步第三步第四步【miniprogram-to-uniapp】转换微信小程序”项目为uni-app项目(新版本工具已经支持各种小程序转换) 参考: 小程序技能树 uni-app基础知识总结 miniprogram-to-uniapp使用指南 第一步 win + R 输入…

打卡第2天----数组双指针,滑动窗口

今天是参与训练营第二天,这几道题我都看懂了,自己也能写出来了,实现思路很重要,万事开头难,希望我可以坚持下去。希望最后的结果是量变带来质变。 一、理解双指针思想 leetcode编号:977 不止是在卡尔这里…

【软件测试】之自动化测试

🏀🏀🏀来都来了,不妨点个关注! 🎧🎧🎧博客主页:欢迎各位大佬! 文章目录 什么是自动化测试Selenium介绍什么是SeleniumSelenium的特点工作原理 SeleniumJava环境搭建下载…

项目管理实用表格与应用【项目文件资料分享】

项目管理基础知识 项目管理可分为五大过程组(启动、规划、执行、监控、收尾)十大知识领域,其中包含49个子过程 项目十大知识领域分为:项目整合管理、项目范围管理、项目进度管理、项目成本管理、项目质量管理、项目资源管理、项目…

实现各平台确定性的物理碰撞

1.使用FixedUpdate而不是Update 1.物理运算,比如刚体运动系统的运算是通过固定的时间来驱动的。 2.再moba帧同步游戏中,15帧的固定调用差不多是网络那边的极限了,采用其他手段如平滑显示来提高画面的平滑度。 FixedUpdate是以一个固定的帧率…

前端Debugger时复制的JS对象字符转JSON对象

前端debugger时,复制的对象在控制台输出时是如下格式,需要转换为对象格式来进行验证操作 bridgeId : 4118 createBy : null createTime : "2023-03-24 10:35:26" createUserId : 1 具体实现代码: // 转换transform (text) {l…

腾讯课堂即将停止服务?来试试这款开源的知识付费系统

项目介绍 本系统基于ThinkPhp5.0layuiVue开发,功能包含在线直播、付费视频、付费音频、付费阅读、会员系统、分销系统、拼团活动、直播带货、直播打赏、商城系统等。能够快速积累客户、会员数据分析、智能转化客户、有效提高销售、吸引流量、网络营销、品牌推广的一款应用&…

如何检查购买的Facebook账号优劣?

Facebook 是全球最受欢迎的社交网络之一,为品牌广告提供了巨大的潜力。许多公司和营销人员使用 Facebook 来推广他们的产品和服务,经常会购买账号。当然也分出了很多账号,比如个人号,BM号,广告号,小黑号等等。 但是,有…

【高阶数据结构】图的应用--最短路径算法

文章目录 一、最短路径二、单源最短路径--Dijkstra算法三、单源最短路径--Bellman-Ford算法四、多源最短路径--Floyd-Warshall算法 一、最短路径 最短路径问题:从在带权有向图G中的某一顶点出发,找出一条通往另一顶点的最短路径,最短也就是沿…

图像信号处理器(ISP)基础算法及处理流程

💪 专业从事且热爱图像处理,图像处理专栏更新如下👇: 📝《图像去噪》 📝《超分辨率重建》 📝《语义分割》 📝《风格迁移》 📝《目标检测》 📝《暗光增强》 &a…

找不到msvcp120.dll无法继续执行的原因分析及解决方法

在计算机使用中,经常会遇到msvcp120.dll文件丢失的情况,很多人对这个文件不是很熟悉,今天就来给大家讲解一下msvcp120.dll文件的丢失以及这个文件的重要性,让大家更好地了解计算机,同时也可以帮助我们更好地掌握这个文…