【OpenCV实现平滑图像处理】

news2024/11/21 2:34:18

文章目录

    • 概要
    • 2D 卷积(图像过滤)
    • 模糊图像(平滑图像)
    • 中值模糊
    • 双边过滤
    • 小结

概要

在图像处理中,低通滤波器是一种常用的技术,用于平滑、模糊或降低图像的噪音。这种滤波器通过去除图像中高频部分(即变化较快的部分)来实现这些效果。通过应用2D卷积操作,低通滤波器将每个像素的值与其周围像素的值进行加权平均,从而实现图像的平滑处理。

在实际应用中,我们可以定制不同类型的低通滤波器,例如平均滤波器、高斯滤波器等,根据需求选择合适的滤波器。平均滤波器将像素的值替换为其周围像素值的平均值,从而消除图像中的高频噪音。而高斯滤波器则使用高斯函数生成一个权重矩阵,将像素值进行加权平均,使得距离中心像素越远的像素权重越小,实现更加自然的平滑效果。

定制的低通滤波器可以根据图像特性进行调整,例如在面对强烈噪音时增加滤波器的大小,或者根据图像中对象的大小调整滤波器的标准差。这种灵活性使得低通滤波器在图像处理中具有广泛的应用,例如在计算机视觉中的目标检测、图像识别、医学图像处理等领域。

2D 卷积(图像过滤)

使用各种低通滤波平滑图像
将定制的过滤器应用在图像上(2D卷积)

OpenCV提供了一个非常有用的函数,即cv.filter2D,该函数允许我们将一个图像和一个自定义的核(也称为滤波器)进行卷积操作。举个例子,如果我们想在一幅图像上尝试平均滤波,我们可以使用一个简单的平均核,该核中的所有元素值相等,代表了平均操作。通过使用cv.filter2D函数,我们可以将这个平均核应用到图像上,从而实现平均滤波的效果。

这种滤波技术不仅可以用于去除图像中的噪声,还可以在图像处理任务中发挥关键作用,比如在边缘检测、图像增强和特征提取等领域。
一个 5 X 5 的平均滤波核如下所示:

在这里插入图片描述
保持这个核在像素上面,将被这个核覆盖的25个像素点的值求平均值,然后将这个平均值替换掉最中间那个像素点的值。然后将这个操作应用在图像的所有像素点上。

# 导入必要的库
import numpy as np  # 用于数值计算
import cv2 as cv     # OpenCV库,用于图像处理
import matplotlib.pyplot as plt  # 用于绘图和可视化

# 读取图像文件 'img.png'
img = cv.imread('img.png')

# 定义一个 5x5 的平均滤波核
kernel = np.ones((5, 5), np.float32) / 25

# 使用 cv2.filter2D 函数将图像与平均滤波核进行卷积
dst = cv.filter2D(img, -1, kernel)

# 绘制原始图像、平均滤波后的图像并显示
plt.subplot(121)  # 创建第一个子图
plt.imshow(img)    # 显示原始图像
plt.title('Original')  # 设置子图标题为 'Original'
plt.xticks([]), plt.yticks([])  # 隐藏坐标轴

plt.subplot(122)  # 创建第二个子图
plt.imshow(dst)    # 显示平均滤波后的图像
plt.title('Averaging')  # 设置子图标题为 'Averaging'
plt.xticks([]), plt.yticks([])  # 隐藏坐标轴

plt.show()  # 显示绘制好的图像

在这里插入图片描述

模糊图像(平滑图像)

图像处理中,模糊(或称平滑)图像是一种常见的操作,可以通过低通滤波器与图像进行卷积来实现。这个技术非常有效地去除图像中的噪声,因为它能够消除高频内容,比如噪声和边缘。然而,需要注意的是,模糊操作也会稍微模糊图像的边缘,尽管有一些特殊的模糊技术可以保持边缘的清晰度。

  1. 平均
    这是通过将图像与归一化框滤波器进行卷积完成的。它简单的将核下面的像素值求平均并覆盖中间的像素值。这个可以使用函数cv.blur() 或者 cv.boxFilter() 来实现。我们应该指定内核的高度和宽度。一个 3 X 3 的归一化框滤波器如下所示:
    在这里插入图片描述
    Note: 如果你不想使用归一化框滤波器,那可以使用 cv.boxFilter。将 normalize=False 传入函数。
# 导入必要的库
import cv2 as cv  # OpenCV库,用于图像处理
import numpy as np  # 用于数值计算
from matplotlib import pyplot as plt  # 用于绘图和可视化

