本文最后更新于:2024年5月7日 下午
本文摘录OpenCV 中的卷积、滤波相关操作内容,重点介绍 Opencv 操作中处理边界卷积与阈值化相关的操作。
预备知识
滤波、核和卷积
滤波器指的是一种由一幅图像(x,y)根据像素点x,y附近的区域计算得到一幅新图像’(x,y)的算法。其中,模板规定了滤波器的形状以及这个区域内像素的值的组成规律,也称“滤波器”或者核。本章中出现的滤波器多数为线性核,也就是说I"(x,y)的像素的值由(x,y)及其周围的像素的值加权相加得来。这个过程可以用下面的方程表示:
$$
I^{\prime}(x, y)=\sum_{i, j \in \text { kermel }} k_{i, j} \cdot I(x+i, y+j)
$$
锚点
图中的每个核都有一个点的值加粗显示,这个点就称作“核的锚点”。它定义了核与源图像的对齐关系。例如图(D)所示的核,数字$41$加粗显示,这意味着用于计算$I’(x,y)$的累加项中,一个项就是$41/273$与$I(x,y)$相乘的结果(同样,$I(x-1,y)$和
$I(x+1,y)$与$26/273$相乘的结果是另外两个项)。
边界外推和边界处理
在对图像进行卷积操作时需要处理边界,常用的方法是在卷积真正像素时向外扩展出虚拟数据,之后再进行卷积。在卷积函数的处理过程中为源图像添加虚拟像素是非常必要的。那么,如何对缺少相邻像素点的边缘像素点计算出一个有效的结果?实际上,在没有公认方法的情况下,我们一般通过自定义的方式在某一场景中处理问题。
1. cv2.copyMakeBorder()
- 一个为图像创建边框的函数,通过指定两幅图像,第一幅是源图像,第二幅是扩充之后的图像,同时指明填充方法,这个函数就会将第一幅图像填补后的结果保存在第二幅图像中。
- 函数使用
1 |
|
- borderType 参数说明
borderType | 含义 |
---|---|
cv2.BORDER_CONSTANT | 复制指定的常量扩展边界 |
cv2.BORDER_WRAP | 复制对边的像素扩展边界 |
cv2.BORDER_REPLICATE | 复制边缘的像素扩展边界 |
cv2.BORDER_REFLECT | 通过镜像复制扩展边界 |
cv2.BORDER_REFLECT_101 | 通过镜像复制扩展边界,边界像素除外 |
cv2.BORDER_DEFAULT | cv2.B0_RDER_REFLECT101的别名 |
- 代码示例
1 |
|
2. cv2.borderInterpolate()
计算扩充的像素对应原图哪个坐标的像素
1 |
|
阈值化操作
图像处理过程中经常会遇见这种情况:我们已经完成了多层处理步骤并需要做出一个最终决定,或者将高于或低于某一值的像素置零同时其他的像素保持不变。OpenCV中的函数cv2.threshold()
实现了这些功能
其原理是对于数组中每个值,根据其高于或低于这个阈值做出相应的处理,给定一个数组和阈值。根据个人喜好,也可以把阈值化操作理解成一个用 $1×1$ 的核进行卷积,对每个像素进行一次非线性操作。
1. cv2.threshold()
- 函数使用
1 |
|
thresholdType
阈值类型 | 操作 |
---|---|
cv2.THRESH_BINARY | DST = (SRC > thresh) ? MAXVALUE : 0 |
cv2.THRESH_BINARY_INV | DST = (SRC > thresh) ? 0 : MAXVALUE |
cv2.THRESH_TRUNC | DST = (SRC > thresh) ? THRESH : SRC |
cv2.THRESH_TOZERO | DST = (SRC > thresh) ? SRC : 0 |
cv2.THRESH_TOZERO_INV | DST = (SRC > thresh) ? 0 : SRC |
cv2.THRESH_OTSU | Otsu 算法选择阈值 |
- 示例代码
1 |
|
- 函数
cv2.threshold()
也可以自动决定最优的阈值,你只需对参数thresholdType
传递值cv2.THRESH_OTSU
即可。 - Otsu 算法的思路为遍历所有可能的阈值,选择加权方差最大的那一个作为结果,具体参考 Otsu
1 |
|
2. cv2.adaptiveThreshold()
有一种与之前不同的阈值化方法,这种方法中阈值在整个过程中自动产生变化。在OpenCV中,函数cv2.adaptiveThreshold(),实现了这种方法
- 官方文档:https://docs.opencv.org/4.5.5/d7/d1b/group__imgproc__misc.html#ga72b913f352e4a1b1b397736707afcde3
- 函数使用
1 |
|
-
adaptiveMethod
-
cv2.adaptiveThreshold()
根据adaptiveMethod
的设置,允许两种不同的自适应阈值方法。两种方法都是逐个像素地计算自适应阈值$T(x,y)$,方法是通过计算每个像素位置周围的$b×b$区域的加权平均值然后减去常数$C$,其中$b$由blockSize
给定。 -
不同的是,如果选择的均值方法是
cv2.ADAPTIVE_THRESH_MEAN_C
,那么均值时取得权值是相等的;如果选择的均值方法是cv2.ADAPTIVE_THRESH_GAUSSIAN_C
,$(x,y)$ 周围的像素的权值则根据其到中心点的距离通过高斯方程得到。方法 实现 cv2.ADAPTIVE_THRESH_MEAN_C
T(x,y) = mean(blockSize×blockSize neighborhood of (x,y)) - C cv2.ADAPTIVE_THRESH_GAUSSIAN_C
T(x,y) = GaussianMean(blockSize×blockSize neighborhood of (x,y)) - C
-
-
thresholdType
- THRESH_BINARY
- THRESH_BINARY_INV
-
相对于一般的阈值化操作,当图像中出现较大的明暗差异时,自适应阈值时非常有效的。这个函数仅处理单通道8位或浮点型图像。
-
示例代码
1 |
|
示例源码
参考资料
- 《学习 OpenCV3》 第十章
文章链接:
https://www.zywvvd.com/notes/study/image-processing/opencv/opencv-filter-conv/filter-conv/
“觉得不错的话,给点打赏吧 ୧(๑•̀⌄•́๑)૭”
微信支付
支付宝支付