【OpenCV入门】第八部分——滤波器

文章结构

  • 图像平滑处理
  • 均值滤波器
  • 中值滤波器
  • 高斯滤波器
  • 双边滤波器
  • 拉普拉斯高通滤波器

图像平滑处理

图像平滑处理是指在尽量保留原图像信息的情况下,去除掉图像内部的噪声(分布不均匀的、高亮度的像素点)。而用于图像平滑处理的工具就是滤波器。OpenCV提供了种类丰富的滤波器,虽然每种滤波器的实现算法都不同,但每种滤波器都能完成图像平滑处理的操作。本文主要讲解其中的4中滤波器,分别是均值滤波器中值滤波器高斯滤波器双边滤波器

均值滤波器

噪声与周围像素的差别非常大,导致从视觉上就能看出噪声无法与周围像素组成可识别的图像信息,从而降低了整个图像的质量。如果图像中的噪声都是随机的纯黑像素或者纯白像素,这样的噪声也被称作“椒盐噪声”或“盐噪声”。

以一个像素为核心,核心周围像素可以组成一个 n 行 n 列(简称 n × n) 的矩阵,这样的矩阵结构在滤波操作中被称为“滤波核”。矩阵的行列数决定了滤波核的大小,例如图 9.4 所示的滤波核大小为 3x3,包含 9 个像素;图 9.5 所示的滤波核大小为 5x5,包含 25 个像素。

在这里插入图片描述
均值滤波器 (也被称为低通滤波器) 可以把图像中的每一个像素都当成滤波核的核心,然后计算出核内所有像素的平均值,最后让核心像素值等于这个平均值。

在这里插入图片描述

上图就是均值波的计算过程。滤波核大小为 3x3,核心像素值是 35,颜色极深,周围像素值都在 110~150之间,因此可以认为核心像素是噪声。将滤波核中的所有像素值相加,然后除以像素个数,就得出了平均值 123 (四舍五入取整)。将核心像素的值改成 123,其颜色就与周围颜色差别不大了,图像就变得平滑了。这就是均值滤波去噪的原理。

OpenCV将均值滤波器封装成了 blur()方法:

dst = cv2.blur(src, ksize, anchor, borderType)
  • src: 被处理的图像。
  • ksize: 滤波核大小,其格式为(高度,宽度),建议使用如(3,3)、(5,5)、(7,7)等宽高相等的奇数边长。滤波核越大,处理之后的图像就越模糊。
  • anchor: (可选)滤波核的锚点,建议采用默认值,方法可以自动计算锚点
  • borderType:(可选)边界样式,建议采用默认值
  • dst: 经过均值滤波处理之后的图像。

实例1: 对花朵图像进行均值滤波操作

import cv2img = cv2.imread("3.png")  # 读取原图
dst1 = cv2.blur(img, (3, 3))  # 使用大小为3*3的滤波核进行均值滤波
dst2 = cv2.blur(img, (5, 5))  # 使用大小为5*5的滤波核进行均值滤波
dst3 = cv2.blur(img, (9, 9))  # 使用大小为9*9的滤波核进行均值滤波
cv2.imshow("img", img)  # 显示原图
cv2.imshow("3*3", dst1)  # 显示滤波效果
cv2.imshow("5*5", dst2)
cv2.imshow("9*9", dst3)
cv2.waitKey()  # 按下任何键盘按键后
cv2.destroyAllWindows()  # 释放所有窗体

结果如下:

在这里插入图片描述

中值滤波器

中值滤波器的原理与均值滤波器非常相似,唯一的不同就是不会计算像素的平均值,而是将所有像素值排序,把最中间的像素值取出,赋值给核心像素。

在这里插入图片描述

例如上图就是中值滤波的计算过程。滤波核大小为3×3,核心像素值是 35,周围像素值都在110~150之间。将核内所有像素值升序排序,9个像素值排成一队,最中间位置为第5个位置,这个位置的像素值为131。不需再做任何计算,直接把131赋值给核心像素,其颜色就与周围颜色差别不大了,图像就变得平滑了。这就是中值滤波去噪的原理。

OpenCV将中值滤波器封装成了medianBlur()方法:

dst = cv2.medianBlur(src, ksize)
  • src: 被处理的图像。
  • ksize: 滤波核的边长 (宽度),必须是大于1的奇数,例如3、5、7等。方法会根据此边长自动创建一个正方形的滤波核。中值滤波器的 ksize 参数是边长,而其他滤波器的 ksize 参数通常为(高,宽)。
  • dst: 经过中值滤波处理之后的图像

实例2: 对花朵图像进行中值滤波操作

import cv2img = cv2.imread("3.png")  # 读取原图
dst1 = cv2.medianBlur(img, 3)  # 使用宽度为3的滤波核进行中值滤波
dst2 = cv2.medianBlur(img, 5)  # 使用宽度为5的滤波核进行中值滤波
dst3 = cv2.medianBlur(img, 9)  # 使用宽度为9的滤波核进行中值滤波
cv2.imshow("img", img)  # 显示原图
cv2.imshow("3", dst1)  # 显示滤波效果
cv2.imshow("5", dst2)
cv2.imshow("9", dst3)
cv2.waitKey()  # 按下任何键盘按键后
cv2.destroyAllWindows()  # 释放所有窗体

结果如下:
在这里插入图片描述
中值滤波处理的图像会比均值滤波处理的图像丢失更多细节。

高斯滤波器

高斯滤波也被称为高斯模糊、高斯平滑,是目前应用最广泛的平滑处理算法。高斯滤波可以很好地在降低图片噪声、细节层次的同时保留更多的图像信息,经过处理的图像会呈现“磨砂玻璃”的滤镜效果。

进行均值滤波处理时,核心周围每个像素的权重都是均等的,也就是每个像素都同样重要,所以计算平均值即可。但在高斯滤波中,越靠近核心的像素权重越大,越远离核心的像素权重越小。

高斯滤波的计算过程涉及到卷积运算,会有一个与滤波核大小相等的卷积核。本文不会深入介绍高斯函数以及高斯核的计算方式,仅以 3x3 的滤波核为例,简单地描述一下高斯滤波的计算过程。

卷积核中保存的值就是核所覆盖区域的权重值,其遵循图 9.16 的规律。卷积核中所有权重值相加的结果为 1。例如,3x3 的卷积核可以是如图 9.17 所示的值。随着核大小、标准差的变化,卷积核中的值也会发生较大变化,图 9.17 仅是一种最简单的情况。

在这里插入图片描述
进行高斯滤波的过程中,滤波核中像素会与卷积核进行卷积计算,最后将计算结果赋值给滤波核的核心像素。其计算过程如下所示:

在这里插入图片描述
在上图的计算过程中,滤波核中的每个像素值都会与卷积核对应位置的权重值相乘最后计算出9个值,让这9个值相加,再四舍五入取整,就得到了高斯滤波的计算结果。

OpenCV将高斯滤波器封装成了GaussianBlur()方法:

dst = cv2.GaussianBlur(src, ksize, sigmaX, sigmaY, borderType)
  • src: 被处理的图像
  • ksize: 滤波核的大小,宽高必须是奇数,例如(3,3)、(5,5) 等,
  • sigmaX: 卷积核水平方向的标准差。
  • sigmaY: 卷积核垂直方向的标准差。修改 sigmaX 或 sigmaY 的值都可以改变卷积材中的权重比例。如果不知道如何设计这两个参数值,就直接把这两个参数的值写成 0,方法就会根据滤波核的大小自动计算出合适的权重比例。
  • borderType:(可选)边界样式,建议使用默认值。
  • dst: 经过高斯滤波处理之后的图像。

实例3: 对花朵图像进行高斯滤波

import cv2img = cv2.imread("3.png") # 读取原图
dst1 = cv2.GaussianBlur(img, (5, 5), 0, 0) # 使用大小为5*5的滤波核进行高斯滤波
dst2 = cv2.GaussianBlur(img, (9, 9), 0, 0) # 使用大小为9*9的滤波核进行高斯滤波
dst3 = cv2.GaussianBlur(img, (15, 15), 0, 0) # 使用大小为15*15的滤波核进行高斯滤波
cv2.imshow("img", img) # 显示原图
cv2.imshow("5", dst1) # 显示滤波效果
cv2.imshow("9", dst2)
cv2.imshow("15", dst3)
cv2.waitKey() # 按下任何键盘按键后
cv2.destroyAllWindows() # 释放所有窗体