# 读取图像文件 'img.png'
img = cv.imread('img.png')

# 使用平均模糊(平滑)技术对图像进行处理,卷积核大小为 (5, 5)
blur = cv.blur(img, (5, 5))

# 绘制原始图像和模糊处理后的图像并显示
plt.subplot(121)  # 创建第一个子图
plt.imshow(img)    # 显示原始图像
plt.title('Original')  # 设置子图标题为 'Original'
plt.xticks([]), plt.yticks([])  # 隐藏坐标轴

plt.subplot(122)  # 创建第二个子图
plt.imshow(blur)   # 显示平均模糊后的图像
plt.title('Blurred')  # 设置子图标题为 'Blurred'
plt.xticks([]), plt.yticks([])  # 隐藏坐标轴

plt.show()  # 显示绘制好的图像

在这里插入图片描述

2.高斯滤波(Gaussian Blur)
在高斯滤波中,我们使用高斯核替代了盒(框)滤波器。这种滤波方法已经被集成在OpenCV的cv.GaussianBlur()函数中。在使用高斯滤波时,我们需要确定核的高度和宽度,这两个数值需要是正数且奇数。此外,我们还需要指定X和Y方向上的标准差(sigma X和sigma Y)。如果只确定了sigma X,那么sigma Y的值会被设置为与sigma X相同。如果两者都为0,那么它们的值会根据核的大小自动计算。

高斯滤波在去除图像中的高斯噪声方面非常有效。高斯核的权重分布使得中心像素周围的像素对平均值的贡献更大,这样可以更好地保留图像的细节。

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

# 读取图像文件 'img.png'
img = cv.imread('img.png')

# 使用高斯滤波(核大小为 5x5,标准差为 0,表示自动计算)
blur = cv.GaussianBlur(img, (5, 5), 0)

# 绘制原始图像和高斯滤波处理后的图像并显示
plt.subplot(121)  # 创建第一个子图
plt.imshow(img)    # 显示原始图像
plt.title('Original')  # 设置子图标题为 'Original'
plt.xticks([]), plt.yticks([])  # 隐藏坐标轴

plt.subplot(122)  # 创建第二个子图
plt.imshow(blur)   # 显示高斯滤波后的图像
plt.title('Blurred')  # 设置子图标题为 'Blurred'
plt.xticks([]), plt.yticks([])  # 隐藏坐标轴

plt.show()  # 显示绘制好的图像

在这里插入图片描述

中值模糊

中值模糊是一种特殊的滤波技术,它的原理是在核的覆盖区域内找到像素值的中间值,并将中间值赋给核中心的像素点。与其他滤波方法不同,中值滤波不是使用计算得到的新值替代中心像素,而是直接采用该区域内的中间值。

在OpenCV中,中值滤波可以通过cv.medianBlur()函数实现。与其他滤波方法类似,中值滤波的核的大小也应该是正数和奇数。这种滤波技术在处理图像中的椒盐噪声(图像中随机出现的亮或暗像素点)非常有效。因为它通过选择中间值,可以避免受到噪声的干扰。

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

# 读取图像文件 'img.png'
img = cv.imread('img.png')

# 使用中值模糊(核大小为 5x5)
blur = cv.medianBlur(img, 5)

# 绘制原始图像和中值模糊处理后的图像并显示
plt.subplot(121)  # 创建第一个子图
plt.imshow(img)    # 显示原始图像
plt.title('Original')  # 设置子图标题为 'Original'
plt.xticks([]), plt.yticks([])  # 隐藏坐标轴

plt.subplot(122)  # 创建第二个子图
plt.imshow(blur)   # 显示中值模糊后的图像
plt.title('Blurred')  # 设置子图标题为 'Blurred'
plt.xticks([]), plt.yticks([])  # 隐藏坐标轴

plt.show()  # 显示绘制好的图像

在这里插入图片描述

双边过滤

双边过滤在需要处理噪声但又需要保持图像边缘清晰的场景中非常有效。它的操作由cv.bilateralFilter()函数完成。相较于其他滤波器,这个操作相对较慢。我们已经了解到,高斯滤波器通过获取像素周围的邻域并计算其高斯加权平均值来进行操作。高斯滤波仅仅是一个空间函数,即在滤波时只考虑相邻像素的值。它不会检查像素值是否接近,也不会检查一个像素是否是边缘像素。因此,它可能会模糊掉一些我们希望保留的边缘细节。

