0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

OpenCV种支持标准卷积边缘填充做法

OpenCV学堂 来源:OpenCV学堂 作者:OpenCV学堂 2022-07-12 14:18 次阅读

概述

OpenCV在使用卷积进行图像处理过程种,如何处理边缘像素锚定输出两个技术细节一直是很多人求而不得的疑惑。其实OpenCV在做卷积滤波时会对图像进行边界填充,实现对边缘像素的卷积计算的支持,不同填充方式不同锚定点会得到图像卷积输出不同的结果。

边界填充

我们首先来看一下OpenCV种支持标准卷积边缘填充做法,OpenCV支持的有如下几种卷积边缘填充算法:

常量边界

BORDER_CONSTANT

iiiiii|abcdefgh|iiiiiii

边界复制

BORDER_REPLICATE

aaaaaa|abcdefgh|hhhhhhh

边界反射

BORDER_REFLECT

fedcba|abcdefgh|hgfedcb

边界换行

BORDER_WRAP

cdefgh|abcdefgh|abcdefg

边界反射101

BORDER_REFLECT_101

gfedcb|abcdefgh|gfedcba

边界透明-很不幸运的是OpenCV4已经不支持啦!

BORDER_TRANSPARENT

uvwxyz|abcdefgh|ijklmno

默认填充方式

OpenCV中 filter2D, blur, GaussianBlur等卷积操作默认支持为BORDER_DEFAULT(BORDER_REFLECT_101)

各种不同方式对边缘的填充效果如下:

ad3a60fa-01a9-11ed-ba43-dac502259ad0.jpg

上图背景为红色,填充上下左右四个像素大小边缘!右下角为原图,左上角图像为常量边缘填充效果(i=0黑色)。

相关代码实现如下:

image=cv.imread("D:/images/qxx.png");
ih,iw=image.shape[:2]
border=4

#边界填充
b1=cv.copyMakeBorder(image,border,border,border,border,cv.BORDER_CONSTANT)
b2=cv.copyMakeBorder(image,border,border,border,border,cv.BORDER_REPLICATE)
b3=cv.copyMakeBorder(image,border,border,border,border,cv.BORDER_REFLECT)
b4=cv.copyMakeBorder(image,border,border,border,border,cv.BORDER_WRAP)
b5=cv.copyMakeBorder(image,border,border,border,border,cv.BORDER_REFLECT_101)

#边界填充类型说明
cv.putText(image,"input",(20,20),cv.FONT_HERSHEY_PLAIN,1.0,(255,0,0))
cv.putText(b1,"BORDER_CONSTANT",(20,20),cv.FONT_HERSHEY_PLAIN,1.0,(255,0,0))
cv.putText(b2,"BORDER_REPLICATE",(20,20),cv.FONT_HERSHEY_PLAIN,1.0,(255,0,0))
cv.putText(b3,"BORDER_REFLECT",(20,20),cv.FONT_HERSHEY_PLAIN,1.0,(255,0,0))
cv.putText(b4,"BORDER_WRAP",(20,20),cv.FONT_HERSHEY_PLAIN,1.0,(255,0,0))
cv.putText(b5,"BORDER_REFLECT_101",(20,20),cv.FONT_HERSHEY_PLAIN,1.0,(255,0,0))

#拼接结果输出
h=b1.shape[0]*2+8
w=b1.shape[1]*3+16
bh,bw=b1.shape[:2]
result=np.zeros([h,w,3],dtype=np.uint8)
result[:,:,:]=(0,0,255)
result[0:bh,0:bw,:]=b1;
result[0:bh,bw+8:bw+bw+8,:]=b2;
result[0:bh,bw+bw+16:bw+bw+bw+16,:]=b3;
result[bh+8:bh+bh+8,0:bw,:]=b4;
result[bh+8:bh+bh+8,bw+8:bw+bw+8,:]=b5;
result[bh+12:bh+12+ih,bw+bw+20:bw+bw+20+iw,:]=image;

#显示
cv.imshow("result",result)
cv.imwrite("D:/border_result.png",result)
cv.waitKey(0)
cv.destroyAllWindows()

锚定位置

在进行卷积处理的时候,卷积mask与对应的像素块点乘得到输出,把输出结果赋值给哪个像素点是由锚定参数anchor决定,以自定义滤波函数filter2D为例说明

