OpenCV基础(2)

news2024/10/6 6:24:54

目录

滤波处理

均值滤波

基本原理

函数用法

程序示例

高斯滤波 

基本原理

函数用法

程序示例

中值滤波

基本原理

函数用法

程序示例

形态学

腐蚀

膨胀

通用形态学函数


前言:本部分是上一篇文章的延续,前面部分请查看: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.coloradmin.cn/o/1895467.html

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

相关文章

深入理解如何撤销 Git 中不想提交的文件

个人名片 🎓作者简介:java领域优质创作者 🌐个人主页:码农阿豪 📞工作室:新空间代码工作室(提供各种软件服务) 💌个人邮箱:[2435024119qq.com] &#x1f4f1…

图增强LLM + 可穿戴设备实时数据,生成个性化健康见解

图增强LLM 可穿戴设备实时数据,生成个性化健康见解 提出背景图增强LLM 子解法1(使用层次图模型) 子解法2(动态数据整合) 子解法3(LLM引导评估) 提出背景 论文:https://arxiv.or…

【js正则】去除文本中的a标签及其内容

场景&#xff1a;有时候服务端返回的文本中&#xff0c;包含a标签&#xff0c;前端不需要展示。 // 示例 const inputText 【提醒&#xff1a;XXXX】\nXXXXXX: 1\n\n<a href"https://export.shobserver.com/baijiahao/html/767805.html">详情</a>;JS正…

【营销策划模型大全】私域运营必备

营销策划模型大全&#xff1a;战略屋品牌屋、电商运营模型、营销战略、新媒体运营模型、品牌模型、私域运营模型…… 该文档是一份策划总监工作模型的汇总&#xff0c;包括战略屋/品牌屋模型、营销战略模型、品牌相关模型、电商运营模型、新媒体运营模型和私域运营模型等&…

JavaScript基础-函数(完整版)

文章目录 函数基本使用函数提升函数参数arguments对象&#xff08;了解&#xff09;剩余参数(重点)展开运算符(...) 逻辑中断函数参数-默认参数函数返回值-return作用域(scope)全局作用域局部作用域变量的访问原则垃圾回收机制闭包 匿名函数函数表达式立即执行函数 箭头函数箭头…

全自动内衣洗衣机什么牌子好?四大热门内衣洗衣机多角度测评

内衣洗衣机是近几年新兴的一种家用电器产品&#xff0c;正日益引起人们的重视。但是&#xff0c;面对市面上品牌繁多、款式繁多的内衣洗衣机&#xff0c;使得很多人都不知道该如何选择。身为一个数码家电博主&#xff0c;我知道这类产品在挑选方面有着比较深入的了解。为此&…

AIGC对设计师积极性的影响

随着科技的迅猛发展&#xff0c;生成式人工智能&#xff08;AIGC&#xff09;工具正逐渐深入设计的每个角落&#xff0c;对设计师的工作方式和思维模式产生了深远的影响。AIGC不仅极大提升了设计师的工作效率&#xff0c;更激发了他们的创新思维&#xff0c;为设计行业带来了翻…

好文阅读-日志篇

https://mp.weixin.qq.com/s/jABbG4MKvEiWXwdYwUk8SA 这里直接看最佳实践。 Maven 依赖 <dependencyManagement><dependencies><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.36…

聊聊 CTO 和 技术总监的区别

前言 CTO&#xff08;Chief Technology Officer&#xff09;&#xff0c;是首席技术官的意思。 技术总监&#xff0c;顾名思义&#xff0c;就是负责指导和监督公司的技术团队&#xff0c;确保技术和产品的开发与创新顺利进行。 有的软件公司同时有 CTO 和技术总监&#xff0…

第二届计算机、视觉与智能技术国际会议(ICCVIT 2024)

随着科技的飞速发展&#xff0c;计算机、视觉与智能技术已成为推动现代社会进步的重要力量。为了汇聚全球顶尖专家学者&#xff0c;共同探讨这一领域的最新研究成果和前沿技术&#xff0c;第二届计算机、视觉与智能技术国际会议&#xff08;ICCVIT 2024&#xff09;将于2024年1…

