图像平滑处理---OpenCV-Python开发指南(17)

简介: 图像平滑处理---OpenCV-Python开发指南(17)

什么是图像平滑处理


在尽量保留图像原有信息的情况下,过滤掉图像内部的噪声,这一过程我们称之为图像的平滑处理,所得到的图像称为平滑图像。


那么什么是图像的噪声呢?


图像的噪声就是图像中与周围像素点差异较大的像素点。噪声的处理就是将其更改为临近像素点的近似值,使图像更平滑。


图像平滑处理的噪声取值的方式有以下6种:


(1)均值滤波


(2)方框滤波


(3)高斯滤波


(4)中值滤波


(5)双边滤波


(6)2D卷积(自定义滤波)


均值滤波


均值滤波是指用当前像素点周围N*N个像素点的均值来代替当前像素值。使用该方法遍历处理图像内的每一个像素点,即可完成整幅图像的均值滤波。


在进行均值滤波处理时,我们需要考虑对周围多少个像素点取平均值。通常情况下,我们会以当前像素点为中心,对行数和列数相等的一块区域内的所有像素点取平均值。


但是边缘像素点可能不能这样做,毕竟比如左上角的像素点是没有左上像素点的,这个时候我们常常会取图像内存在的周围邻域点的平均值。


OpenCV中,它给我们提供的均值滤波函数为cv2.blur(),其完整定义如下:

def blur(src, ksize, dst=None, anchor=None, borderType=None): 

src:原始图像


kszie:滤波中心的大小,也就是取平均值的周围像素点的高度与宽度,比如(5,5),就是取5*5邻域像素点均值作为结果。


anchor:锚点,其默认值为(-1,1),表示当前计算均值的点位于核的中心点位置。一般使用默认值即可。


borderType:边界样式,该值决定了以何种方式处理边界,一般情况下不需要更改。


了解了该函数的定义,下面我们简单的来完成一个去噪图像,具体代码如下所示:

import cv2
img = cv2.imread("5.jpg")
result_5img = cv2.blur(img, (5, 5))
result_30img= cv2.blur(img, (30, 30))
cv2.imshow("img", img)
cv2.imshow("result_5img", result_5img)
cv2.imshow("result_30img", result_30img)
cv2.waitKey()
cv2.destroyAllWindows()


运行之后,效果如下所示:

从上图可以看出来,使用(5,5)卷积进行均值滤波处理后图像虽然模糊,但还可以辨认。而使用(30,30)卷积进行均值滤波,图像失真非常严重。


所以,我们可以得出来,卷积核越大,去噪效果越好,花费的时间越长,同时图像失真也越严重。而实际的处理中,我们需要在失真与去噪之间取得平衡,选取合适的卷积大小。


方框滤波


方框滤波与均值滤波的不同之处在于,方框滤波不会计算像素均值,它可以自由选择是否对均值滤波的结果进行归一化,即可以自由选择滤波结果是邻域像素值之和的平均值,还是邻域像素值之和。


在OpenCV中,它提供cv2.boxFilter()函数来实现方框滤波,其完整定义如下:

def boxFilter(src, ddepth, ksize, dst=None, anchor=None, normalize=None, borderType=None): 

src:原始图像


ddepth:处理结果图像的图像深度,一般使用-1表示与原图像使用相同的图像深度


ksize:滤波核心的大小


normalize:是否在滤波时进行归一化处理。当它为1时,表示要进行归一化处理,也就是邻域像素值的和除以面积,比如(3,3),公式如下:


当它为0时,表示不需要进行归一化处理,直接使用邻域像素值的和。


下面,我们来用程序分别实现归一化与不归一化的效果,代码如下:

import cv2
img = cv2.imread("5.jpg")
result1 = cv2.boxFilter(img, -1, (5, 5))
result2 = cv2.boxFilter(img, -1, (30, 30))
result3 = cv2.boxFilter(img, -1, (2, 2),normalize=0)
cv2.imshow("img", img)
cv2.imshow("result1", result1)
cv2.imshow("result2", result2)
cv2.imshow("result3", result3)
cv2.waitKey()
cv2.destroyAllWindows()


运行之后,显示的效果如下所示:

可以看到,左下角不需要归一化处理,这里只取(2,2),如果你取大了,可以试试。因为范围大了,和一般都会大于255,那么就会造成图像全是白色。


高斯滤波


在进行均值滤波与方框滤波时,其邻域内每个像素的权重是相等的。而高斯滤波会将中心点的权重加大,远离中心点的权重减小,以此来计算邻域内各个像素值不同权重的和。


在OpenCV中,它给我们提供cv2.GaussianBlur()函数进行高斯滤波,其完整定义如下:

def GaussianBlur(src, ksize, sigmaX, dst=None, sigmaY=None, borderType=None):

src:原始图像


ksize:滤波核的大小


sigmaX:卷积和在水平方向上(X轴方向)的标准差,其控制的是权重比例


