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导出DBF文件到Excel的方法
Jul 25 Python
python获取当前用户的主目录路径方法(推荐)
Jan 12 Python
Python爬虫通过替换http request header来欺骗浏览器实现登录功能
Jan 07 Python
Python实现输入二叉树的先序和中序遍历,再输出后序遍历操作示例
Jul 27 Python
对python3 Serial 串口助手的接收读取数据方法详解
Jun 12 Python
Python绘制三角函数图(sin\cos\tan)并标注特定范围的例子
Dec 04 Python
在Python中实现函数重载的示例代码
Dec 12 Python
python小项目之五子棋游戏
Dec 26 Python
Python如何获取文件指定行的内容
May 27 Python
Python实现在线批量美颜功能过程解析
Jun 10 Python
如何利用python生成MD5并去重
Dec 07 Python
详解pycharm的python包opencv(cv2)无代码提示问题的解决
Jan 29 Python
OpenCV-Python模板匹配人眼的实例
健身房被搭讪?用python写了个小米计时器助人为乐
解决pycharm安装scrapy DLL load failed:找不到指定的程序的问题
OpenCV-Python实现轮廓拟合
python图像处理基本操作总结(PIL库、Matplotlib及Numpy)
Django drf请求模块源码解析
Python中OpenCV实现查找轮廓的实例
You might like
用PHP调用数据库的存贮过程
2006/10/09 PHP
php Rename 更改文件、文件夹名称
2011/05/24 PHP
php若干单维数组遍历方法的比较
2011/09/20 PHP
PHP获取指定月份第一天和最后一天的方法
2015/07/18 PHP
Laravel 的数据库迁移的方法
2017/07/31 PHP
PHP操作Redis数据库常用方法示例
2018/08/25 PHP
Laravel 6 将新增为指定队列任务设置中间件的功能
2019/08/06 PHP
JavaScript 异步调用框架 (Part 3 - 代码实现)
2009/08/04 Javascript
javascript下arguments,caller,callee,call,apply示例及理解
2009/12/24 Javascript
jquery制作属于自己的select自定义样式
2015/11/23 Javascript
jquery.qtip提示信息插件用法简单实例
2016/06/17 Javascript
JS实现鼠标滑过显示边框的菜单效果
2016/09/21 Javascript
JS实现控制图片显示大小的方法【图片等比例缩放功能】
2017/02/18 Javascript
JS对象的深度克隆方法示例
2017/03/16 Javascript
令按钮悬浮在(手机)页面底部的实现方法
2017/05/02 Javascript
vue+mockjs模拟数据实现前后端分离开发的实例代码
2017/08/08 Javascript
vue mint-ui学习笔记之picker的使用
2017/10/11 Javascript
vue-router的钩子函数用法实例分析
2019/10/26 Javascript
python 安装virtualenv和virtualenvwrapper的方法
2017/01/13 Python
致Python初学者 Anaconda入门使用指南完整版
2018/04/05 Python
Python3.6.x中内置函数总结及讲解
2019/02/22 Python
Pandas0.25来了千万别错过这10大好用的新功能
2019/08/07 Python
用python爬取历史天气数据的方法示例
2019/12/30 Python
PyInstaller将Python文件打包为exe后如何反编译(破解源码)以及防止反编译
2020/04/15 Python
用python计算文件的MD5值
2020/12/23 Python
matplotlib绘制鼠标的十字光标的实现(内置方式)
2021/01/06 Python
台湾家适得:Homeget
2019/02/11 全球购物
Shell编程面试题
2012/05/30 面试题
中专生求职自荐信范文
2013/12/22 职场文书
工程专业毕业生自荐信范文
2013/12/25 职场文书
《颐和园》教学反思
2014/02/26 职场文书
三问三解心得体会
2014/09/05 职场文书
单位更名证明
2015/06/18 职场文书
大学军训通讯稿(2016最新版)
2015/12/21 职场文书
Html5通过数据流方式播放视频的实现
2021/04/27 HTML / CSS
详解MySQL的主键查询为什么这么快
2022/04/03 MySQL