OpenCV每日函数 图像过滤模块 (23) sqrBoxFilter函数

一、概述

        计算与过滤器重叠的像素值的归一化平方和。对于源图像中的每个像素 (x,y),该函数计算与放置在像素 (x,y) 上的滤波器重叠的相邻像素值的平方和。非归一化方盒滤波器可用于计算局部图像统计信息,例如像素附近的局部方差和标准偏差。

        该函数是在boxFilter()函数功能基础上进行扩展功能。CV_8U数据类型的图像像素值从0到255,计算平方后数据会变得更大,即使归一化操作也不能保证像素值不会超过最大值,但是CV_32F数据类型的图像像素值是从0到1之间的小数,在0到1之间的数计算平方会变得更小,但是始终保持在0到1之间。

        因此该函数在处理图像滤波的任务时主要针对的是CV_32数据类型的图像,而且根据计算关系可知,在归一化后图像在变模糊的同时亮度也会变暗。

        见最后示例图像的显示效果。

二、sqrBoxFilter函数

1、函数原型

cv::sqrBoxFilter (InputArray src, OutputArray dst, int ddepth, Size ksize, Point anchor=Point(-1, -1), bool normalize=true, int borderType=BORDER_DEFAULT)

2、参数详解

src 输入图像
dst 输出与 src 相同大小和类型的图像
ddepth 输出图像深度(-1 使用 src.depth())
ksize 内核大小
anchor 内核锚点。 Point(-1, -1) 的默认值表示锚点位于内核中心。
normalize 标志,指定内核是否按其区域进行规范化。
borderType 用于推断图像外部像素的边框模式,请参阅 BorderTypes。 不支持 BORDER_WRAP。

三、OpenCV源码

1、源码路径

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

2、源码代码

void sqrBoxFilter(InputArray _src, OutputArray _dst, int ddepth,
                  Size ksize, Point anchor,
                  bool normalize, int borderType)
{
    CV_INSTRUMENT_REGION();

    CV_Assert(!_src.empty());

    int srcType = _src.type(), sdepth = CV_MAT_DEPTH(srcType), cn = CV_MAT_CN(srcType);
    Size size = _src.size();

    if( ddepth < 0 )
        ddepth = sdepth < CV_32F ? CV_32F : CV_64F;

    if( borderType != BORDER_CONSTANT && normalize )
    {
        if( size.height == 1 )
            ksize.height = 1;
        if( size.width == 1 )
            ksize.width = 1;
    }

    CV_OCL_RUN(_dst.isUMat() && _src.dims() <= 2,
               ocl_boxFilter(_src, _dst, ddepth, ksize, anchor, borderType, normalize, true))

    int sumDepth = CV_64F;
    if( sdepth == CV_8U )
        sumDepth = CV_32S;
    int sumType = CV_MAKETYPE( sumDepth, cn ), dstType = CV_MAKETYPE(ddepth, cn);

    Mat src = _src.getMat();
    _dst.create( size, dstType );
    Mat dst = _dst.getMat();

    Ptr<BaseRowFilter> rowFilter = getSqrRowSumFilter(srcType, sumType, ksize.width, anchor.x );
    Ptr<BaseColumnFilter> columnFilter = getColumnSumFilter(sumType,
                                                            dstType, ksize.height, anchor.y,
                                                            normalize ? 1./(ksize.width*ksize.height) : 1);

    Ptr<FilterEngine> f = makePtr<FilterEngine>(Ptr<BaseFilter>(), rowFilter, columnFilter,
                                                srcType, dstType, sumType, borderType );
    Point ofs;
    Size wsz(src.cols, src.rows);
    src.locateROI( wsz, ofs );

    f->apply( src, dst, wsz, ofs );
}

四、效果图像示例

原图
未归一化
归一化

猜你喜欢

转载自blog.csdn.net/bashendixie5/article/details/125257819