OpenCV每日函数 图像过滤模块 (5) dilate函数

一、概述

        通过使用特定的结构元素来扩大图像。该函数使用指定的结构元素扩展源图像,该结构元素确定取最大值的像素邻域的形状:

        膨胀可以应用数次(迭代)。 在多通道图像的情况下,每个通道都是独立处理的。

        膨胀:

        腐蚀:

二、dilate函数

1、函数原型

cv::dilate (InputArray src, OutputArray dst, InputArray kernel, Point anchor=Point(-1,-1), int iterations=1, int borderType=BORDER_CONSTANT, const Scalar &borderValue=morphologyDefaultBorderValue())

2、参数详解 

src 输入图像; 通道数可以是任意的,但深度应该是 CV_8U、CV_16U、CV_16S、CV_32F 或 CV_64F 之一。
dst 输出与 src 大小和类型相同的图像。
kernel 用于膨胀的结构元素; 如果 elemenat=Mat(),则使用 3 x 3 矩形结构元素。 可以使用 getStructuringElement 创建内核
anchor 锚点在元素中的位置; 默认值 (-1, -1) 表示锚点位于元素中心。
iterations 应用膨胀的次数。
borderType 像素外推法,请参阅边框类型。 不支持边框包装。
borderValue 边界不变的情况下的边界值

三、OpenCV源码

1、源码路径

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

2、源码代码

        从源码可知最终是调用了morph函数,其它诸如开闭运算等等均是调用这个函数。

void dilate( InputArray src, OutputArray dst, InputArray kernel,
                 Point anchor, int iterations,
                 int borderType, const Scalar& borderValue )
{
    CV_INSTRUMENT_REGION();

    CV_Assert(!src.empty());

    morphOp( MORPH_DILATE, src, dst, kernel, anchor, iterations, borderType, borderValue );
}
static void morphOp( int op, InputArray _src, OutputArray _dst,
                     InputArray _kernel,
                     Point anchor, int iterations,
                     int borderType, const Scalar& borderValue )
{
    CV_INSTRUMENT_REGION();

    CV_Assert(!_src.empty());

    Mat kernel = _kernel.getMat();
    Size ksize = !kernel.empty() ? kernel.size() : Size(3,3);
    anchor = normalizeAnchor(anchor, ksize);

    CV_OCL_RUN(_dst.isUMat() && _src.dims() <= 2 && _src.channels() <= 4 &&
               borderType == cv::BORDER_CONSTANT && borderValue == morphologyDefaultBorderValue() &&
               (op == MORPH_ERODE || op == MORPH_DILATE) &&
               anchor.x == ksize.width >> 1 && anchor.y == ksize.height >> 1,
               ocl_morphOp(_src, _dst, kernel, anchor, iterations, op, borderType, borderValue) )

    if (iterations == 0 || kernel.rows*kernel.cols == 1)
    {
        _src.copyTo(_dst);
        return;
    }

    if (kernel.empty())
    {
        kernel = getStructuringElement(MORPH_RECT, Size(1+iterations*2,1+iterations*2));
        anchor = Point(iterations, iterations);
        iterations = 1;
    }
    else if( iterations > 1 && countNonZero(kernel) == kernel.rows*kernel.cols )
    {
        anchor = Point(anchor.x*iterations, anchor.y*iterations);
        kernel = getStructuringElement(MORPH_RECT,
                                       Size(ksize.width + (iterations-1)*(ksize.width-1),
                                            ksize.height + (iterations-1)*(ksize.height-1)),
                                       anchor);
        iterations = 1;
    }

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

    Point s_ofs;
    Size s_wsz(src.cols, src.rows);
    Point d_ofs;
    Size d_wsz(dst.cols, dst.rows);
    bool isolated = (borderType&BORDER_ISOLATED)?true:false;
    borderType = (borderType&~BORDER_ISOLATED);

    if(!isolated)
    {
        src.locateROI(s_wsz, s_ofs);
        dst.locateROI(d_wsz, d_ofs);
    }

    hal::morph(op, src.type(), dst.type(),
               src.data, src.step,
               dst.data, dst.step,
               src.cols, src.rows,
               s_wsz.width, s_wsz.height, s_ofs.x, s_ofs.y,
               d_wsz.width, d_wsz.height, d_ofs.x, d_ofs.y,
               kernel.type(), kernel.data, kernel.step, kernel.cols, kernel.rows, anchor.x, anchor.y,
               borderType, borderValue.val, iterations,
               (src.isSubmatrix() && !isolated));
}

四、效果图像示例

原图
3*3的矩形结构元素;迭代3次;
10*3的矩形结构元素;迭代3次;
3*10的矩形结构元素;迭代3次;

猜你喜欢

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