OpenCV-Python实现图像平滑处理操作


Posted in Python onJune 08, 2021

什么是图像平滑处理

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

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

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

图像平滑处理的噪声取值的方式有以下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()

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

OpenCV-Python实现图像平滑处理操作

从上图可以看出来,使用(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),公式如下:

OpenCV-Python实现图像平滑处理操作

当它为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()

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

OpenCV-Python实现图像平滑处理操作

可以看到,左下角不需要归一化处理,这里只取(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-Python实现图像平滑处理操作

中值滤波

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

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

在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-Python实现图像平滑处理操作

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

双边滤波

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

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

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

在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()

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

OpenCV-Python实现图像平滑处理操作

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()

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

OpenCV-Python实现图像平滑处理操作

到此这篇关于OpenCV-Python实现图像平滑处理操作的文章就介绍到这了,更多相关OpenCV 图像平滑处理内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python字符串详细介绍
May 09 Python
Python读取YUV文件,并显示的方法
Dec 04 Python
Python闭包和装饰器用法实例详解
May 22 Python
python文本数据处理学习笔记详解
Jun 17 Python
Tensorflow实现酸奶销量预测分析
Jul 19 Python
Django Rest framework权限的详细用法
Jul 25 Python
python中hasattr()、getattr()、setattr()函数的使用
Aug 16 Python
Python any()函数的使用方法
Oct 28 Python
Python 必须了解的5种高级特征
Sep 10 Python
Ubuntu权限不足无法创建文件夹解决方案
Nov 14 Python
Django利用AJAX技术实现博文实时搜索
May 06 Python
Python使用pyecharts控件绘制图表
Jun 05 Python
OpenCV-Python模板匹配人眼的实例
健身房被搭讪?用python写了个小米计时器助人为乐
解决pycharm安装scrapy DLL load failed:找不到指定的程序的问题
OpenCV-Python实现轮廓拟合
python图像处理基本操作总结(PIL库、Matplotlib及Numpy)
Django drf请求模块源码解析
Python中OpenCV实现查找轮廓的实例
You might like
用PHP连接Oracle for NT 远程数据库
2006/10/09 PHP
php程序的国际化实现方法(利用gettext)
2011/08/14 PHP
在windows平台上构建自己的PHP实现方法(仅适用于php5.2)
2013/07/05 PHP
php文件夹与文件目录操作函数介绍
2013/09/09 PHP
javascript与asp.net(c#)互相调用方法
2009/12/13 Javascript
理解Javascript_03_javascript全局观
2010/10/11 Javascript
来自国外的14个图片放大编辑的jQuery插件整理
2010/10/20 Javascript
Javascript实现DIV滚动自动滚动到底部的代码
2012/03/01 Javascript
JS中批量给元素绑定事件过程中的相关问题使用闭包解决
2013/04/15 Javascript
JQuery+CSS提示框实现思路及代码(纯手工打造)
2013/05/07 Javascript
在javaScript中关于submit和button的区别介绍
2013/10/20 Javascript
js控制浏览器全屏示例代码
2014/02/20 Javascript
javascript实现网页字符定位的方法
2015/07/14 Javascript
常用原生js自定义函数总结
2016/11/20 Javascript
在一个页面重复使用一个js函数的方法详解
2016/12/26 Javascript
jQuery zTree树插件简单使用教程
2017/01/10 Javascript
JavaScript编写九九乘法表(两种任选)
2017/02/04 Javascript
vuex 动态注册方法 registerModule的实现
2019/07/03 Javascript
在pycharm中开发vue的方法步骤
2020/03/04 Javascript
在Django中编写模版节点及注册标签的方法
2015/07/20 Python
Python获取某一天是星期几的方法示例
2017/01/17 Python
Python+Wordpress制作小说站
2017/04/14 Python
Python实现求笛卡尔乘积的方法
2017/09/16 Python
Django后端发送小程序微信模板消息示例(服务通知)
2019/12/17 Python
完美解决Pycharm中matplotlib画图中文乱码问题
2021/01/11 Python
美国瑜伽品牌:Gaiam
2017/10/31 全球购物
高级运动鞋:GREATS
2019/07/19 全球购物
某公司C#程序员面试题笔试题
2014/05/26 面试题
Python如何实现单例模式
2016/06/03 面试题
应届大学生求职信
2013/12/01 职场文书
2014年销售人员工作总结
2014/11/27 职场文书
户外亲子活动总结
2015/05/08 职场文书
我的长征观后感
2015/06/09 职场文书
Java 实战项目之家居购物商城系统详解流程
2021/11/11 Java/Android
Java异常处理try catch的基本用法
2021/12/06 Java/Android
python如何利用cv2.rectangle()绘制矩形框
2022/12/24 Python