一、基础知识
1.卷积核
我们不妨将图片视为一个由不同数字组成的巨大矩阵,卷积核一般体现为一个3×3/5×5/7×7的横纵为奇数的小型方阵,填充的数字可视为各个部分的权重。将卷积核逐次与图片矩阵的部分进行相乘(反转相乘),求和。将所得结果除以卷积核所有权重的总值,就可以得到一个相对平滑的图片,同时也是一种最基础的滤波器——均值滤波,或者是Normalize == True的方盒滤波(Opencv写法)。
卷积核的大小:在深度学习中,卷积核越大,可以看到的信息(专业术语中叫感受野)越多,提取的特征越好,同时计算量也就越大,所以在进行大量或复杂的图像处理时,不会使用太大的卷积核,而选择使用多个小的卷积核处理,避免运算爆炸。
具体计算详见:
2.锚点
简而言之,就是卷积核的正中心,通常情况下,卷积核是一个行列为奇数的方阵,目的也是为了锚点一直在卷积核的正中心,从而防止图像处理时位置发生偏移。
3.边界扩充
由图我们很容易发现,当我们采用卷积核处理图像,最终一定会导致输出图像小于原图像,然而通常我们通过OpenMV得到的图像与原来大小相同。这是因为处理时,OpenMV已经对图像用数字0进行了边界扩充操作(如图虚线处),从而达到输出图像大小不变的效果。
4.步长
当使用卷积核逐次对图像各个部分进行处理时,并非只能一格一格的运行处理,图像可以通过增加步长的方式,让卷积核“跳过”一格或几格进行处理。
二、低通滤波器的使用
(1)均值滤波器(mean_filter)
代码如下:
import sensor
import time
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QQVGA)
sensor.skip_frames(time=2000)
clock = time.clock()
while True:
img = sensor.snapshot()
# kernel = {1,2...} kernel为卷积核,卷积核可以选择 1:3x3大小,2: 5x5大小,
#卷积核过大会导致运算量爆表,因此2之后的卷积核尽量不要使用
img.mean(1)
效果展示:
左侧为原图,右侧为输出图。我们明显发现,图像更加模糊平滑,毛发的细腻度降低。(由于OpenMV展现的实时滤波图像不明显,所以以下都使用OpenCV代码代为处理)
原理分析:
(2)高斯滤波器(blur_filter)
代码如下:
import sensor
import time
sensor.reset()
sensor.set_pixformat(sensor.GRAYSCALE)
sensor.set_framesize(sensor.QQVGA)
sensor.skip_frames(time=2000)
clock = time.clock()
while True:
img = sensor.snapshot()
# 在图像的每个像素上运行内核。
img.gaussian(1)
效果展示:
左侧为原图,右侧为输出图。我们明显发现,图像高斯噪点更少,图像更清晰。
原理分析:
(3)中值滤波器(median_filter)
代码如下:
import sensor
import time
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QQVGA)
sensor.skip_frames(time=2000)
clock = time.clock()
while True:
img = sensor.snapshot()
# 0、1或2,分别对应1x1、3x3或5x5内核。 The second
# percentile=0.5 为取中位数
img.median(1, percentile=0.5)
效果展示:
左侧为原图,右侧为输出图。我们明显发现,图像椒盐噪点(盐噪声多)更少,图像更清晰。
原理分析:
(4)双边滤波器(以彩色为例:color_bilateral_filter)
代码如下:
import sensor, image, time
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QQVGA)
sensor.skip_frames(time = 2000)
while(True):
img = sensor.snapshot()
# color_sigma控制像素色彩上之间必须有相似的距离才能模糊。
# 更小的值意味着它们必须更接近。
# 较大的值不那么严格。
# space_sigma控制像素空间上彼此之间必须有多接近才能模糊
# 更小的值意味着它们必须更接近。
# 较大的值不那么严格。
# 在图像的每个像素上运行核
img.bilateral(3, color_sigma=0.1, space_sigma=1)
# 如果将color_sigma/space_sigma设置为聚合,双边过滤器可能导致图像缺陷。
# 如果你看到缺陷,增加sigma值直到缺陷消失
效果展示:
左侧为原图,右侧为输出图。我们明显发现,画面起到了一个磨皮的效果,但是脸部边缘依旧明显,并未进行模糊化处理。
原理分析:
(5)自定义卷积核滤波器(kernel_filters)
代码如下:
import sensor, image, time
sensor.reset()
sensor.set_pixformat(sensor.GRAYSCALE)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
kernel_size = 1 # 3x3==1, 5x5==2, 7x7==3, etc.
kernel = [-2, -1, 0, \
-1, 1, 1, \
0, 1, 2] # 卷积核矩阵
while(True):
img = sensor.snapshot() # 拍一张照片,返回图像
# 在图像的每个像素上运行核
img.morph(kernel_size, kernel)
效果展示:
特殊处理方法,略。
(6)一些补充
椒盐噪声:
分为椒噪声和盐噪声,椒噪声未画面上分布的小黑点,盐噪声为图像上分布的小白点,二者所构成的噪声被称作椒盐噪声/胡椒噪声。最好的处理办法是使用中值滤波器处理,由于中值滤波器取中位数,可以有效排除图片中椒盐噪声颜色的极端情况,功效良好。因此如果选择众数滤波器也可以起到较为良好除噪的效果。简而言之,类似黑白电视的雪花。
高斯噪声:
呈现为图片上分布的彩色噪点,具有多种颜色。最好处理办法是使用高斯滤波器,但是在噪点过多且明显的情况下输出图像会具有“晕染”效果。值得注意的是,如果在灰度图下区分高斯噪声和椒盐噪声,会发现高斯噪声所呈现噪点没有椒盐噪声那么分明,高噪点情况下,对图像大致内容影响没椒盐噪声大。