Python 计算机视觉—— OpenCV进行图像平滑
Posted 一马归一码
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python 计算机视觉—— OpenCV进行图像平滑相关的知识,希望对你有一定的参考价值。
参考的一些文章以及论文我都会给大家分享出来 —— 链接就贴在原文,论文我上传到资源中去,大家可以免费下载学习,如果当天资源区找不到论文,那就等等,可能正在审核,审核完后就可以下载了。大家一起学习,一起进步!加油!!
目录
1. 图像平滑概述
此处参考论文:《几种图像平滑处理方法比较研究_关雪梅》
在处理和传输数字图像的过程中可能会受到不同的噪声的干扰,图像噪声会引起图像质量降低、图像变得模糊,使图像的特征被淹没、而通过除去噪声来达到图像增强的目的的操作被称为图像平滑处理;
一般来说,污染图像的噪声的来源主要有以下三种方式:
(1)第一种是在光电、电磁转换过程中产生的人为噪声
(2)第二种是大气层电(磁)暴、闪 电、电压、浪涌等引起的强脉冲性冲激噪声
(3)第三种是自然起伏性噪声,由物理量的不连续性或粒子性所引起
2. 均值滤波
(1)基本概念
假设被噪声污染的数字图像空间含有 N*N 个像素点,而这幅数字图像中每一个像素点值可以通过领域内(可以理解为使用矩形括起来)几个像素点的平均值计算出来,采用平滑图像处理方法就可以得到一幅新的图像,这个过程就被称为均值滤波
如果对于这种二维中的图像的平滑处理理解有点难度的话,可以参考我之前的一篇关于语音信号经过滑动平均滤除噪声的文章,应该理解起来轻松一点:M-point moving-average(M点滑动平均)Matlab 实现
(2)代码实现
图片添加噪声
首先肯定就是读取图像信息了:
"""
Author:XiaoMa
date:2021/10/28
"""
import cv2
import numpy as np
#读取图像信息
img0 = cv2.imread("E:\\From Zhihu\\For the desk\\cvnine0.jpg")
img1 = cv2.cvtColor(img0, cv2.COLOR_BGR2GRAY)
h, w = img0.shape[:2]
print(h, w)
cv2.namedWindow("W0")
cv2.imshow("W0", img0)
cv2.waitKey(delay = 0)
得到的图像信息如下:450 720
然后在原图中加入噪声:
使用 skimage.util.random_noise(image, mode=‘gaussian’, seed=None, clip=True, **kwargs)
image: 添加噪声的图像
mode: 添加的噪声类型(‘gaussian’ 高斯加性噪声
‘localvar’ 高斯加性噪声,每点具有特定的局部方差
‘poisson’ 泊松分布的噪声
'salt’盐噪声,随机用1替换像素。属于高灰度噪声
‘pepper’ 胡椒噪声,随机用0或-1替换像素,属于低灰度噪声
‘s&p’椒盐噪声,两种噪声同时出现,呈现出黑白杂点)
在这篇文章中我们就加入简单的高斯白噪声即可:
#给图像增加随机噪声
img2 = skimage.util.random_noise(img0, mode='gaussian')
cv2.namedWindow("W1")
cv2.imshow("W1", img2)
cv2.waitKey(delay = 0)
进行均值滤波
使用 cv2.blur() 函数
其中主要有两个参数,需要处理的图像和操作的核
#进行均值滤波
img3 = cv2.blur(img2, (6, 5))
cv2.namedWindow("W2")
cv2.imshow("W2", img3)
cv2.waitKey(delay = 0)
可以看出来滤波后的图像对于加了噪声的图像来说确实好了一点,但没办法达到原图那样的效果;按照我个人的理解,加入噪声就是使得一些像素点的像素值发生了改变,所以整个图像中的像素总值也发生了改变,即便求平均也会对原图产生影响,而且还把那些之前没有被改变的像素点也给影响了
3. 方框滤波
(1)基本概念
前面提到的均值滤波是对整个领域内的像素点求平均,再将平均值赋给目标像素点,但是方框滤波可以选择是否对像素值进行归一化,即可以将得到的像素点的总值赋给一个像素点
(2)代码实现
使用 cv2.boxFilter(src,ddepth,ksize,normalize)
src: 原图
ddepth: 目标图像深度
ksize: 核大小(和均值滤波类似)
normalize: 是否进行归一化,使用布尔值进行选择
若我们进行归一化处理,效果就会和均值滤波一样,所以在这里我们只演示不进行归一化操作:
#进行方框滤波
img4 = cv2.boxFilter(img2, ddepth = -1, ksize = (2, 2), normalize = False)
cv2.namedWindow("W3")
cv2.imshow("W3", img4)
cv2.waitKey(delay = 0)
在这里我们将核的大小设置为(2, 2),得出结果:
设置为(3, 3):
再次扩大为(5, 5):
整个图像变白了,这是为什么呢?
我们知道不进行归一化就是将方框内的所有像素点值赋给一个像素点,而它的值是有最大值255的,如果超过这个值像素点就溢出了,变成了白色;前面我们将核值设为(x, y),那么就有 x*y个像素点的值赋给一个像素点,超过某个界限肯定会导致所有的点都溢出了,整个图像自然也就变白了
4. 高斯滤波
(1)基本概念
均值滤波中我们是将方框中的每一个像素点的值都加起来求平均然后赋给原来的像素点,这样每一个像素点的权值都是1,但是在高斯滤波中,每一个像素点的权值以和该像素点的距离成高斯分布;即距离越远的像素点的权值越小
(2)代码实现
#进行高斯滤波
img5 = cv2.GaussianBlur(img2, (5, 5), 0) #参数分别为:原图、滤波器大小、标准差(标准差设置为0则会自动按照大小进行选择)
cv2.namedWindow("W4")
cv2.imshow("W4", img5)
cv2.waitKey(delay = 0)
上图中 W4 是高斯滤波的结果,W2 是均值滤波的结果(反正我本人看不出区别,哈哈哈哈)
5. 中值滤波
(1)基本概念
(2)代码实现
使用函数 cv2.medianblur()
此处参考:opencv学习(二十一)之中值滤波medianBlur
一般参数有:
输入图像:可规定图像深度,与滤波器大小有关
滤波器尺寸大小:必须为奇数
当滤波器大小为 3、5时,输入图像的深度为 CV_8U、CV_16U、CV_32F中的一个,当滤波器尺寸过大时,输入图像的深度只能是 CV_8U
CV_8U - 8-bit unsigned integers ( 0..255 )
CV_8S - 8-bit signed integers ( -128..127 )
CV_16U - 16-bit unsigned integers ( 0..65535 )
CV_16S - 16-bit signed integers ( -32768..32767 )
CV_32S - 32-bit signed integers ( -2147483648..2147483647 )
CV_32F - 32-bit floating-point numbers ( -FLT_MAX..FLT_MAX, INF, NAN )
CV_64F - 64-bit floating-point numbers ( -DBL_MAX..DBL_MAX, INF, NAN )
#进行中值滤波
img6 = cv2.imread("E:\\From Zhihu\\For the desk\\cvnine0_0.png") #读取的是添加了噪声的图像
img7 = cv2.medianBlur(np.uint8(img6), 9)
cv2.namedWindow("W5")
cv2.imshow("W5", img7)
cv2.waitKey(delay = 0)
个人认为并不见得效果有多好,通过调整滤波器尺寸可以进行多次尝试,来达到最优的一个图像平滑效果
6.结束语
这篇文章主要介绍了图像平滑中常用到的几种滤波方法,比如均值滤波、方框滤波、高斯滤波以及中值滤波,图像平滑的主要目的是减小图像中的一些噪声,对图像进行优化处理;当然图像平滑的代价就是失去一些图像中的细节变化,如果大家学过《信号与系统》就会知道,图像变换域中决定细节部分的是高频部分,所以通过图像平滑,图像肯定丢失了高频部分,这表明我们在本篇文章中构建的这几个滤波器本质上都属于低通滤波器,肯定会使图像变得模糊的,至于去噪和保留细节这两个对立的面的平衡自己通过调整参数进行寻找即可。在本篇文章中参考的文章链接我都粘贴上去了,论文既上传到资源部分也粘贴到了下面,需要的直接查看就可以了,加油!
7.参考论文
以上是关于Python 计算机视觉—— OpenCV进行图像平滑的主要内容,如果未能解决你的问题,请参考以下文章