结果如下:

在这里插入图片描述

双边滤波器

不管是均值滤波、中值滤波还是高斯滤波,都会使整幅图像变得平滑,图像中的边界会变得模糊不清。双边滤波是一种在平滑处理过程中可以有效保护边界信息的滤波操作。

双边滤波器会自动判断滤波核处于“平坦”区域还是“边缘”区域:如果滤波核处于“平坦”区域,则会使用类似高斯滤波的算法进行滤波;如果滤波核处于“边缘”区域,则加大“边缘”像素的权重,尽可能地让这些像素值保持不变。

例如 ,图9.23是一幅黑白拼接图像,对这个图像进行高斯滤波,黑白交界处就会变得模糊不清,效果如图9.24所示;但如果对这幅图像进行双边滤波,黑白交界处的边界则可以很好地保留下来,效果如图9.25所示。

在这里插入图片描述
OpenCV将双边滤波器封装成了 bilateralFilter() 方法

dst = cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace, borderType)
  • src: 被处理的图像。
  • d: 以当前像素为中心的整个滤波区域的直径。如果是 d<0,则自动根据 sigmaSpace 参数计算得到。该值与保留的边缘信息数量成正比,与方法运行效率成反比。
  • sigmaColor: 参与计算的颜色范围,这个值是像素颜色值与周围颜色值的最大差值只有颜色值之差小于这个值时,周围的像素才会进行滤波计算。值为 255 时,表示所有色都参与计算。
  • sigmaSpace: 坐标空间的σ (sigma) 值,该值越大,参与计算的像素数量就越多
  • borderType:(可选)边界样式,建议默认。
  • dst: 经过双边滤波处理之后的图像。

实例4: 对一幅人脸图像进行”磨皮“

import cv2img = cv2.imread("girl.png")  # 读取原图
# 双边滤波,选取范围直径为7,颜色差为120
dst2 = cv2.bilateralFilter(img, 7, 120, 100)
cv2.imshow("img", img)  # 显示原图
cv2.imshow("bilateral", dst2)  # 显示双边滤波效果
cv2.waitKey()  # 按下任何键盘按键后
cv2.destroyAllWindows()  # 释放所有窗体

结果如下:

在这里插入图片描述

拉普拉斯高通滤波器

锐化又可以称作锐化滤镜,可以加深图像的边缘细节,以达到略微提高图像清晰度的目的,还能让图像中某些色彩更加鲜明。拉普拉斯高通滤波器就是实现锐化效果的一种关键技术。拉普拉斯高通滤波器使用的滤波核如下图所示:

在这里插入图片描述
使用这个核进行滤波计算 (同卷积计算) 后,中间的像素值会先乘以5再减去其上、下、左、右四个相邻的像素值。如果中心像素值与四周像素值差别很大,算法就会加深这种差别。从视觉上看,处理之后的图像边缘会呈现出明显的颗粒化。

OpenCV 把拉普拉斯高通滤波器封装成了 filter2D()方法

dst = cv2.filter2D(src, ddepth, kernel, anchor=None, delta=None, borderType=None)
  • src: 原始图像。
  • ddepth: 输出的图像深度
  • kernel: 滤波核。
  • anchor:(可选)核的锚点位置,默认为核的中心
  • delta:(可选)亮度,默认值为 0。
  • borderType:(可选)边界样式。
  • dst: 输出的图像。

实例5: 锐化图像

import cv2
import numpy as np# 拉普拉斯高通滤波的滤波核
def laplacian(img):# Laplacian高通滤波算子,5*中间像素值 - 上下左右四个像素值,让像素的梯度越来越大kernel = np.array([[0, -1, 0],[-1, 5, -1],[0, -1, 0]])dst = cv2.filter2D(img, cv2.CV_32F, kernel)  # 滤波dst = cv2.convertScaleAbs(dst)  # 取绝对值return dst# 加载图像
img = cv2.imread('pluto.jpg')
cv2.imshow('Original Image', img)dst1 = laplacian(img)
cv2.imshow('Laplace', dst1)
cv2.waitKey()
cv2.destroyAllWindows()

