手撕OpenCV源码之filter2D(一)

本文深入探讨了OpenCV中的filter2D函数,详细解释了函数原型、Point anchor的概念及其在源码中的处理,以及边界处理方式。通过源码分析,揭示了anchor在实际计算中的定位和对填充的影响,提供了不同anchor设置下的计算示例。

opencv中的filter2D

函数原型

  • 官方解释
    image

网站

CV_EXPORTS_W void filter2D( InputArray src, OutputArray dst, int ddepth,
                            InputArray kernel, Point anchor=Point(-1,-1),
                            double delta=0, int borderType=BORDER_DEFAULT );
  • ddepth是目标图像深度:每个像素所用的位数
    当前支持的图像深度为:
src.depth() = CV_8U, ddepth = -1/CV_16S/CV_32F/CV_64F
    src.depth() = CV_16U/CV_16S, ddepth = -1/CV_32F/CV_64F
    src.depth() = CV_32F, ddepth = -1/CV_32F/CV_64F
    src.depth() = CV_64F, ddepth = -1/CV_64F

ddepth为-1时,图像深度与源图像深度保持一致.

如果了解深度学习可能知道,深度学习中图像的直接卷积计算有4个参数,whck,但是在opencv
当前只支持k==1,c==1;如果图像为多通道,每个通道使用不同的kernel,则需要使用split()
函数将各通道拆开.

  • Point anchor:这个参数直接翻译叫做锚点,普通意义上,我们在计算卷积的时候,锚点是kernel的中心.中心与图像需要卷积的点对齐,计算改点及周围8个点的乘累加和,替代中心点.在OpenCV中可以设置其他点为锚点,这样就是以锚点和卷积的点对其,计算9个点.但是在Opencv中,对于anchor point做了计算,所以锚点的实际值与设置的值稍有差别,下文会详细介绍.

  • dalta:额外加的数值,就是在卷积过程中该数值会添加到每个像素上.

  • int borderType:表示对边界的处理方式.主要有以下几种:
/*
 Various border types, image boundaries are denoted with '|'
 * BORDER_REPLICATE:     aaaaaa|abcdefgh|hhhhhhh
 * BORDER_REFLECT:       fedcba|abcdefgh|hgfedcb
 * BORDER_REFLECT_101:   gfedcb|abcdefgh|gfedcba
 * BORDER_WRAP:          cdefgh|abcdefgh|abcdefg
 * BORDER_CONSTANT:      iiiiii|abcdefgh|iiiiiii  with some specified 'i'
 */

这是opencv中对5种宏的解释,例子描述的是比较形象的.
BORDER_REPLICATE: 表示对边界重复,来填充边界的扩展.
BORDER_REFLECTBORDER_REFLECT_101都是对边界的对称扩展,但是具体
方式不同,从例子可以很容易看出来.

Point anchor详解

关于Point anchor我在网上查了很多资料,解释都不够清楚,或者说在OpenCV中,按照常规解释,难以获得和OpenCV相同的计算结果.最终在OpenCV的源代码中找到了答案.先上源代码:
(opencv-2.4.9/modules/imgproc/src/filter.cpp)

void cv::filter2D( InputArray _src, OutputArray _dst, int ddepth,
                    InputArray _kernel, Point anchor,
                    double delta, int borderType )
{
     Mat src = _src.getMat(), kernel = _kernel.getMat();

     if( ddepth < 0 )
         ddepth = src.depth();

 #if CV_SSE2
     int dft_filter_size = ((src.depth() == CV_8U && (ddepth == CV_8U || ddepth == CV_16S)) ||
         (src.depth() == CV_32F && ddept
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值