OpenCV每日函数 图像过滤模块 (16) pyrDown函数

一、概述

        模糊图像并对其进行下采样。默认情况下,输出图像的大小计算为 Size((src.cols+1)/2, (src.rows+1)/2),但无论如何,应满足以下条件:

        该函数执行高斯金字塔构造的下采样步骤。 首先,它将源图像与内核进行卷积:

        然后,它通过移除偶数行和列来对图像进行下采样。这里的down是指图像变小,所以原始图像在金字塔的底部。首先将当前层的图像和上面这个高斯核卷积。

        这个高斯核的尺寸为5×5大小,所有元素的值加起来正好为256,最后再除以256,得到的加权和正好为1。其距离最中心越近数值越大,这正好和高斯平滑选择的高斯核类似。

        这个过程也类似于高斯平滑,可以看到经过pyrDown()处理的图像变得更加模糊(平滑)。然后移除偶数行和偶数列,然后就能得到和原图相比是原图1/4大小的新的图像,在图像金字塔中就位于当前层的上一层。

二、pyrDown函数

1、函数原型

cv::pyrDown (InputArray src, OutputArray dst, const Size &dstsize=Size(), int borderType=BORDER_DEFAULT)

2、参数详解

src 输入图像。
dst 输出图像; 它具有指定的大小和与 src 相同的类型。
dstsize 输出图像的大小。
borderType 像素外推法,请参阅 BorderTypes(不支持 BORDER_CONSTANT)

三、OpenCV源码

1、源码路径

opencv\modules\imgproc\src\pyramids.cpp

2、源码代码

void cv::pyrDown( InputArray _src, OutputArray _dst, const Size& _dsz, int borderType )
{
    CV_INSTRUMENT_REGION();

    CV_Assert(borderType != BORDER_CONSTANT);

    CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
               ocl_pyrDown(_src, _dst, _dsz, borderType))

    CV_OVX_RUN(_src.dims() <= 2,
               openvx_pyrDown(_src, _dst, _dsz, borderType))

    Mat src = _src.getMat();
    Size dsz = _dsz.empty() ? Size((src.cols + 1)/2, (src.rows + 1)/2) : _dsz;
    _dst.create( dsz, src.type() );
    Mat dst = _dst.getMat();
    int depth = src.depth();

    CALL_HAL(pyrDown, cv_hal_pyrdown, src.data, src.step, src.cols, src.rows, dst.data, dst.step, dst.cols, dst.rows, depth, src.channels(), borderType);

#ifdef HAVE_IPP
    bool isolated = (borderType & BORDER_ISOLATED) != 0;
    int borderTypeNI = borderType & ~BORDER_ISOLATED;
#endif
    CV_IPP_RUN(borderTypeNI == BORDER_DEFAULT && (!_src.isSubmatrix() || isolated) && dsz == Size((_src.cols() + 1)/2, (_src.rows() + 1)/2),
        ipp_pyrdown( _src,  _dst,  _dsz,  borderType));


    PyrFunc func = 0;
    if( depth == CV_8U )
        func = pyrDown_< FixPtCast<uchar, 8> >;
    else if( depth == CV_16S )
        func = pyrDown_< FixPtCast<short, 8> >;
    else if( depth == CV_16U )
        func = pyrDown_< FixPtCast<ushort, 8> >;
    else if( depth == CV_32F )
        func = pyrDown_< FltCast<float, 8> >;
    else if( depth == CV_64F )
        func = pyrDown_< FltCast<double, 8> >;
    else
        CV_Error( CV_StsUnsupportedFormat, "" );

    func( src, dst, borderType );
}

四、效果图像示例

        下面的例子采用python代码,进行了连续3次进行pyrDown,得到三张新的图片,对应了金字塔中的三个级别,们可以使用cv2.pyrDown()cv2.pyrUp()函数得到高斯金字塔。

img = cv2.imread('..\\messi5.jpg')
img_down = cv2.pyrDown(img,dstsize=(img.shape[1]//2,img.shape[0]//2))
img_down2 = cv2.pyrDown(img_down,dstsize=(img_down.shape[1]//2,img_down.shape[0]//2))
img_down3 = cv2.pyrDown(img_down2,dstsize=(img_down2.shape[1]//2,img_down2.shape[0]//2))

猜你喜欢

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