OpenCV每日函数 图像过滤模块 (7) filter2D函数

一、概述

        将图像与内核卷积。该函数将任意线性滤波器应用于图像。当内核部分位于图像之外时,该函数会根据指定的边框模式对异常像素值进行插值。

        该函数确实计算相关性,而不是卷积:

        也就是说,内核不是围绕锚点镜像的。如果您需要真正的卷积,请使用翻转内核并将新锚设置为 (kernel.cols - anchor.x - 1, kernel.rows - anchor.y - 1)。

        该函数在内核较大(11 x 11 或更大)的情况下使用基于 DFT 的算法,而对于小内核则使用直接算法。

二、filter2D函数

1、函数原型

cv::filter2D (InputArray src, OutputArray dst, int ddepth, InputArray kernel, Point anchor=Point(-1,-1), double delta=0, int borderType=BORDER_DEFAULT)

2、参数详解

src 输入图像。
dst 输出与 src 大小和通道数相同的图像。
ddepth 目标图像的所需深度,请参阅组合
kernel 卷积核(或者更确切地说是相关核),单通道浮点矩阵; 如果要将不同的内核应用于不同的通道,请使用 split 将图像拆分为单独的颜色平面并单独处理它们。
anchor 内核的锚点,指示内核中过滤点的相对位置; 锚点应位于内核中; 默认值 (-1,-1) 表示锚点位于内核中心。
delta 在将过滤像素存储到 dst 之前添加到过滤像素的可选值。
borderType 像素外推法,请参阅 BorderTypes。 不支持 BORDER_WRAP。

三、OpenCV源码

1、源码路径

opencv\modules\imgproc\src\filter.dispatch.cpp

2、源码代码

void filter2D(InputArray _src, OutputArray _dst, int ddepth,
              InputArray _kernel, Point anchor0,
              double delta, int borderType)
{
    CV_INSTRUMENT_REGION();

    CV_Assert(!_src.empty());
    CV_Assert(!_kernel.empty());

    CV_OCL_RUN(_dst.isUMat() && _src.dims() <= 2,
               ocl_filter2D(_src, _dst, ddepth, _kernel, anchor0, delta, borderType))

    Mat src = _src.getMat(), kernel = _kernel.getMat();

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

    _dst.create( src.size(), CV_MAKETYPE(ddepth, src.channels()) );
    Mat dst = _dst.getMat();
    Point anchor = normalizeAnchor(anchor0, kernel.size());

    Point ofs;
    Size wsz(src.cols, src.rows);
    if( (borderType & BORDER_ISOLATED) == 0 )
        src.locateROI( wsz, ofs );

    hal::filter2D(src.type(), dst.type(), kernel.type(),
                  src.data, src.step, dst.data, dst.step,
                  dst.cols, dst.rows, wsz.width, wsz.height, ofs.x, ofs.y,
                  kernel.data, kernel.step,  kernel.cols, kernel.rows,
                  anchor.x, anchor.y,
                  delta, borderType, src.isSubmatrix());
}
void filter2D(int stype, int dtype, int kernel_type,
              uchar * src_data, size_t src_step,
              uchar * dst_data, size_t dst_step,
              int width, int height,
              int full_width, int full_height,
              int offset_x, int offset_y,
              uchar * kernel_data, size_t kernel_step,
              int kernel_width, int kernel_height,
              int anchor_x, int anchor_y,
              double delta, int borderType,
              bool isSubmatrix)
{
    bool res;
    res = replacementFilter2D(stype, dtype, kernel_type,
                              src_data, src_step,
                              dst_data, dst_step,
                              width, height,
                              full_width, full_height,
                              offset_x, offset_y,
                              kernel_data, kernel_step,
                              kernel_width, kernel_height,
                              anchor_x, anchor_y,
                              delta, borderType, isSubmatrix);
    if (res)
        return;

    /*CV_IPP_RUN_FAST(ippFilter2D(stype, dtype, kernel_type,
                              src_data, src_step,
                              dst_data, dst_step,
                              width, height,
                              full_width, full_height,
                              offset_x, offset_y,
                              kernel_data, kernel_step,
                              kernel_width, kernel_height,
                              anchor_x, anchor_y,
                              delta, borderType, isSubmatrix))*/

    res = dftFilter2D(stype, dtype, kernel_type,
                      src_data, src_step,
                      dst_data, dst_step,
                      width, height,
                      full_width, full_height,
                      offset_x, offset_y,
                      kernel_data, kernel_step,
                      kernel_width, kernel_height,
                      anchor_x, anchor_y,
                      delta, borderType);
    if (res)
        return;
    ocvFilter2D(stype, dtype, kernel_type,
                src_data, src_step,
                dst_data, dst_step,
                width, height,
                full_width, full_height,
                offset_x, offset_y,
                kernel_data, kernel_step,
                kernel_width, kernel_height,
                anchor_x, anchor_y,
                delta, borderType);
}

四、效果图像示例

原图
基于不同3*3内核的卷积

猜你喜欢

转载自blog.csdn.net/bashendixie5/article/details/125238391
今日推荐