sigmaY:卷积和在垂直方向上(Y轴方向)的标准差,也是控制的是权重比例。如果它为0,只采用sigmaX的值,如果sigmaX与sigmaY都是0,则通过ksize.width和ksize.height计算得到(可选参数)


下面,我们来使用高斯滤波看看效果,代码如下所示:

import cv2
img = cv2.imread("5.jpg")
result = cv2.GaussianBlur(img, (3, 3), 0, 0)
cv2.imshow("img", img)
cv2.imshow("result", result)
cv2.waitKey()
cv2.destroyAllWindows()


运行之后,效果如下所示:



中值滤波


中值滤波与前面的三种滤波都不同,它不在采用加权求均值的方式计算滤波结果,而是用邻域内所有像素值的中间值来代替当前像素点的像素值。


简单点说,就是取当前像素点及其周围临近像素点的像素值,将这些值进行排序后,取中间位置的像素值作为当前位置的像素值。


在OpenCV中,它提供给我们cv2.medianBlur()函数来进行中值滤波,其完整定义如下:

def medianBlur(src, ksize, dst=None): 

src:原始图像


kszie:滤波核的大小


参数就两个,下面我们来用代码测试一下:

import cv2
img = cv2.imread("5.jpg")
result = cv2.medianBlur(img, 3)
cv2.imshow("img", img)
cv2.imshow("result", result)
cv2.waitKey()
cv2.destroyAllWindows()


运行之后,显示效果如下:


可以看到,这里我们将脸上的红点去掉了。需要特别注意的是,滤波核的大小必须是奇数,矩阵中心点向外衍生必然是奇数,不信可以随便矩阵取一点试试。


双边滤波


双边滤波是综合考虑空间信息和色彩信息的滤波方式,在滤波的过程中能够有效地保护图像内的边缘信息。


前面滤波方式基本只考虑了空间的权重信息,这种情况计算起来比较方便,但是边缘信息的处理上存在较大问题。而双边滤波在处理边缘时,与当前点色彩相近的像素点给与较大的权重值,而与当前像素点色彩差别大的会给较小的权重,这样就保护了边缘信息。


简单点概括,双边滤波在计算某一个像素点的新值时,不仅考虑距离信息,还考虑色彩信息。双边滤波即能有效地去除噪声,又能很好地保护边缘信息。


在OpenCV中,它给我们提供cv2.bilateralFilter()函数来实现,其完整定义如下:

def bilateralFilter(src, d, sigmaColor, sigmaSpace, dst=None, borderType=None):

src:原始图像


d:在滤波时选取的空间距离参数,这里表示以当前像素点为中心点的直径。如果该值为非正数,则会从参数sigmaSpace计算得到。如果滤波空间较大,比如d>5,则速度较慢。因此,在实际的应用中,推荐d=5。对于噪声较大的离线滤波,可以选择d=9。


sigmaColor:在滤波处理时,选择的颜色范围,该值决定了周围哪些像素点能够参与到滤波中来。与当前像素点的像素值差值小于sigmaColor的像素点,能够参与到当前的滤波中。该值越大,就说明周围有越多的像素点可以参与到运算中。该值为0时,滤波失去意义;该值为255,指定直径内的所有点都能够参与运算。


sigmaSpace:坐标空间中的sigma值。它的值越大,说明有越多的点能够参与到滤波计算中来。当d>0时,无论sigmaSpace的值如何,d都指定邻域大小;否则,d域sigmaSpace的值成比例。


为了简单起见,博主这里将两个sigmaColor与sigmaSpace值设置为相同的。如果它们的值比较小,比如小于10,滤波的效果不太明显;如果它们的值较大,比如大于150,则滤波效果会比较明显。


代码如下所示:

import cv2
img = cv2.imread("5.jpg")
result = cv2.bilateralFilter(img,25,50,50)
cv2.imshow("img", img)
cv2.imshow("result", result)
cv2.waitKey()
cv2.destroyAllWindows()


运行之后,显示效果如下所示:


2D卷积


在OpenCV中,除了提供上面这些常用的滤波方式之外,还允许用户自定义卷积核实现卷积操作。这个函数是cv2.Filter2D(),其完整定义如下:

def filter2D(src, ddepth, kernel, dst=None, anchor=None, delta=None, borderType=None): 

src:原始图像


ddepth:处理结果图像的深度,-1与原图像一致。


kernel:卷积核,是一个单通道数组。如果想在处理彩色图像时,让每个通道使用不同的核,则必须将彩色图像分解后使用不同的核完成。


delta:修正值,可选参数。如果该值存在,会在基础滤波的结果上加上该值作为最终的滤波结果。


下面,我们来使用这个函数看看效果,具体代码如下所示:

import cv2
import numpy as np
img = cv2.imread("5.jpg")
kernel = np.ones((9,9), np.float32) / 81
result = cv2.filter2D(img, -1, kernel)
cv2.imshow("img", img)
cv2.imshow("result", result)
cv2.waitKey()
cv2.destroyAllWindows()