双边滤波在空间上同样使用高斯滤波器,但还引入了一个像素强度差异的高斯滤波器。空间上的高斯函数确保只有附近的像素被用来进行模糊处理,而像素差异高斯函数确保只有与中心像素具有相似强度的像素被模糊处理。因此,它可以保持图像边缘的清晰度,因为边缘处的像素会有较大的强度变化,不容易被平滑掉。这种特性使得双边滤波在同时保持图像细节和去除噪声的需求下表现出色。

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

# 读取图像文件 'img.png'
img = cv.imread('img.png')

# 使用双边过滤(参数:d表示领域直径,sigmaColor表示颜色空间标准差,sigmaSpace表示坐标空间标准差)
blur = cv.bilateralFilter(img, d=9, sigmaColor=75, sigmaSpace=75)

# 绘制原始图像和双边过滤处理后的图像并显示
plt.subplot(121)  # 创建第一个子图
plt.imshow(img)    # 显示原始图像
plt.title('Original')  # 设置子图标题为 'Original'
plt.xticks([]), plt.yticks([])  # 隐藏坐标轴

plt.subplot(122)  # 创建第二个子图
plt.imshow(blur)   # 显示双边过滤后的图像
plt.title('Bilateral Filtered')  # 设置子图标题为 'Bilateral Filtered'
plt.xticks([]), plt.yticks([])  # 隐藏坐标轴

plt.show()  # 显示绘制好的图像

在这里插入图片描述

小结

总之,低通滤波器通过2D卷积操作,能够有效平滑图像、去除噪音、提高图像质量,为各种图像处理任务提供了重要支持。通过定制不同类型的滤波器,我们能够根据具体需求进行图像处理,获得更清晰、更有信息量的图像结果。

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

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

相关文章

基于FPGA的电风扇控制器verilog,视频/代码

名称:基于FPGA的电风扇控制器verilog 软件:QuartusII 语言:Verilog 代码功能: 基于FPGA的电风扇控制器 运用 EDA SOPO实验开发系统设计一个基于FPGA的电风扇定时开关控制器,能实现手动和自动模式之间的切换。要求: (1)KI为电…

PLM如何与MES管理系统协同工作

产品生命周期管理(PLM)和MES生产管理系统是现代企业中不可或缺的生产管理工具。它们分别负责产品的设计和制造过程,对于提高企业的生产效率和产品质量具有重要作用。然而,要实现高效的生产管理,PLM和MES需要进行协同工…

Python---练习:使用for循环嵌套实现打印九九乘法表

思考: 外层循环主要用于控制循环的行数,内层循环用于控制列数。 基本语法: # 外层循环 for i in 序列1:# 内层循环for j in 序列2:循环体 序列1 序列2 ,就可以是range(1, 10) -----也就是从1,到9。 参考while循环…

笔记43:ResNet 结构详解

笔记本地地址:D:\work_file\DeepLearning_Learning\03_个人笔记\2.图像处理任务\ResNet网络学习 a a a a a a a a a a a a a a a a a a a a a a a a a a a a a

DTO、VO、BO、PO等各种XO汇总

贫血模型和富领域模型 1.POJO对象(Plain Old Java Object) Plain Old Java Object(POJO),它的本来含义是指一个常规的、不受任何框架、平台的约束和限制的Java对象。可以认为,如果一个模块定义的对象皆为POJO,那么除了依赖JDK,它…

聚团队之力,学领军之道——麒麟信安组织开展卓越领导力主题培训

为提升高层次管理人员的领导力水平,为企业上市后高速发展以及高效运营提供更好支撑,日前,麒麟信安组织开展卓越领导力主题培训,公司领导层、各部门负责人以及各项目、技术骨干共同参加。 麒麟信安总裁刘文清作开训致辞。刘总指出&…

Python---练习:使用for循环实现用户名+密码认证