voidcv::filter2D(
InputArraysrc,
OutputArraydst,
intddepth,
InputArraykernel,
Pointanchor=Point(-1,-1),
doubledelta=0,
intborderType=BORDER_DEFAULT
)
其中
kernel - 表示输入的自定义卷积核大小
anchor - 表示锚定点位置,默认情况Point(-1,-1)表示是卷积核的中心位置
borderType - 表示边缘填充的像素大小,ksize/2其中ksize表示卷积核大小

上述函数在卷积核为奇数的时候,卷积核的中心位置很容易确定,比如3x3的卷积核大小,中心位置为Point(1,1)5x5的卷积核大小中心位置为Point(2,2)

但是当卷积核大小为偶数的时候,很多人都搞不清楚中心位置是如何确定的,其实这个时候中心也为(ksize/2), 对2x2的卷积核,中心位置为Point(1,1)4x4的卷积核中心位置为Point(2,2)

锚定位置对卷积结果的影响

以2x2与4x4的卷积核为与3x3与5x5的像素数据为例

情况一

2x2卷积核对3x3的像素块

ad5a1eb8-01a9-11ed-ba43-dac502259ad0.png

ad6c6776-01a9-11ed-ba43-dac502259ad0.png

当锚定点为默认(1,1)/(-1,-1)时候:

ad7e1552-01a9-11ed-ba43-dac502259ad0.png

当锚定点设置为(0,0)时:

ad91dfe2-01a9-11ed-ba43-dac502259ad0.png

可以看到二者的输出结果全然不同,原因在于当锚定点不同的时候,卷积mask的开始位置也会不不同,图示如下:

ada20f98-01a9-11ed-ba43-dac502259ad0.jpg

情况二:

4x4卷积核对5x5的像素块:

adb38278-01a9-11ed-ba43-dac502259ad0.png

使用BORDER_DEFAULT填充方式,填充之后为:

adc6234c-01a9-11ed-ba43-dac502259ad0.png

不同锚定位置的均值卷积输出结果:

ade1a13a-01a9-11ed-ba43-dac502259ad0.jpg

三个不同锚定点对应卷积mask的起始位置与锚定像素输出:

adfc7d98-01a9-11ed-ba43-dac502259ad0.jpg

代码演示如下:

