在使用opencv-python进行图像处理过程中,经常会使用卷积对图像进行滤波,在卷积运算过程中,卷积边缘如何处理经常让开发者感到略微困惑,现对此问题进行深入分析。我们使用最简单的滤波函数cv2.filter2D()进行分析,cv2.filter2D()函数的说明见链接,其中borderType指明用何种边缘处理方法,根据官方函数文档提示,有如下几个选项: 可见关于BORDER的选项有很多,但是在opencv的官方教程中并没有找到每一种BORDER的精确含义和说明,因此我们选择其中某几个进行测试。首先测试BORDER_CONSTANT,测试代码如下:
src = np.uint8([[1,1,1,1,1],
[1,2,3,2,1],
[1,1,1,1,1],
[1,2,3,2,1],
[1,1,1,1,1]])
kernel = np.ones((3,3),np.float32)
dst = cv2.filter2D(src, -1, kernel,borderType=cv2.BORDER_CONSTANT)
print('src:', src)
print('dst:', dst)
print('kernel:', kernel)
要将必要的包import完整,程序运行的结果为: 我们对这一结果进行分析,我们首先看dst图像的第二行第二列元素,记为:dst(1,1)=12,其计算方式遵循卷积的定义,如下图所示: 因此处边缘外,目标图像dst中部像素值为: 当卷积核与src图像边缘进行卷积运算时,卷积核部分元素势必处于src外部,如下图所示: 现在的问题是:“?”的值都应该多少?根据运行结果,dst(0,0)的值为5,可知“?”中的值应该为0,即卷积核不在源图像范围内的元素值设置为0,入下图所示: 我们再测试另一个选项BORDER_DEFAULT,代码如下:
dst = cv2.filter2D(src, -1, kernel,borderType=cv2.BORDER_DEFAULT)
按照上文给定的src和kernel,运行结果为: 看dst的输出结果可知,边缘元素和使用BORDER_CONSANT选项时输出的元素完全不同,比如dst(0,0),计算结果为13,那么这个13的值是如何算出来的? 也就是说,**补全的元素是基于src边缘的元素进行中心对称翻转即可。**其他位置元素以此类推,因此dst图像各元素的值为:
通过上述内容中对BORDER_DEFAULT和BORDER_CONSTANT两个选项的分析,可以大致理解opencv-python卷积边缘处理的方法,其他选项可以此类推。
感谢支持,欢迎关注,丰富技术/学术内容持续更新!
opencv-python快速入门视频教程
|