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

    文章

    4406

    浏览量

    66851
  • 代码
    +关注

    关注

    30

    文章

    4941

    浏览量

    73155
  • OpenCV
    +关注

    关注

    33

    文章

    651

    浏览量

    44427

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

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

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    卷积运算分析

    卷积运算的基础运算是乘加运算(MAC,Multiplication and Accumulation),本文设计了基本运算单元PE模块来实现MAC运算。对于卷积运算而言,一次性至少处理一个感受域规模
    发表于 10-28 07:31

    NMSIS库的使用

    nmsis core、nmsis dsp和nmsis nn三个组件,分别提供了对处理器核心和外设、数字信号处理库和神经网络内核的支持卷积、激活、池化是卷积神经网络中常用的三操作,
    发表于 10-24 09:58

    机器视觉双雄YOLO 和 OpenCV 到底有啥区别?别再傻傻分不清!

    很多人一听到 “YOLO”和“OpenCV” ,总以为它们是同一东西。其实, 一个是AI算法,一个是视觉工具库;一个会“识别”,一个会“处理” 。本文带你深入了解两者的核心区别与协同关系,以及它们
    的头像 发表于 10-14 16:00 559次阅读
    机器视觉双雄YOLO 和 <b class='flag-5'>OpenCV</b> 到底有啥区别?别再傻傻分不清!

    零成本钢铁侠手套!树莓派+OpenCV 秒变手势遥控器!

    大家好,这是一个树莓派和OpenCV的连载专题。使用树莓派与OpenCV实现姿态估计和面部特征点追踪使用树莓派与OpenCV实现面部和运动追踪的云台系统使用树莓派和OpenCV实现手部
    的头像 发表于 08-16 16:16 893次阅读
    零成本钢铁侠手套!树莓派+<b class='flag-5'>OpenCV</b> 秒变手势遥控器!

    如何使用树莓派与OpenCV实现面部和运动追踪的云台系统?

    大家好,这是一个树莓派和OpenCV的连载专题。使用树莓派与OpenCV实现姿态估计和面部特征点追踪使用树莓派与OpenCV实现面部和运动追踪的云台系统使用树莓派和OpenCV实现手部
    的头像 发表于 08-14 17:45 976次阅读
    如何使用树莓派与<b class='flag-5'>OpenCV</b>实现面部和运动追踪的云台系统?

    AI 边缘计算网关:开启智能新时代的钥匙​—龙兴物联

    智能化决策的关键。卷积神经网络在图像识别方面表现卓越,在智能工厂产品质量检测中,能快速准确识别产品缺陷;循环神经网络擅长处理时间序列数据,可对设备故障进行精准预测。 在通信技术与协议支持上,AI 边缘
    发表于 08-09 16:40

    沟槽填充技术介绍

    图2.2是现代CMOS 器件剖面的示意图。一般来说,水平方向的尺寸微缩幅度比垂直方向的幅度更大,这将导致沟槽(包含接触孔)的深宽比(aspect ratio)也随之提高,为避免沟槽填充过程中产生空穴
    的头像 发表于 05-21 17:50 984次阅读
    沟槽<b class='flag-5'>填充</b>技术介绍

    多协议边缘计算网关EG8200-新升级-支持99%PLC协议 #plc #物联网

    边缘计算
    成都纵横智控科技
    发布于 :2025年03月13日 17:14:18

    如何使用MATLAB实现一维时间卷积网络

    本文对一维卷积操作进行介绍,包括一维扩展卷积和一维因果卷积,以及 MATLAB 对一维卷积支持情况。在最后通过一个实例演示如何在 MATL
    的头像 发表于 03-07 09:15 1680次阅读
    如何使用MATLAB实现一维时间<b class='flag-5'>卷积</b>网络

    请问OpenVINO™工具套件是否支持使用非对称卷积支持模型?

    无法确定使用非对称卷积的模型是否受 OpenVINO™ Toolkit 的支持
    发表于 03-06 07:58

    先进封装Underfill工艺中的四常用的填充胶CUF,NUF,WLUF和MUF介绍

    今天我们再详细看看Underfill工艺中所用到的四填充胶:CUF,NUF,WLUF和MUF。 倒装芯片的底部填充工艺一般分为三:毛细填充
    的头像 发表于 01-28 15:41 3683次阅读
    先进封装Underfill工艺中的四<b class='flag-5'>种</b>常用的<b class='flag-5'>填充</b>胶CUF,NUF,WLUF和MUF介绍

    芯片底部填充胶种类有哪些?

    组成和应用特点进行分类,底部填充胶可以分为以下几种类型:一、按填充方式分类完全底部填充法:将底部空隙完全填满,提供最大的保护和支撑。边缘底部填充
    的头像 发表于 12-27 09:16 1627次阅读
    芯片底部<b class='flag-5'>填充</b>胶种类有哪些?

    AI模型部署边缘设备的奇妙之旅:目标检测模型

    填充(Padding): 填充(Padding)是在卷积神经网络(CNN)中为输入张量的边缘添加额外的像素,以控制输出特征图的大小并保持输入图像的空间尺寸。
    发表于 12-19 14:33

    AI模型部署边缘设备的奇妙之旅:如何在边缘端部署OpenCV

    边缘,通常与边缘检测相关联。 文件保存 cv2.imwrite() 将图像保存到磁盘。 目的:保存处理后的图像以便将来使用或分享。 此外,还有其他重要的OpenCV功能,如: 直方图均衡
    发表于 12-14 09:31

    AI模型部署边缘设备的奇妙之旅:如何在边缘端部署OpenCV

    1简介Opencv(OpenSourceComputerVisionLibrary)是一个基于开源发行的跨平台计算机视觉库,它实现了图像处理和计算机视觉方面的很多通用算法,已成为计算机视觉领域最有
    的头像 发表于 12-14 09:10 1268次阅读
    AI模型部署<b class='flag-5'>边缘</b>设备的奇妙之旅:如何在<b class='flag-5'>边缘</b>端部署<b class='flag-5'>OpenCV</b>