src=np.zeros([3,3],dtype=np.uint8)
src[0,0]=16
src[1,1]=8
src[2,2]=4
print("
inputimage:
",src)

k1=[[1,0],[0,-1]]
print("
kernel:
",k1)
result=cv.copyMakeBorder(src,1,1,1,1,cv.BORDER_DEFAULT)
print("
BORDER_DEFAULT边界填充:
",result)
dst=cv.filter2D(src,cv.CV_32F,np.asarray(k1),None,anchor=(0,0),borderType=cv.BORDER_DEFAULT)
print("
filter2D:
",dst)
print("
")

src=np.zeros([5,5],dtype=np.uint8)
src[0,0]=32
src[1,1]=16
src[2,2]=8
src[3,3]=4
src[4,4]=2
print("
input:
",src)
k2=np.ones([4,4],dtype=np.int32)
print("
kernel:
",k2)
result=cv.copyMakeBorder(src,3,3,3,3,cv.BORDER_DEFAULT)
print("
边界填充:
",result)
dst=cv.filter2D(src,cv.CV_32F,np.asarray(k2),None,anchor=(-1,-1),borderType=cv.BORDER_DEFAULT)
print("
filter2DResult:
",dst)

原文标题:详解OpenCV卷积滤波之边缘处理与锚定输出

文章出处:【微信公众号:OpenCV学堂】欢迎添加关注!文章转载请注明出处。

审核编辑:彭静

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 函数
    +关注

    关注

    3

    文章

    4276

    浏览量

    62314
  • 代码
    +关注

    关注

    30

    文章

    4719

    浏览量

    68210
  • OpenCV
    +关注

    关注

    29

    文章

    624

    浏览量

    41210

原文标题:详解OpenCV卷积滤波之边缘处理与锚定输出

文章出处:【微信号:CVSCHOOL,微信公众号:OpenCV学堂】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    opencv图像识别有什么算法

    OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习软件库,提供了大量的图像处理和计算机视觉相关的算法。以下是一些常见的OpenCV
    的头像 发表于 07-16 10:40 726次阅读

    opencv-python和opencv一样吗

    的。以下是对OpenCVOpenCV-Python的比较: 编程语言: OpenCV是一个跨平台的库,支持多种编程语言,如C++、Java、Python等。而
    的头像 发表于 07-16 10:38 862次阅读

    opencv的主要功能有哪些

    OpenCV提供了丰富的图像处理功能,包括图像的读取、显示、保存、转换等。此外,OpenCV支持图像的滤波、边缘检测、形态学操作、图像金字塔等高级图像处理技术。 特征检测与描述:
    的头像 发表于 07-16 10:35 1224次阅读

    图像处理中的卷积运算

    卷积运算是图像处理中一极其重要的操作,广泛应用于图像滤波、边缘检测、特征提取等多个方面。它基于一个核(或称为卷积核、滤波器)与图像进行相乘并求和的过程,通过这一操作可以实现对图像的平
    的头像 发表于 07-11 15:15 1562次阅读

    卷积神经网络实现示例

    卷积神经网络(Convolutional Neural Network,简称CNN)是一深度学习模型,主要用于处理具有网格结构的数据,如图像。CNN通过卷积层自动提取图像特征,然后通过全连接层进行
    的头像 发表于 07-03 10:51 336次阅读

    卷积神经网络的实现原理

    、训练过程以及应用场景。 卷积神经网络的基本原理 1.1 卷积操作 卷积神经网络的核心是卷积操作。卷积操作是一
    的头像 发表于 07-03 10:49 475次阅读

    卷积神经网络训练的是什么

    卷积神经网络(Convolutional Neural Networks,简称CNN)是一深度学习模型,广泛应用于图像识别、视频分析、自然语言处理等领域。本文将详细介绍卷积神经网络的基本概念、结构
    的头像 发表于 07-03 09:15 311次阅读

    卷积神经网络的原理与实现

    1.卷积神经网络(Convolutional Neural Networks,简称CNN)是一深度学习模型,广泛应用于图像识别、视频分析、自然语言处理等领域。 卷积神经网络是一前馈
    的头像 发表于 07-02 16:47 452次阅读

    请问ESP32是否支持GPIO边缘触发唤醒?

    请问ESP32是否支持GPIO边缘触发唤醒,例如GPIO下降沿触发或者上升沿触发。
    发表于 06-18 08:09

    什么是芯片底部填充胶,它有什么特点?

    什么是芯片底部填充胶,它有什么特点?芯片底部填充胶是一用于电子封装的胶水,主要用于底部填充bga芯片电子组件,以增强组件的可靠性和稳定性。它通常是一
    的头像 发表于 03-14 14:10 939次阅读
    什么是芯片底部<b class='flag-5'>填充</b>胶,它有什么特点?

    填充胶是做什么用的?

    填充胶是做什么用的?填充胶是一广泛应用于电子制造和其他工业领域的材料,它在提高产品性能、增强结构稳定性以及保护核心组件方面发挥着至关重要的作用。以下是关于填充胶的主要用途和它在不同应
    的头像 发表于 01-17 14:52 899次阅读
    <b class='flag-5'>填充</b>胶是做什么用的?

    OpenCV边缘模板匹配算法原理详解

    ,悲喜交加,充分感受到了理想与现实的距离,不过没关系,这里介绍一新的模板匹配算法,主要是基于图像边缘梯度,它对图像光照与像素迁移都有很强的抗干扰能力,据说Halcon的模板匹配就是基于此的加速版本,在工业应用场景中已经得到广泛使用。
    的头像 发表于 12-07 10:56 1279次阅读
    <b class='flag-5'>OpenCV</b><b class='flag-5'>边缘</b>模板匹配算法原理详解

    OpenCV4.8 CUDA编程代码教程

    OpenCV4支持通过GPU实现CUDA加速执行,实现对OpenCV图像处理程序的加速运行,当前支持加速的模块包括如下。
    的头像 发表于 12-05 09:56 945次阅读
    <b class='flag-5'>OpenCV</b>4.8 CUDA编程代码教程

    OpenCV4.8+CUDA+扩展模块支持编译指南

    OpenCV4.8+CUDA+扩展模块支持编译指南
    的头像 发表于 11-30 16:45 867次阅读
    <b class='flag-5'>OpenCV</b>4.8+CUDA+扩展模块<b class='flag-5'>支持</b>编译指南

    OpenCV对openEuler提供上游原生支持

    2023年11月17日,OpenCV社区正式接纳openEuler作为持续集成(Continuous Integration,CI)系统的操作系统之一,对openEuler提供上游原生支持
    的头像 发表于 11-20 09:14 788次阅读