结果如下:

在这里插入图片描述

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

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

相关文章

剑指 Offer 44. 数字序列中某一位的数字(中等)

题目&#xff1a; class Solution { //本题单纯找规律&#xff0c;要注意通过n%digits来判断有几个位数为digits的数 public:int findNthDigit(int n) {long base 9, digits 1; //digits代表位数while(n-base*digits>0){ //该循环是为了确定目标数字所在…

Qt +VTK+Cmake 编译和环境配置(第二篇,中级篇, 重新编译)

1.下载VTK和Cmake 这里不介绍了。我的VTK 8.2.0 cmake 3.27.4 就是不服这编译器了。重新来一次 打开Cmake&#xff0c;把VTK源文件路径和目标路径设置一下&#xff08;目标路径自己设置&#xff0c;随意&#xff09; 点击Configure&#xff1a;。 点击下一步 选择好 Qt的gcc…

C++网狐服务器引入开源日志库spdlog

很多人对日志库不以为然&#xff0c;包括网狐这种十几年的公司都不重视&#xff0c;其实日志库记录的东西能在线上出问题时高效解决&#xff0c;特别是别人写的东西&#xff0c;人又走了&#xff0c;出了问题&#xff0c;还可以用日志分析快速解决。要是没有日志记录&#xff0…

基于SpringBoot2的后台业务管理系统

概述 SpringBoot-Plus 是一个适合大系统拆分成小系统的架构&#xff0c;java快速开发平台&#xff0c;或者是一个微服务系统。其中加入了Thymeleaf数据模板语言代替了之前的JSP页面方式。页面展示采用Layui前端框架&#xff0c;包含了用户管理&#xff0c;角色管理&#xff0c…

2.92-KFKG射频微波同轴连接器的电气特性

2.92mm连接器的名称是以其外导体内径命名的&#xff0c;采用空气介质工作频率高达40GHz,可与SMA和3.5mm连接器互换对插。优越的电性能、可靠的连接尤其适用于测试系统和武*装备&#xff0c;成为国际上应用最为广泛的毫米微波连接器之一。 电气特性&#xff1a; 特性阻抗&…

JavaScript基础语法04——输入输出语法

嗨&#xff0c;大家好&#xff0c;我是雷工。 今天学习JavaScript基础语法&#xff0c;输入输出语法&#xff0c;以下为学习笔记。 1、输出语法&#xff1a; 1.1、alert&#xff08;&#xff09; 作用&#xff1a;界面弹出警告对话框。 示例&#xff1a; <script>aler…

为什么要学习C++

操作系统历史 UINX操作系统诞生之初是用汇编语言编写的。随着UNIX的发展&#xff0c;汇编语言的开发效率成为一个瓶颈。寻找新的高效开发语言成为UNIX开发者需要解决的问题。当时BCPL语言成为了当时的选择之一。Ken Thomposn对BCPL进行简化得到了B语言。但是B语言不是直接生成…

如何使用Puppeteer进行新闻网站数据抓取和聚合

导语 Puppeteer是一个基于Node.js的库&#xff0c;它提供了一个高级的API来控制Chrome或Chromium浏览器。通过Puppeteer&#xff0c;我们可以实现各种自动化任务&#xff0c;如网页截图、PDF生成、表单填写、网络监控等。本文将介绍如何使用Puppeteer进行新闻网站数据抓取和聚…

PostgreSQL 查询语句大全

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

划分字母区间【贪心算法】

划分字母区间 给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段&#xff0c;同一字母最多出现在一个片段中。 注意&#xff0c;划分结果需要满足&#xff1a;将所有划分结果按顺序连接&#xff0c;得到的字符串仍然是 s 。返回一个表示每个字符串片段的长度的列表。…

python -- 实现路径的匹配,剔除掉指定路径,并保存路径