JAVA高级进阶11多线程

第十一天、多线程 线程安全问题 线程安全问题 多线程给我们带来了很大性能上的提升,但是也可能引发线程安全问题 线程安全问题指的是当个多线程同时操作同一个共享资源的时候,可能会出现的操作结果不符预期问题 线程同步方案 认识线程同步 线程同步 线程同步就是让多个线…

swiftui中几个常用的手势控制单击点击,双击和长按事件

简单做了一个示例代码&#xff0c;包含三个圆形形状&#xff0c;配置了不同的事件&#xff0c;示例代码&#xff1a; // // RouterView.swift // SwiftBook // // Created by song on 2024/7/4. //import SwiftUIstruct RouterView: View {State var isClick falsevar bod…

中实新材料:领航绿色建材新纪元,北京创新力量再攀高峰!

近期,北京中实新材料有限责任公司(以下简称“中实新材料”)以一系列耀眼的成果,彰显了其在绿色建材领域的卓越领导地位,不仅在生产效能、技术创新、市场拓展上取得了显著突破,更在社会责任与荣誉表彰上赢得了广泛赞誉。作为中关村科技发展(控股)股份有限公司旗下的璀璨明珠,中实…

Java - 程序员面试笔记记录 实现 - Part3

4.1 线程与进程 线程是程序执行的最小单元&#xff0c;一个进程可以拥有多个线程&#xff0c;各个线程之间共享程序的内存空间以及一些进程级资源&#xff0c;但拥有自己的栈空间。 4.3 Java 多线程 方法一&#xff1a;继承 Thread 类&#xff0c;重写 run 方法&#xff1b;…

实验五 数据库完整性约束的实现与验证

题目 在实验四的基础上&#xff0c;重新创建以下三个表&#xff1a; 会员表&#xff1a;member(memno,memname,address,telephone,username,userpwd)&#xff0c;主码为memno&#xff0c;属性memname不能取空值 员工表&#xff1a;employee(empno,empname,depno,sex,telephone…

【电源专题】DC-DC电路设计为什么一般只考虑电感DCR而不考虑Q值呢?

什么是电感器(线圈)的Q值&#xff1f; Q值是表示电感器质量的参数。Q是Quality Factor&#xff08;质量系数&#xff09;的简称。线圈会顺利流过直流电流&#xff0c;但会对交流电流产生电阻。这称为感抗&#xff0c;交流频率越高则越大。 此外&#xff0c;绕组虽是导体…

基于Istio的多网关运行时:配置、部署和应用

1. 引言 Istio是一个开源的服务网格&#xff0c;主要应用于简化微服务架构中的服务间通信、提供强大的监控能力以及加强服务的安全管理。通过利用Sidecar模式部署的Envoy代理&#xff0c;Istio能够在几乎无需修改服务代码的情况下&#xff0c;实现服务发现、负载均衡、加密通信…

C语言实战 | Flappy Bird游戏

Flappy Bird游戏是由一名越南游戏制作者独自开发的&#xff0c;曾经风靡全球。游戏规则非常简单&#xff0c;玩家必须控制一只小鸟&#xff0c;跨越由各种长度的水管所组成的障碍物&#xff0c;如果撞上管道游戏就结束&#xff0c;如图11.11所示。 ■ 图11.11Flappy Bird 游戏 …

go语言day08 泛型 自定义错误处理 go:协程

泛型&#xff1a; 抛错误异常 实现error接口类型 用java语言解释的话&#xff0c;实现类需要重写error类型的抽象方法Error().这样就可以自定义异常处理。 回到go语言&#xff0c;在Error()方法中用*argError 这样一个指针类来充当error接口的实现类。 在f2()方法中定义返回值…

IMU用于仿生水下机器人姿态估计

近期&#xff0c;自中国农业大学的研究团队从海豚身上汲取灵感&#xff0c;成功研发出一种创新性的双腱驱动机器人海豚尾鳍。这项创新性的设计不仅能够实现全方向运动&#xff0c;还能精细地模拟海豚的推力特性&#xff0c;揭示了其背后隐藏的力学秘密。 这款机器人尾鳍设计独特…