1. 自定义滤波
OpenCV中除了之前说的几种常见的滤波方法外,还支持
自定义卷积核
,用于实现自定义滤波
。这一节笔记就通过
自定义卷积核
与相关API函数实现图像卷积的模糊、锐化、梯度
计算这三个典型的卷积处理功能。
- 卷积核本质是用
Mat对象
+put()
置入数据实现的;- 自定义卷积核普适步骤:
a.新建Mat对象
;
b.新建用于存储数据的数组
;
c.数据数组put进Mat对象;
自定义卷积核调用的滤波API与参数解释具体如下:
-
filter2D(Mat src, Mat dst, int ddepth, Mat kernel)
src
:表示输入
图像。
dst
:表示输出
图像。
ddepth
:表示输出图像深度
,-1
表示与输入图像一致
即可。
kernel
:表示自定义图像卷积
。
下面笔记几种常用的自定义卷积核
。
1.1.模糊
最常见的均值模糊的卷积核如下:自定义3×3的模糊卷积核代码如下:
Mat k = new Mat(3, 3, CvType.CV_32FC1);
float[] data = new float[]{1.0f/9.0f,1.0f/9.0f,1.0f/9.0f,
1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f,
1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f};
k.put(0, 0, data);
除了自定义均值模糊之外,
还可以实现自定义近似高斯模糊卷积核
,卷积核如下:
近似高斯模糊卷积核
实现如下:
Mat k = new Mat(3, 3, CvType.CV_32FC1);
float[] data = new float[]{0,1.0f/8.0f,0,
1.0f/8.0f, 0.5f, 1.0f/8.0f,
0, 1.0f/8.0f, 0};
k.put(0, 0, data);
1.2.锐化
图像锐化可以
提高图像的对比度
,
轻微去模糊
,
提升图像质量
;通过
自定义锐化算子
可以实现
图像的锐化,
对输入图像实现质量增强与提升
;
常见的两个锐化算子
如下:
自定义锐化算子
实现:
Mat k = new Mat(3, 3, CvType.CV_32FC1);
float[] data = new float[]{0,-1,0,-1, 5, -1,0, -1, 0};
k.put(0, 0, data);
1.3.梯度
-
图像边缘
是图像像素变化比较大的区域
(边缘在频域里属于高频部分
),是图像特征表征的候选区域
之一,
在图像特征提取、图像二值化等方面有很重要的应用。 - 而通过
自定义卷积算子实现梯度图像
是查找边缘的关键步骤之一
,
最简单
的计算图像梯度功能的卷积核
为Robot算子
,其表示如下:
其中,左侧是Robert算子的X方向梯度、右侧是Y方向梯度。
自定义Robert算子实现如下:
Mat kx = new Mat(3, 3, CvType.CV_32FC1);
Mat ky = new Mat(3, 3, CvType.CV_32FC1);
// X方向梯度算子
float[] robert_x = new float[]{-1,0,0,1};
kx.put(0, 0, robert_x)
// Y方向梯度算子
float[] robert_y = new float[]{0,1,-1,0};
ky.put(0, 0, robert_y);
使用上述自定义的卷积核实现自定义滤波的代码如下:
Imgproc.filter2D(src, dst, -1, k);
完整的演示代码可查看文末的GitHub源代码;
2. 形态学操作
- OpenCV中提供了几个非常有用的
图像形态学操作API
,其工作原理与卷积类似
,
不同的是,
我们称卷积核
为结构元素
、
计算方式
也由算术运算
改为简单集合运算
与逻辑运算
,
而且可以将结构元素
定义为任意结构
。 - 最常见的结构元素有
矩形、线形、圆形、十字交叉形
等。 - OpenCV支持的图像形态学操作主要有
膨胀、腐蚀、开操作、闭操作、黑帽、顶帽、形态学梯度
。
2.1.腐蚀与膨胀
- 膨胀与腐蚀是
最基本的图像形态学操作
,
与卷积计算类似,其也需要一个类似卷积核的结构元素
,与输入图像像素数据完成计算
,
腐蚀与膨胀的常见操作对象
主要是二值图像
或者灰度图像
,
OpenCV所有的形态操作都可以扩展到彩色图像
,
而腐蚀与膨胀
扩展到彩色图像就是前面提到的图像最小值与最大值滤波
。
关于腐蚀与膨胀操作,本参考书中讲得比较概况,而这方面我之前上课学到过,课内讲得相对详细些,下面便参考我校授课的郭素梅教授的教学PPT,做一个总结:
- 首先是腐蚀操作: 其意义便是说,对于输入图像A:
能完全包含结果元素B的区域,则把B嵌进去,并仅留下一个被B的核中心覆盖下的像素块;
不能的,则淘汰掉(腐蚀/削 掉);
结合上图应该很容易能够理解;
- 另外还有一个拓展技巧,如下: 其意思是说,我们可以根据
结构元素以及输入图像的形状
和腐蚀操作“放入模板,只留中心”的原理
,
在面对较大的输入图像时,可以先把最外层的(可放入B的)腐蚀边界
画出来,即可预算出腐蚀结果
;
- 下面是腐蚀效果(腐蚀操作的作用的一个实例):
腐蚀操作的作用:
即同上篇笔记的最小值滤波
一样,
可以去除小的图像噪声或者图像元素对象的大小丝黏连,抑制图像像素极大值;
- 接下来是膨胀操作: 以及其技巧:
- 其意义可以这样理解:
以结构元素B与输入图像A有交集
为条件
,
令B绕着A转一圈,这样B的途经的这一圈地方会形成一个外围区域
,
这样一来,这个外围区域
是由若干个结构元素B
构成的,
而每个B都有一个核中心
,若干个核中心
会在A外围
圈出一个B的“核中心边界”
,
接下来,令A的像素块
由A的边界
拓展到B的“核中心边界”
,即完成膨胀操作;
- 上面是比较正规地用
边界交集
去理解完成膨胀操作
,
我们私自暂称它为“核边界交集法”
;
其实这样的做法也等价于
下面这种操作:
把B的核中心
沿着A的边界
走一圈,
每途经A
的一个像素块
,
都令A的像素块
由A的边界
拓展到B的“核边界”
;
这种操作的结果其实也是等同于上面的“核边界交集法”
;
为与“边界交集法”
区分理解,这种方法暂称之“核中心交集法”
,
下面是“核中心交集法”
演示的gif图:
- 下面是膨胀效果(膨胀操作的作用的一个实例):
膨胀操作的作用:
即同上篇笔记的最大值滤波
一样,
可以填充小的闭合区域以及狭窄的间断;
下面切回读书笔记。
腐蚀操作的定义如图4-8所示。