前言:Hello大家好,我是小哥谈。在尽量保留原图像信息的情况下,去除图像内噪声、降低细节层次信息等一系列过程,被叫做图像的平滑处理(或者叫图像的模糊处理)。实现平滑处理最常用的工具就是滤波器。通过调节滤波器的参数,可以控制图像的平滑程度。OpenCV提供了种类丰富的滤波器,每种滤波器使用的算法均不相同,但都能对图像中的像素值进行微调,让图像呈现平滑效果。本节将介绍均值滤波器、中值滤波器、高斯滤波器和双边滤波器的使用方法。🌈
前期回顾:
史上最全OpenCV常用方法及使用说明汇总,建议收藏!
OpenCV基础知识(1)— OpenCV概述
OpenCV基础知识(2)— 图像处理的基本操作
OpenCV基础知识(3)— 图像数字化基础(像素、色彩空间)
OpenCV基础知识(4)— 绘制图形
OpenCV基础知识(5)— 几何变换
目录
🚀1.均值滤波器
🚀2.中值滤波器
🚀3.高斯滤波器
🚀4.双边滤波器
🚀5.总结
🚀1.均值滤波器
图像中可能会出现这样一种像素:该像素与周围像素的差别非常大,导致从视觉上就能看出该像素无法与周围像素组成可识别的图像信息,降低了整个图像的质量。这种“格格不入”的像素就被称为图像的噪声。如果图像中的噪声都是随机的纯黑像素或者纯白像素,这样的噪声也被称为“椒盐噪声”或“盐噪声”。
以一个像素为核心,核心周围像素可以组成一个n行n列(简称 n×n)的矩阵,这样的矩阵结构在滤波操作中被称为“滤波核”。矩阵的行列数决定了滤波核的大小,例如下图所示,滤波核大小为3×3,包含9个像素。🌴
均值滤波器(也被称为低通滤波器)可以把图像中的每一个像素都当做滤波核的核心,然后计算出核内所有像素的平均值,最后让核心像素值等于这个平均值。
OpenCV将均值滤波器封装成了blur()方法,其语法如下:
dst = cv2.blur(src,ksize,anchor,borderType)
参数说明:
src:被处理的图像
ksize:滤波核大小,其格式为(高度,宽度),建议使用如(3,3)、(5,5)等宽高相等的奇数边长。滤波核越大,处理之后的图像就越模糊。
anchor:可选参数,滤波核的锚点,建议采用默认值,方法可以自动计算锚点。
boderType:可选参数,边界样式,建议采用默认值。
返回值说明:
dst:经过均值滤波处理之后的图像
案例:
使用大小为9×9的滤波核对图像进行均值滤波操作,代码如下:
import cv2
img = cv2.imread("1.webp") # 读取原图
dst1 = cv2.blur(img, (9, 9)) # 使用大小为9*9的滤波核进行均值滤波
cv2.imshow("img", img) # 显示原图
cv2.imshow("9*9", dst1)
cv2.waitKey() # 按下任何键盘按键后
cv2.destroyAllWindows() # 释放所有窗体
运行效果如图所示:
说明:♨️♨️♨️
滤波核越大,处理之后的图像就越模糊。
🚀2.中值滤波器
中值滤波器的原理与均值滤波器非常相似,唯一的不同就是不会计算像素的平均值,而是将所有像素值进行排序,把最中间的像素值取出,赋值给核心像素。
OpenCV将中值滤波器封装成了medianBlur()方法,其语法如下:
dst = cv2.medianBlur(src,ksize)
参数说明:
src:被处理的图像
ksize:滤波核的边长,必须是大于1的奇数,例如3、5、7等。方法会根据此边长自动创建一个正方形的滤波核。
返回值说明:
dst:经过中值滤波处理之后的图像
案例:
使用边长为9的滤波核对图像进行中值滤波操作,代码如下:
import cv2
img = cv2.imread("1.webp") # 读取原图
dst1 = cv2.medianBlur(img, 9) # 使用宽度为9的滤波核进行中值滤波
cv2.imshow("img", img) # 显示原图
cv2.imshow("9", dst1) # 显示滤波效果
cv2.waitKey() # 按下任何键盘按键后
cv2.destroyAllWindows() # 释放所有窗体
运行效果如图所示:
说明:♨️♨️♨️
1.中值滤波器语法中的ksize参数是边长,而其它滤波器的ksize参数通常是(高,宽) 。
2.滤波核的边长越长,处理之后的图像就越模糊。
3.中值滤波处理的图像会比均值滤波处理的图像丢失更多细节。
🚀3.高斯滤波器
高斯滤波也被称为高斯模糊、高斯平滑,是目前应用最广泛的平滑处理算法。高斯滤波可以很好地在降低图片噪声、细节层次的同时保留更多的图像信息,经过处理的图像会呈现“磨砂玻璃”的滤镜效果。
OpenCV将高斯滤波器封装成了GaussianBlur()方法,其语法如下:
dst = cv2.GaussianBlur(src,ksize,sihmaX,sigmaY,borderType)
参数说明:
src:被处理的图像
ksize:滤波核的大小,宽、高必须是奇数,例如(3,3)、(5,5)等。
sigmaX:卷积核水平方向的标准差
sigmaY:卷积核垂直方向的标准差。修改 sigmaX 或 sigmaY 的值都可以改变卷积核中的权重比例。如果不知道如何设计这两个参数值,就直接把这两个参数的值写成0,方法就会根据滤波核的大小自动计算出合适的权重比例。
boderType:可选参数,边界样式,建议使用默认值。
返回值说明:
dst:经过高斯滤波处理之后的图像
案例:
使用9×9的滤波核对图像进行高斯滤波操作,水平方向和垂直方向的标准差参数值全部为0,代码如下:
import cv2
img = cv2.imread("amygdalus triloba.jpg") # 读取原图
dst1 = cv2.GaussianBlur(img, (9, 9), 0, 0) # 使用大小为9*9的滤波核进行高斯滤波
cv2.imshow("img", img) # 显示原图
cv2.imshow("9", dst1) # 显示滤波效果
cv2.waitKey() # 按下任何键盘按键后
cv2.destroyAllWindows() # 释放所有窗体
运行效果如图所示:
说明:♨️♨️♨️
和均值滤波、中值滤波处理的图像相比,高斯滤波处理的图像更加平滑,保留的图像信息更多,更容易辨认。
🚀4.双边滤波器
不管是均值滤波、中值滤波还是高斯滤波,都会使整幅图像变得平滑,图像中的边界会变得模糊不清。双边滤波是一种在平滑处理过程中可以有效保护边界信息的滤波操作。
双边滤波器会自动判断滤波核处于“平坦”区域还是“边缘”区域:如果滤波核处于“平坦”区域,则会使用类似高斯滤波的算法进行滤波;如果滤波核处于“边缘”区域,则加大“边缘”像素的权重,尽可能让这些像素值保持不变。
OpenCV将双边滤波器封装成了bilateralFilter()方法,其语法如下:
dst = cv2.bilateralFilter(src,d,sigmaColor,sigmaSpace,borderType)
参数说明:
src:被处理的图像
d:以当前像素为中心的整个滤波区域的直径。如果是d<0,则自动根据 sigmaSpace 参数计算得到。该值与保留的边缘信息数量成正比,与方法运行效率成反比。
sigmaColor:参与计算的颜色范围,这个值是像素颜色值与周围颜色值的最大差值,只有颜色值之差小于这个值时,周围的像素才会进行滤波计算。值为255时,表示所有颜色都参与计算。
sigmaSpace:坐标空间的σ(sigma)值,该值越大,参与计算的像素数量就越多。
borderType:可选参数,边界样式,建议默认。
返回值说明:
dst:经过双边滤波处理之后的图像
案例:
使用大小为(15,15)的滤波核对图像进行高斯滤波处理,同样使用15作为范围直径对图像进行双边滤波处理,观察两种滤波处理之后的图像边缘有什么差别,代码如下:
import cv2
img = cv2.imread("1.webp") # 读取原图
dst1 = cv2.GaussianBlur(img, (15, 15), 0, 0) # 使用大小为15*15的滤波核进行高斯滤波
# 双边滤波,选取范围直径为15,颜色差为120
dst2 = cv2.bilateralFilter(img, 15, 120, 100)
cv2.imshow("img", img) # 显示原图
cv2.imshow("Gauss", dst1) # 显示高斯滤波效果
cv2.imshow("bilateral", dst2) # 显示双边滤波效果
cv2.waitKey() # 按下任何键盘按键后
cv2.destroyAllWindows() # 释放所有窗体
运行效果如图所示:
说明:♨️♨️♨️
由上面三张图对比可得,高斯滤波模糊了整个画面,但双边滤波保留了较清晰的边缘信息。
🚀5.总结
均值滤波器:中央像素取平均值,效果像马赛克。
中值滤波器:中央像素取排序后的中间值,效果像水彩画。
高斯滤波器:按照卷积核权重计算中央像素值,毛玻璃效果。
双边滤波器:保留边缘信息,边缘清晰。