opencv-python常用函数解析及参数介绍(三)——图像滤波
创始人
2024-05-03 16:49:06
0

图像滤波

  • 前言
  • 1.制作噪声
    • 生成椒盐噪声
    • 生成高斯噪声
  • 2.滤波
    • 均值滤波
    • 框滤波
    • 高斯滤波
    • 中值滤波
  • 总结

前言

很多时候我们能拿到的图片并不是十分干净,有时会有一些噪声,这时我们就应该采用滤波的方式对他进行处理,本文将在一张干净的图片上生成噪声并进行滤波操作。

1.制作噪声

假设我们有这样一张名为kl.jpg的图片
在这里插入图片描述
读入

img=cv2.imread('kl.png')

接下来我们要在这张图片上制作噪声来模拟有噪声情况下的图片,以供学习滤波
为了显示方便我们先定义一个显示图像的函数

def cv_show(img,name):cv2.imshow(name,img)cv2.waitKey()cv2.destroyAllWindows()

生成椒盐噪声

椒盐噪声是出现在随机位置、噪点深度基本固定的噪声,下面代码的原理就是随机选择图像上的点并将他们替换成全0或者全255

import randomdef make_random_noise(img, rate=0.01):imgInfo = img.shapeheight = imgInfo[0] - 1 # 防止越界width = imgInfo[1] - 1random_noise = img.copy()temp = int(img.shape[0] * img.shape[1] * rate) # 噪声点的个数占总像素点的ratefor i in range(0, temp):if random.randint(1, temp) % 2 == 0:random_noise[random.randint(0, height), random.randint(0, width)] = (255, 255, 255)if random.randint(1, temp) % 2 != 0:random_noise[random.randint(0, height), random.randint(0, width)] = (0, 0, 0)return random_noiserandom_noise = make_random_noise(img)
cv_show(random_noise, 'random noise')

效果如下
在这里插入图片描述

生成高斯噪声

高斯噪声与椒盐噪声相反,是几乎每个点上都出现噪声、噪点深度随机的噪声

def make_gauss_noise(img, mean, var):image = np.array(img / 255, dtype=float)  # 将原始图像的像素值进行归一化,除以255使得像素值在0-1之间noise = np.random.normal(mean, var ** 0.5, image.shape)  # 创建一个均值为mean,方差为var呈高斯分布的图像矩阵out = image + noise  # 将噪声和原始图像进行相加得到加噪后的图像if out.min() < 0:low_clip = -1.else:low_clip = 0.resultImg = np.clip(out, low_clip, 1.0)  # clip函数将元素的大小限制在了low_clip和1之间了,小于的用low_clip代替,大于1的用1代替resultImg = np.uint8(resultImg * 255)  # 解除归一化,乘以255将加噪后的图像的像素值恢复return resultImggauss_noise = make_gauss_noise(img, 0, 0.02)
cv_show(gauss_noise, "gauss_noise")

在这里插入图片描述

2.滤波

均值滤波

均值滤波实际上就是简单的平均卷积操作,即每个滤波后的像素点是有噪声的图像中对应位置的卷积核内的像素点均值

我们使用cv2.blur函数可以进行均值滤波,参数需要图像和卷积核大小

random_blur = cv2.blur(random_noise, (7, 7))
gauss_blur = cv2.blur(gauss_noise, (7, 7))
cv2.imshow('random gauss blur', np.hstack([random_blur, gauss_blur]))
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述
左侧是椒盐噪声下均值滤波的效果,右侧是高斯滤波下的滤波效果,可以看到均值滤波能较好的解决椒盐噪声

框滤波

使用cv2.boxFilter可以实现框滤波,框滤波基本和均值一样,可以选择归一化,一般不进行归一化容易越界,所以尽量还是使用均值cv2.blur滤波比较好

box_1 = cv2.boxFilter(random_noise,-1,(7,7), normalize=True) 
box_2 = cv2.boxFilter(random_noise,-1,(7,7), normalize=False)  cv2.imshow('box', np.hstack([box_1, box_2]))
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述
左侧归一化,右侧没有归一化

高斯滤波

高斯模糊的卷积核里的数值是满足高斯分布,相当于更重视中间的,cv2.GaussianBlur可以实现高斯滤波,下面看一下高斯滤波在随机噪声和高斯噪声的效果

gauss_1 = cv2.GaussianBlur(random_noise, (9, 9), 1)  
gauss_2 = cv2.GaussianBlur(gauss_noise, (9, 9), 1)
cv2.imshow('gaussian', np.hstack([gauss_1, gauss_2]))
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述
可以看到高斯滤波在椒盐噪声上效果一般,但是在高斯噪声上会比均值滤波稍好一些

中值滤波

相当于用中值代替均值滤波中的均值

median_1 = cv2.medianBlur(random_noise, 5)  # 中值滤波
median_2 = cv2.medianBlur(gauss_noise, 5)
cv2.imshow('median', np.hstack([median_1, median_2]))
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述
由于噪声很难正好赶上是图像的中值,所以在很多情况下中值滤波能得到很好的效果

总结

均值滤波适合椒盐噪声,高斯滤波适合高斯噪声,两种噪声都要尝试一下中值滤波通过比较得出较好的图片

相关内容

热门资讯

前端-session、jwt 目录:   (1)session (2&#x...
linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
nodejs:本地安装nvm实... 一、背景-使用不同版本node的原因 vue3+ts、nuxt3版本,node...
JAVA集合知识整理 Java集合知识整理 HashMap相关 HashMap的底层数据结构:jdk1.8之...
无刷直流电机介绍及单片机控制实... 无刷直流电机介绍及单片机控制实例前言基本概念优势与劣势使用寿命基本结构使用单片机控制实例电子调速器&...
fwdiary(2) dp2 1.传纸条  AcWing 275. 传纸条 - AcWing 走两条路,走一条最大的...
常用的DOS命令 常用的DOS命令 DOS(Disk Operating System,磁...
<C++> 类和对象(下) 1.const成员函数将const修饰的“成员函数”称之为const成员函数,cons...