案例: 用for循环实现用户登录 ① 输入用户名和密码 ② 判断用户名和密码是否正确(usernamelaowang,passwordlw123) ③ 登录仅有三次机会,超过3次会报错 思考: 用户登陆情况有3种: ① 用户名错误(此时…

Ctrl+Alt+L或Ctrl+Alt+M或Ctrl+Alt+S热键无法启用(华硕天选)与armoury creat冲突

其实就是冲突了,但是就是检测不到(spy测不到,其他哪个open啥啥啥的直接进不去内核模式)。然后去找了个按键检测,发现都是找不到按键按下的事件,能检测到按键抬起事件,判断要么是应用占用&#x…

常见面试题-MySQL专栏(一)

为什么 mysql 删了行记录,反而磁盘空间没有减少? 答: 在 mysql 中,当使用 delete 删除数据时,mysql 会将删除的数据标记为已删除,但是并不去磁盘上真正进行删除,而是在需要使用这片存储空间时&…

vue源码分析(二)——vue的入口发生了什么

文章目录 前言(1)vue 项目构建的时候,通过package.json文件看到构建入口(2) 构建入口页面:导入同级模块config的getAllbuilds方法(3) 通过传入参数中的builds对象使用map获取&#x…

Python---for循环嵌套

for循环嵌套,就是一个for循环里面嵌套另外一个for循环的写法。 当循环结构相互嵌套时,位于外层的循环结构常简称为外层循环或外循环,位于内层的循环结构常简称为内层循环或内循环。 基本语法: # 外层循环 for i in 序列1:# 内层…

Typecho 添加 Emoji 表情报错「解决方案」

Typecho 添加 Emoji 表情报错 文章目录 Typecho 添加 Emoji 表情报错前言Emoji 表情utf8mb4 与 UTF8 解决方案[1] 数据库编码更改[2] 数据库配置文件更改 前言 Typecho 添加 Emoji 表情不支持,报错 Database Query Error Emoji 表情 Emoji 就是表情符号&#xff0c…

VMware Workstation提示:另一个程序已锁定文件的一部分,进程无法访问,删除.lck文件夹和文件

一、如图 二、原因 因为虚拟机在运行的时候,会锁定文件,防止被修改,而如果系统突然崩溃,虚拟机就来不急把已锁定的文件解锁。当你再次启动虚拟机的时候,会提示这类错误信息。 三、解决 进入虚拟机文件夹,…

node模块导出引入两种方式和npm包管理

模块化的好处 在 Node.js 中每个文件都被当做是一个独立的模块,模块内定义的变量和函数都是独立作用域的,因为 Node.js 在执行模块代码时,将使用如下所示的函数封装器对其进行封装 (function(exports,require,module,__filename,_dirname){//…

JavaScript-2-菜鸟教程

字符串 可以使用 索引 位置访问字符串中的每个字符 可以使用内置属性 length 来计算字符串的长度 var txt "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; var sln txt.length;<script>var x "John"; // x是一个字符串// 使用 new 关键字将字符…

p5.js 变换操作

本文简介 带尬猴&#xff0c;我嗨德育处主任 在 canvas 里&#xff0c;变换是基础功能。很多基于 canvas 封装的库都有这功能&#xff0c;比如 《Fabric.js 变换视窗》。 变换是针对画布进行全局调整的一种能力&#xff0c;它可以对画布进行全局移动、缩放、旋转等操作。 p5…

hibernate源码(2)--- springboot-jpa是如何引入的

starter引入 要想看jpa是如何将hibernate引入容器&#xff0c;首先要看的是 spring-boot-starter-data-jpa 如何引入依赖&#xff1a; 如果注意的话&#xff0c;starter的包内容其实没有什么实质的内容&#xff0c;关键是pom里的依赖 pom中规定了各依赖和依赖的版本&#xf…

python 过滤曲线噪点(滤波)

import numpy as np import matplotlib.pyplot as plt from scipy import signal# 生成示例信号 t np.linspace(0, 1, 1000) x np.sin(2 * np.pi * 5 * t) np.sin(2 * np.pi * 20 * t) np.random.randn(len(t)) * 0.2# 设计低通滤波器 order 3 # 滤波器阶数 cutoff_freq …

Linux--进程等待

1.什么是进程等待 1.通过系统调用wait/waitid,来对子进程进行进行检测和回收的功能。 2.为什么有进程等待 1.对于每个进程来说&#xff0c;如果子进程终止&#xff0c;父进程没有停止&#xff0c;就会形成僵尸进程&#xff0c;导致内存泄露&#xff0c;为了防止僵尸进程的形成…

【组合计数】CF1866 H

Problem - H - Codeforces 题意 思路 不知道这种trick叫什么&#xff0c;昨天VP刚遇到过 设 f[x] 为恰好有一个最大值为 x 的方案数&#xff0c;我们要求这个&#xff0c;那就设 g[x] 为 至少有一个最大值为 x 的方案数&#xff0c;那么答案就是 f[x] g[x] - g[x - 1] 这里…