图像平滑处理---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()

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


1.png

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


2.png

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

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


3.png

可以看到,左下角不需要归一化处理,这里只取(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()

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


4.png

中值滤波

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

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

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

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


5.png

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

双边滤波

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

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

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

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

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


6.png

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

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


7.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,454评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,553评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,921评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,648评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,770评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,950评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,090评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,817评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,275评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,592评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,724评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,409评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,052评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,815评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,043评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,503评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,627评论 2 350