目录
滤波处理
均值滤波
基本原理
函数用法
程序示例
高斯滤波
基本原理
函数用法
程序示例
中值滤波
基本原理
函数用法
程序示例
形态学
腐蚀
膨胀
通用形态学函数
前言:本部分是上一篇文章的延续,前面部分请查看:OpenCV基础(1)
滤波处理
均值滤波
基本原理
其实这也相当于将该像素点的 5× 5 邻域像素值与一个内部值都是 1/25 的 5× 5 矩阵相乘,得到均值滤波的结果 126。
这里可以把这个矩阵简化为以下形式
而简化后的矩阵也被叫做卷积核,一般形式为
其中,M和N是矩阵的高和宽,比较常用的有 3× 3、5× 5、7× 7 等。M 和 N 的值越大,参与运算的像素点越多,当前像素点的计算结果受到越多的周围像素点影响。
函数用法
dst = cv2.blur( src, ksize, anchor, borderType )
其中:
- dst 是返回值,表示进行均值滤波后得到的处理结果。
- src 是需要处理的图像,即原始图像。
- ksize 是滤波核的大小。(就是卷积核)
- anchor 是锚点,默认值是(-1,-1),表示当前计算均值的像素点位于滤波核的中心点位置。该值使用默认值即可,在特殊情况下可以指定不同的点作为锚点。
- borderType 是边界样式,该值决定了以何种方式处理边界。OpenCV 提供了多种填充边界的方式,如用边缘值填充、用 0 填充、用 255 填充、用特定值填充等。
一般来说,anchor 和borderType 都不需要修改,因此只需要传入3个参数即可。
程序示例
import cv2
o=cv2.imread("Colnoiselena.jpg")
r3=cv2.blur(o,(3,3))
r11=cv2.blur(o,(7,7))
cv2.imshow("original",o)
cv2.imshow("result3",r3)
cv2.imshow("result7",r11)
cv2.waitKey()
cv2.destroyAllWindows()
上图中白色的点即为噪声,使用3× 3的卷积核时噪声明显有所改善,图像失真不太严重;使用7× 7 的卷积核时图像噪声大幅减少,但是图像失真很严重。
补充:失真表示与原图像的偏差,这里也就是模糊度。
高斯滤波
基本原理
高斯滤波中,卷积核的值不再相等,但卷积核的大小一定要是奇数。不同大小的卷积核如下图示:
计算方式如下:
函数用法
高斯滤波的函数是 cv2.GaussianBlur(),该函数的语法格式是
dst = cv2.GaussianBlur( src, ksize, sigmaX, sigmaY, borderType )
其中:
- dst 是返回值,表示滤波后的图像。
- src 是需要处理的图像,即原始图像。
- ksize 是滤波核的大小。滤波核大小是指在滤波处理过程中邻域图像的高度和宽度。滤波核的大小必须是奇数。
- sigmaX 是卷积核在水平方向(X 轴方向)上的标准差,其控制的是权重比。
- sigmaY是卷积核在垂直方向(Y轴方向)上的标准差。若将该值设置为0,则只采用sigmaX 的值;如果 sigmaX 和 sigmaY 都是 0,则通过 ksize.width 和 ksize.height 计算得到。其中:
- borderType 是边界样式,该值决定了以何种方式处理边界。一般情况下,该值采用默认值即可。
补充:这里可能会有不理解标准差和权重比的,我简单说一下:标准差就是方差开根,表示数据的离散程度,换句话说就是标准差越大,表示所有数据离均值越远,越小离均值越近。而权重比就是卷积核内的数求和取倒数。
在这里,sigmaY 和 borderType 是可选参数。sigmaX 是必选参数,但是可以将该参数设置为 0,让函数自己去计算 sigmaX 的具体值。所以至少需要传入3个参数。
一般来说当卷积核确定时,sigma 越大图像的去噪效果越好,但相应的图像也变得更为模糊,反之亦是如此。为了简便,我们一般不会手动去设置这个值,由函数自己计算,因此函数的一般形式为
dst = cv2.GaussianBlur( src, ksize, 0, 0 )
程序示例
import cv2
o=cv2.imread(r"Colnoiselena.jpg")
r1=cv2.GaussianBlur(o,(5,5),0,0)
r2=cv2.GaussianBlur(o,(5,5),0.1,0.1)
r3=cv2.GaussianBlur(o,(5,5),1,1)
cv2.imshow("original",o)
cv2.imshow("result1",r1)
cv2.imshow("result2",r2)
cv2.imshow("result3",r3)
cv2.waitKey()
cv2.destroyAllWindows()
可以明显看出,使用相同的卷积核时函数自己计算和标准差为1得到的去噪效果相差不大,但是由于标准差较大表现出模糊的现象。所以有时我们手动设置值得到的效果图不一定比默认的好啊。
中值滤波
中值滤波采用邻域内所有像素值的中间值来替代当前像素点的像素值。
基本原理
函数用法
dst = cv2.medianBlur( src, ksize)
其中:
- dst 是返回值,表示进行中值滤波后得到的处理结果。
- src 是需要处理的图像,即原始图像。
- ksize 是滤波核的大小。滤波核大小是指在滤波处理过程中邻域图像的高度和宽度。滤波核的大小必须是比 1 大的奇数,如 3、5、7 等。
程序示例
import cv2
o=cv2.imread("Colnoiselena.jpg")
r=cv2.medianBlur(o,3)
cv2.imshow("original",o)
cv2.imshow("result",r)
cv2.waitKey()
cv2.destroyAllWindows()
形态学
腐蚀
图中,黑色方块是结构元(又称核),白色圆形是前景。
- 如果结构元完全处于前景对象中,就将结构元中心点对应的腐蚀结果图像中的像素点处理为前景色(白色,像素点的像素值为 1)。
- 如果结构元未完全处于前景对象中(可能部分在,也可能完全不在),就将结构元中心点对应的腐蚀结果图像中的像素点处理为背景色(黑色,像素点的 像素值为 0)。
最后得到的图像就会向内部收缩。下面我们用一个具体的示例进行说明。
图中
- (a)表示待腐蚀图像 img。
- (b)是核 kernel。
- (c)中的阴影部分是核 kernel 在遍历 img 时,完全位于前景对象内部时的 3 个全部可能位置。也就是说,当核 kernel 处于任何其他位置时都不能完全位于前景对象中。
- (d)是腐蚀结果 rst,即在核 kernel 完全位于前景对象中时,将其中心点对应的rst 中像素点的像素值置为 1;当核 kernel 不完全位于前景对象中时,将其中心点对应的rst 中像素点的像素值置为 0。
dst = cv2.erode( src, kernel[, anchor[, iterations[, borderType[, borderValue]]]] )
其中:
- dst 是腐蚀后输出的目标图像,该图像和原始图像的类型和大小相同。
- src 是需要进行腐蚀的原始图像。
- kernel 代表腐蚀操作时采用的结构类型,一般会输入一个元组。
- anchor 代表结构元中锚点的位置。该值默认为(-1,-1),在核的中心位置。
- iterations 是腐蚀操作迭代的次数,该值默认为 1,即只进行一次腐蚀操作。
import cv2
import numpy as np
o=cv2.imread("1.png")
kernel1 = np.ones((3,3),np.uint8)
erosion1 = cv2.erode(o,kernel1)
kernel2 = np.ones((5,5),np.uint8)
erosion2 = cv2.erode(o,kernel2, iterations=5)
cv2.imshow("orriginal",o)
cv2.imshow("erosion1",erosion1)
cv2.imshow("erosion2",erosion2)
cv2.waitKey()
cv2.destroyAllWindows()
可以看出,腐蚀操作具有腐蚀去噪功能,核越大腐蚀效果越明显。
膨胀
- 如果结构元中任意一点处于前景对象中,就将膨胀结果图像中对应像素点处理为前景色。
- 如果结构元完全处于背景对象外,就将膨胀结果图像中对应像素点处理为背景色。
图中:
- (a)表示待膨胀图像 img。
- (b)是核 kernel。
- (c)中的阴影部分是核 kernel 在遍历 img 时,核 kernel 中心像素点位于 img[1,1]、 img[3,3]时与前景对象存在重合像素点的两种可能情况。
- (d)是膨胀结果图像 rst。在核 kernel 内,当任意一个像素点与前景对象重合时,其中心点对应的膨胀结果图像内的像素点的像素值为 1;当核 kernel 与前景对象完全无重合时,其中心点对应的膨胀结果图像内的像素点值为 0。
dst = cv2.dilate( src, kernel[, anchor[, iterations[, borderType[, borderValue]]]])
- dst 代表膨胀后输出的目标图像,该图像和原始图像类型和大小相同。
- src 代表需要进行膨胀操作的原始图像。
- kernel 代表膨胀操作采用的结构类型,一般是元组。
- anchor 代表结构元中锚点的位置。该值默认为(-1,-1),在核的中心位置。
- iterations 是膨胀操作迭代的次数,该值默认为 1,即只进行一次膨胀操作。
import cv2
import numpy as np
o=cv2.imread("erode2.jpg")
kernel = np.ones((5,5),np.uint8)
dilation1 = cv2.dilate(o,kernel)
dilation2 = cv2.dilate(o,kernel,iterations = 9)
cv2.imshow("original",o)
cv2.imshow("dilation1",dilation1)
cv2.imshow("dilation2",dilation2)
cv2.waitKey()
cv2.destroyAllWindows()
通用形态学函数
dst = cv2.morphologyEx( src, op, kernel[, anchor[, iterations[, borderType[, borderValue]]]] )
- dst 代表经过形态学处理后输出的目标图像,该图像和原始图像的类型和大小相同。
- src 代表待进行形态学操作的原始图像。
- op 代表操作类型。各种形态学运算的操作规则均是将腐蚀操作和膨胀操作进行组合得到的。
- 开运算操作先将图像腐蚀,再对腐蚀的结果进行膨胀,可以用于去噪、计数等。
- 闭运算是先膨胀、后腐蚀的操作,有助于关闭前景物体内部的小孔,或去除物体上的小黑点,还可以将不同的前景对象进行连接。
- 形态学梯度运算是用原始图像的膨胀图像减腐蚀图像的操作,该操作可以获取原始图像中前景对象的边缘。
- 顶帽运算是用原始图像减去其开运算图像的操作。该操作能够获取图像的噪声信息,或者得到比原始图像的边缘更亮的边缘信息。
- 黑帽运算是用闭运算图像减去原始图像的操作。该运算能够获取图像内部的小孔,或前景色中的小黑点,或者得到比原始图像的边缘更暗的边缘部分。