运行之后,效果如下所示:

相关文章
|
11天前
|
计算机视觉
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
这篇文章详细介绍了OpenCV库中的图像二值化函数`cv2.threshold`,包括二值化的概念、常见的阈值类型、函数的参数说明以及通过代码实例展示了如何应用该函数进行图像二值化处理,并展示了运行结果。
107 0
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
|
1月前
|
机器学习/深度学习 算法 TensorFlow
动物识别系统Python+卷积神经网络算法+TensorFlow+人工智能+图像识别+计算机毕业设计项目
动物识别系统。本项目以Python作为主要编程语言,并基于TensorFlow搭建ResNet50卷积神经网络算法模型,通过收集4种常见的动物图像数据集(猫、狗、鸡、马)然后进行模型训练,得到一个识别精度较高的模型文件,然后保存为本地格式的H5格式文件。再基于Django开发Web网页端操作界面,实现用户上传一张动物图片,识别其名称。
73 1
动物识别系统Python+卷积神经网络算法+TensorFlow+人工智能+图像识别+计算机毕业设计项目
|
1月前
|
算法 计算机视觉
opencv图像形态学
图像形态学是一种基于数学形态学的图像处理技术,它主要用于分析和修改图像的形状和结构。
39 4
|
18天前
|
存储 JSON API
Python| 如何使用 DALL·E 和 OpenAI API 生成图像(1)
Python| 如何使用 DALL·E 和 OpenAI API 生成图像(1)
24 7
Python| 如何使用 DALL·E 和 OpenAI API 生成图像(1)
|
1月前
|
机器学习/深度学习 人工智能 算法
植物病害识别系统Python+卷积神经网络算法+图像识别+人工智能项目+深度学习项目+计算机课设项目+Django网页界面
植物病害识别系统。本系统使用Python作为主要编程语言,通过收集水稻常见的四种叶片病害图片('细菌性叶枯病', '稻瘟病', '褐斑病', '稻瘟条纹病毒病')作为后面模型训练用到的数据集。然后使用TensorFlow搭建卷积神经网络算法模型,并进行多轮迭代训练,最后得到一个识别精度较高的算法模型,然后将其保存为h5格式的本地模型文件。再使用Django搭建Web网页平台操作界面,实现用户上传一张测试图片识别其名称。
96 22
植物病害识别系统Python+卷积神经网络算法+图像识别+人工智能项目+深度学习项目+计算机课设项目+Django网页界面
|
1月前
|
机器学习/深度学习 人工智能 算法
鸟类识别系统Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+ResNet50算法模型+图像识别
鸟类识别系统。本系统采用Python作为主要开发语言,通过使用加利福利亚大学开源的200种鸟类图像作为数据集。使用TensorFlow搭建ResNet50卷积神经网络算法模型,然后进行模型的迭代训练,得到一个识别精度较高的模型,然后在保存为本地的H5格式文件。在使用Django开发Web网页端操作界面,实现用户上传一张鸟类图像,识别其名称。
86 12
鸟类识别系统Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+ResNet50算法模型+图像识别
|
29天前
|
存储 计算机视觉
Opencv的基本操作(一)图像的读取显示存储及几何图形的绘制
本文介绍了使用OpenCV进行图像读取、显示和存储的基本操作,以及如何绘制直线、圆形、矩形和文本等几何图形的方法。
Opencv的基本操作(一)图像的读取显示存储及几何图形的绘制
|
13天前
|
JSON API 数据格式
Python| 如何使用 DALL·E 和 OpenAI API 生成图像(2)
Python| 如何使用 DALL·E 和 OpenAI API 生成图像(2)
34 0
Python| 如何使用 DALL·E 和 OpenAI API 生成图像(2)
|
2月前
|
机器学习/深度学习 人工智能 TensorFlow
利用Python和TensorFlow实现简单图像识别
【8月更文挑战第31天】在这篇文章中,我们将一起踏上一段探索人工智能世界的奇妙之旅。正如甘地所言:“你必须成为你希望在世界上看到的改变。” 通过实践,我们不仅将学习如何使用Python和TensorFlow构建一个简单的图像识别模型,而且还将探索如何通过这个模型理解世界。文章以通俗易懂的方式,逐步引导读者从基础到高级,体验从编码到识别的整个过程,让每个人都能在AI的世界中看到自己的倒影。
|
2月前
|
机器学习/深度学习 自动驾驶 计算机视觉
使用Python实现简单的图像识别
【8月更文挑战第31天】在本文中,我们将探索如何使用Python语言和其强大的库来创建一个简单的图像识别系统。通过逐步指导,我们将了解如何准备图像数据,选择和训练模型,以及评估我们的成果。无论你是机器学习的初学者还是希望扩展你的技能集,这篇文章都将为你提供实用的知识和代码示例。