python – 实现路径的匹配&#xff0c;剔除掉指定路径&#xff0c;并保存路径 在处理nc数据时&#xff0c;由于部分数据在插值的过程中&#xff0c;存在过多的0值&#xff0c;使得在制作标签时该时刻的数据出现报错&#xff0c;但是对于一年的数据量来说&#xff0c;无关紧要&…

HTTP 协议

目录 ​编辑一、HTTP 协议是什么 二、抓包工具的使用 三、HTTP 请求 1、认识 URL 2、认识方法 3、认识请求 “报头” HOST &#xff1a; Content-Length 和 Content-Type​编辑 User-Agent Referer Cookie 四、HTTP 响应 1、认识状态码 2、通过 form 表单构造 H…

38、springboot为 spring mvc 提供的静态资源管理,覆盖和添加静态资源目录

springboot为 spring mvc 提供的静态资源管理 ★ Spring Boot为Spring MVC提供了默认的静态资源管理&#xff1a; ▲ 默认的四个静态资源目录&#xff1a; /META-INF/resources > /resources > /static > /public ▲ ResourceProperties.java类的源代码&#xff0…

iOS开发Swift-6-深色模式,类与对象,MVC模式,弹出框,闭包-趣味问答App

1.创建趣味问答App项目 2.创建一个问题文本&#xff0c;水平居中约束。 创建蓝、红两个按钮&#xff0c;放入Stack View中&#xff0c;给StackView水平居中约束&#xff0c;下边约束&#xff0c;设置两按钮间距为20. 设置进度条view与safe View关系为equal width。设置他们的比…

设计模式—外观模式(Facade)

目录 一、什么是外观模式&#xff1f; 二、外观模式具有什么优点吗&#xff1f; 三、外观模式具有什么缺点呢&#xff1f; 四、什么时候使用外观模式&#xff1f; 五、代码展示 ①、股民炒股代码 ②、投资基金代码 ③外观模式 思维导图 一、什么是外观模式&#xff1f;…

vue3实现日历日期选择(不使用任何插件,纯javaScript实现)

个人项目地址&#xff1a; SubTopH前端开发个人站 &#xff08;自己开发的前端功能和UI组件&#xff0c;一些有趣的小功能&#xff0c;感兴趣的伙伴可以访问&#xff0c;欢迎提出更好的想法&#xff0c;私信沟通&#xff0c;网站属于静态页面&#xff09; SubTopH前端开发个人…

中东 Shopify 如何使用 Bytebase 构建一站式数据库开发工作流

公司简介 Salla 是一家 2016 年成立&#xff0c;位于沙特麦加的自建站电商平台。 作为中东 Shopify&#xff0c;其最大的特点是支持阿拉伯语建站&#xff0c;并且提供更多适应中东地区特点的本地化服务。截止目前&#xff0c;已有 47,000 家店铺入驻 Salla&#xff0c;商品销售…

【前端demo】将二进制数转换为十进制数 原生实现

https://github.com/florinpop17/app-ideas 总结 文章目录 效果JavaScript实现进制转换原生代码遇到的问题 效果 二进制转换为十进制若输入为空或不是二进制&#xff0c;提示清空 https://codepen.io/karshey/pen/dywXZYQ JavaScript实现进制转换 parseInt parseInt(111,…

《Kali渗透基础》15. WEB 渗透

kali渗透 1&#xff1a;WEB 技术1.1&#xff1a;WEB 攻击面1.2&#xff1a;HTTP 协议基础1.3&#xff1a;AJAX1.4&#xff1a;WEB Service 2&#xff1a;扫描工具2.1&#xff1a;HTTrack2.2&#xff1a;Nikto2.3&#xff1a;Skipfish2.4&#xff1a;Arachni2.5&#xff1a;OWAS…

前端面试必备 | uni-app 篇(P1-15)

文章目录 1. 请简述一下uni-app的定义和特点。2. uni-app兼容哪些前端框架&#xff1f;请列举几个。3. 请简述一下uni-app的跨平台工作原理。4. 什么是条件编译&#xff1f;在uni-app中如何实现条件编译&#xff1f;5. uni-app中的页面生命周期有哪些&#xff1f;请简要介绍。6…