一、图像滤波
1、滤波简介
- 滤波实际上是信号处理得一个概念,图像可以看成一个二维信号,其中像素点的灰度值代表信号的强弱;
高频
:图像上变化剧烈的部分;低频
:图像灰度值变化缓慢,平坦的地方;- 根据图像高低频,设置高通和低通滤波器。高通滤波器可以检测变化尖锐,明显的地方,低通可以让图像变得平滑,消除噪声;
滤波作用:高通滤波器用于边缘检测,低通滤波器用于图像平滑去噪;
线性滤波
:方框滤波/均值滤波/高斯滤波;非线性滤波
:中值滤波/双边滤波;
2、线性滤波
- 领域算子:利用给定像素周围的像素值决定此像素的最终输出值的一种算子;
- 线性滤波:一种常用的领域算子,像素输出取决于输入像素的加权和。(卷积神经中的卷积操作)
(1)方框滤波-cv2.boxFilter(src,depth,ksize,normalize)
-
介绍
方框滤波(box Filter)被封装在一个名为boxFilter的函数中,即boxFilter 函数的作用是使用方框滤波器(box filter)来模糊一张图片
,从src输入,从dst输出; -
注意
normalize = true 与均值滤波相同
normalize = false 很容易发生溢出
-
函数
cv2.boxFilter(src,depth,ksize,normalize) -
参数说明
参数1:输入图像
参数2:目标图像深度
参数3:核大小
参数4:normalize属性
r = cv2.boxFilter(img, -1, (7, 7), normalize=1) # -1代表默认
d = cv2.boxFilter(img, -1, (3, 3), normalize=0)
![](https://i-blog.csdnimg.cn/blog_migrate/64d52c7e28bc6643b51181c292c253b2.png#pic_center)
(2)均值滤波-cv2.blur(src, ksize)
均值滤波是一种最简单的滤波处理,它取的是卷积核区域内元素的均值,用cv2.blur() 实现,如3×3的卷积核.
- 函数:cv2.blur(src, ksize)
- 参数说明:
参数1:输入原图
参数2:kernel的大小,一般为奇数
blur = cv2.blur(img, (3, 3))
![](https://i-blog.csdnimg.cn/blog_migrate/417c172ec48eab08f30422f7f39718b4.png#pic_center)
(3)高斯滤波-cv2.Guassianblur(src, ksize, std)
- 介绍
高斯滤波是一种线性平滑滤波,适用于消除高斯噪声
,广泛应用于图像处理的减噪
过程。高斯滤波的卷积核权重并不相同
,中间像素点权重最高,越远离中心的像素权重越小。其原理是一个2维高斯函数)
高斯滤波相比均值滤波效率要慢,但可以有效消除高斯噪声
,能保留更多的图像细节,所以经常被称为最有用的滤波器
。
![](https://i-blog.csdnimg.cn/blog_migrate/2b4b2d2ae3fb24d639f2edcd0f3de096.png#pic_center)
-
函数:
cv2.Guassianblur(src, ksize, std) -
参数说明:
参数1:输入原图
参数2:高斯核大小
参数3:标准差σ,平滑时,调整σ实际是在调整周围像素对当前像素的影响程度
,调大σ即提高了远处像素对中心像素的影响程度,滤波结果也就越平滑。
blur = cv2.GaussianBlur(img, (7, 7), 7)
![](https://i-blog.csdnimg.cn/blog_migrate/b253b4b0b6c2b41929d907c858551ce0.png#pic_center)
3、非线性滤波
(1)中值滤波-cv2.medianBlur(img,ksize)
-
介绍
中值滤波是一种非线性滤波,是用像素点邻域灰度值的中指代替该点的灰度值
,中值滤波可以去除椒盐噪声和斑点噪声
。 -
函数:
cv2.medianBlur(img,ksize) -
参数说明:
参数1:输入原图
参数2:核大小
median = cv2.medianBlur(img,9)
![](https://i-blog.csdnimg.cn/blog_migrate/0dd6ca0d0e7bca3928a2e30fc7547c20.png#pic_center)
(2)双边滤波-cv2.bilateralFilter(src=image, d, sigmaColor, sigmaSpace)
-
介绍
双边滤波是一种非线性的滤波方法,是结合图像的空间邻近度和像素值相似度的一种折中处理
,同时考虑空间与信息和灰度相似性
,达到保边去噪
的目的,具有简单、非迭代、局部处理的特点。 -
函数
cv2.bilateralFilter(src=image, d, sigmaColor, sigmaSpace) -
参数说明:
参数1:输入原图
参数2:像素的邻域直径
参数3:灰度值相似性高斯函数标准差
参数4:空间高斯函数标准差
关于2个sigma参数:
简单起见,可以令2个sigma的值相等; 如果他们很小(小于10),那么滤波器几乎没有什么效果; 如果他们很大(大于150),那么滤波器的效果会很强,使图像显得非常卡通化; 关于参数d:
过大的滤波器(d>5)执行效率低。 对于实时应用,建议取d=5; 对于需要过滤严重噪声的离线应用,可取d=9; d>0时,由d指定邻域直径; d<=0时,d会自动由sigmaSpace的值确定,且d与sigmaSpace成正比;
blur = cv2.bilateralFilter(img, -1, 15, 10)
![](https://i-blog.csdnimg.cn/blog_migrate/587b6c5f1dc5b86be61436841b8cb44f.png#pic_center)
4、图像滤波代码汇总
import cv2
import numpy as np
import matplotlib.pyplot as plt
# ----------------------------方框滤波----------------------------
flag = 0
# flag = 1
if flag:
img = cv2.imread('./girl2.png', cv2.IMREAD_UNCHANGED)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
r = cv2.boxFilter(img, -1, (7, 7), normalize=1) # -1代表默认
d = cv2.boxFilter(img, -1, (3, 3), normalize=0)
title = ['img', 'r', 'd']
images = [img, r, d]
for i in range(3):
plt.subplot(1, 3, i + 1)
plt.imshow(images[i])
plt.title(title[i])
plt.xticks([])
plt.yticks([])
plt.show()
# ----------------------------均值滤波----------------------------
flag = 0
# flag = 1
if flag:
img = cv2.imread('image/opencv.png')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
blur = cv2.blur(img, (3, 3))
plt.subplot(121), plt.imshow(img), plt.title("Original")
plt.subplot(122), plt.imshow(blur), plt.title("Blurred")
plt.xticks([]), plt.yticks([])
plt.show()
# ----------------------------高斯滤波----------------------------
flag = 0
# flag = 1
if flag:
img = cv2.imread('image/median.png')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
blur = cv2.GaussianBlur(img, (7, 7), 7)
plt.subplot(121), plt.imshow(img), plt.title("Original")
plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(blur), plt.title("Blurred")
plt.xticks([]), plt.yticks([])
plt.show()
# ----------------------------中值滤波----------------------------
flag = 0
# flag = 1
if flag:
img = cv2.imread('image/median.png')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
median = cv2.medianBlur(img, 9)
plt.subplot(121), plt.imshow(img), plt.title("Original")
plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(median), plt.title("Blurred")
plt.xticks([]), plt.yticks([])
plt.show()
# ----------------------------双边滤波----------------------------
flag = 0
flag = 1
if flag:
img = cv2.imread('image/bilateral.png')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
blur = cv2.bilateralFilter(img, -1, 15, 10)
plt.subplot(121), plt.imshow(img), plt.title("Original")
plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(blur), plt.title("Blurred")
plt.xticks([]), plt.yticks([])
plt.show()
二、图像增强
1、直方图均衡化-cv2.equalizeHist(img)
-
目的
直方图均衡化是将原图像通过某种变换,得到一幅灰度直方图为均匀分布的新图像的方法。 直方图均衡化方法的基本思想是对在图像中像素个数多的灰度级进行展宽,而对像素个数少的灰度级进行缩减。从而达到清 晰图像的目的。 -
函数
cv2.equalizeHist(img) -
参数1:待均衡化图像
-
步骤
统计直方图中每个灰度级出现的次数;
计算累计归一化直方图;
重新计算像素点的像素值
(1)灰度图直方图均值化
img = cv2.imread('image/dark.png', 0)
img_equal = cv2.equalizeHist(img)
![](https://i-blog.csdnimg.cn/blog_migrate/e3a9f55daad1200c640480a63dacbb11.png#pic_center)
(2)局部直方图均值化-cv2.createCLAHE
img = cv2.imread('image/dark.png', 0)
# 调用cv2.createCLAHE函数进行局部直方图均衡化
clahe = cv2.createCLAHE(clipLimit=2, tileGridSize=(30, 30))
cll = clahe.apply(img)
![](https://i-blog.csdnimg.cn/blog_migrate/374394ef0dc1d897b876fb6d5e621a99.png#pic_center)
(3)彩色图直方图均值化
(b, g, r) = cv2.split(img)
bH = cv2.equalizeHist(b)
gH = cv2.equalizeHist(g)
rH = cv2.equalizeHist(r)
result=cv2.merge((bH,gH,rH))
![](https://i-blog.csdnimg.cn/blog_migrate/a515d599672ed7e50be2521915555b72.png#pic_center)
2、Gamma变化
-
Gamma变换
Gamma变换是对输入图像灰度值进行的非线性操作
, 使输出图像灰度值与输入图像灰度值呈指数关系
. -
目的
Gamma变换就是用来图像增强
,其提升了暗部细节
, 通过非线性变换,让图像从暴光强度的线性响应变得更接近人眼感受的响应,即将漂白(相机曝光)或过 暗(曝光不足)的图片,进行矫正。
def adjust_gamma(img, gamma=1.0):
invGamma = 1.0 / gamma
table = []
for i in range(256):
table.append((i / 255.0) ** invGamma * 255)
table = np.array(table).astype('uint8')
return cv2.LUT(img, table) # 查找表
# gamma > 1 变亮;gamma < 1 变暗。
img_gamma = adjust_gamma(img, 1.5)
![](https://i-blog.csdnimg.cn/blog_migrate/9da5f3012882f036770231f2083aa7ed.png#pic_center)
3、图像增强代码汇总
import cv2
import numpy as np
import matplotlib.pyplot as plt
# ----------------------------灰度图直方图均值化----------------------------
flag = 0
# flag = 1
if flag:
img = cv2.imread('image/dark.png', 0)
img_equal = cv2.equalizeHist(img)
plt.subplot(1, 2, 1), plt.imshow(img), plt.title('original'), plt.xticks([]), plt.yticks([])
plt.subplot(1, 2, 2), plt.imshow(img_equal), plt.title('img_equal'), plt.xticks([]), plt.yticks([])
plt.show()
# ----------------------------局部直方图均值化----------------------------
flag = 0
# flag = 1
if flag:
img = cv2.imread('image/dark.png', 0)
# 调用cv2.createCLAHE函数进行局部直方图均衡化
clahe = cv2.createCLAHE(clipLimit=2, tileGridSize=(30, 30))
cll = clahe.apply(img)
plt.subplot(1, 2, 1), plt.imshow(img), plt.title('original'), plt.xticks([]), plt.yticks([])
plt.subplot(1, 2, 2), plt.imshow(cll), plt.title('img_equal'), plt.xticks([]), plt.yticks([])
plt.show()
# ----------------------------彩色图直方图均值化----------------------------
flag = 0
# flag = 1
if flag:
img = cv2.imread('image/dark1.jpg')
img_RGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
(b, g, r) = cv2.split(img)
bH = cv2.equalizeHist(b)
gH = cv2.equalizeHist(g)
rH = cv2.equalizeHist(r)
result = cv2.merge((rH, gH, bH))
plt.subplot(1, 2, 1), plt.imshow(img_RGB), plt.title('original'), plt.xticks([]), plt.yticks([])
plt.subplot(1, 2, 2), plt.imshow(result), plt.title('img_equal'), plt.xticks([]), plt.yticks([])
plt.show()
# ----------------------------Gamma变换----------------------------
flag = 0
flag = 1
if flag:
img = cv2.imread('./image/dark1.jpg')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
def adjust_gamma(img, gamma=1.0):
invGamma = 1.0 / gamma
table = []
for i in range(256):
table.append((i / 255.0) ** invGamma * 255)
table = np.array(table).astype('uint8')
return cv2.LUT(img, table) # 查找表
# gamma > 1 变亮;gamma < 1 变暗
img_gamma = adjust_gamma(img, 1.5)
plt.subplot(1, 2, 1), plt.imshow(img), plt.title('original'), plt.xticks([]), plt.yticks([])
plt.subplot(1, 2, 2), plt.imshow(img_gamma), plt.title('img_gamma'), plt.xticks([]), plt.yticks([])
plt.show()