• opencv erode


    opencv   erode

    void cv::erode( InputArray src, OutputArray dst, InputArray kernel,
                    Point anchor, int iterations,
                    int borderType, const Scalar& borderValue )
    {
        CV_INSTRUMENT_REGION()
    
        morphOp( MORPH_ERODE, src, dst, kernel, anchor, iterations, borderType, borderValue );
    }

    opencv morphOp

    static void morphOp( int op, InputArray _src, OutputArray _dst,
                         InputArray _kernel,
                         Point anchor, int iterations,
                         int borderType, const Scalar& borderValue )
    {
        CV_INSTRUMENT_REGION()
    
        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));
    }
    
    }

    opencv ocl_morphOp

    static bool ocl_morphOp(InputArray _src, OutputArray _dst, InputArray _kernel,
                            Point anchor, int iterations, int op, int borderType,
                            const Scalar &, int actual_op = -1, InputArray _extraMat = noArray())
    {
        const ocl::Device & dev = ocl::Device::getDefault();
        int type = _src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
        Mat kernel = _kernel.getMat();
        Size ksize = !kernel.empty() ? kernel.size() : Size(3, 3), ssize = _src.size();
    
        bool doubleSupport = dev.doubleFPConfig() > 0;
        if ((depth == CV_64F && !doubleSupport) || borderType != BORDER_CONSTANT)
            return false;
    
        bool haveExtraMat = !_extraMat.empty();
        CV_Assert(actual_op <= 3 || haveExtraMat);
    
        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;
        }
    
    #ifndef __APPLE__
        int esz = CV_ELEM_SIZE(type);
        // try to use OpenCL kernel adopted for small morph kernel
        if (dev.isIntel() &&
            ((ksize.width < 5 && ksize.height < 5 && esz <= 4) ||
             (ksize.width == 5 && ksize.height == 5 && cn == 1)) &&
             (iterations == 1)
             )
        {
            if (ocl_morph3x3_8UC1(_src, _dst, kernel, anchor, op, actual_op, _extraMat))
                return true;
    
            if (ocl_morphSmall(_src, _dst, kernel, anchor, borderType, op, actual_op, _extraMat))
                return true;
        }
    #endif
    
        if (iterations == 0 || kernel.rows*kernel.cols == 1)
        {
            _src.copyTo(_dst);
            return true;
        }
    
    #ifdef __ANDROID__
        size_t localThreads[2] = { 16, 8 };
    #else
        size_t localThreads[2] = { 16, 16 };
    #endif
        size_t globalThreads[2] = { (size_t)ssize.width, (size_t)ssize.height };
    
    #ifdef __APPLE__
        if( actual_op != MORPH_ERODE && actual_op != MORPH_DILATE )
            localThreads[0] = localThreads[1] = 4;
    #endif
    
        if (localThreads[0]*localThreads[1] * 2 < (localThreads[0] + ksize.width - 1) * (localThreads[1] + ksize.height - 1))
            return false;
    
    #ifdef __ANDROID__
        if (dev.isNVidia())
            return false;
    #endif
    
        // build processing
        String processing;
        Mat kernel8u;
        kernel.convertTo(kernel8u, CV_8U);
        for (int y = 0; y < kernel8u.rows; ++y)
            for (int x = 0; x < kernel8u.cols; ++x)
                if (kernel8u.at<uchar>(y, x) != 0)
                    processing += format("PROCESS(%d,%d)", y, x);
    
        static const char * const op2str[] = { "OP_ERODE", "OP_DILATE", NULL, NULL, "OP_GRADIENT", "OP_TOPHAT", "OP_BLACKHAT" };
    
        char cvt[2][50];
        int wdepth = std::max(depth, CV_32F), scalarcn = cn == 3 ? 4 : cn;
    
        if (actual_op < 0)
            actual_op = op;
    
        std::vector<ocl::Kernel> kernels(iterations);
        for (int i = 0; i < iterations; i++)
        {
            int current_op = iterations == i + 1 ? actual_op : op;
            String buildOptions = format("-D RADIUSX=%d -D RADIUSY=%d -D LSIZE0=%d -D LSIZE1=%d -D %s%s"
                                         " -D PROCESS_ELEMS=%s -D T=%s -D DEPTH_%d -D cn=%d -D T1=%s"
                                         " -D convertToWT=%s -D convertToT=%s -D ST=%s%s",
                                         anchor.x, anchor.y, (int)localThreads[0], (int)localThreads[1], op2str[op],
                                         doubleSupport ? " -D DOUBLE_SUPPORT" : "", processing.c_str(),
                                         ocl::typeToStr(type), depth, cn, ocl::typeToStr(depth),
                                         ocl::convertTypeStr(depth, wdepth, cn, cvt[0]),
                                         ocl::convertTypeStr(wdepth, depth, cn, cvt[1]),
                                         ocl::typeToStr(CV_MAKE_TYPE(depth, scalarcn)),
                                         current_op == op ? "" : cv::format(" -D %s", op2str[current_op]).c_str());
    
            kernels[i].create("morph", ocl::imgproc::morph_oclsrc, buildOptions);
            if (kernels[i].empty())
                return false;
        }
    
        UMat src = _src.getUMat(), extraMat = _extraMat.getUMat();
        _dst.create(src.size(), src.type());
        UMat dst = _dst.getUMat();
    
        if (iterations == 1 && src.u != dst.u)
        {
            Size wholesize;
            Point ofs;
            src.locateROI(wholesize, ofs);
            int wholecols = wholesize.width, wholerows = wholesize.height;
    
            if (haveExtraMat)
                kernels[0].args(ocl::KernelArg::ReadOnlyNoSize(src), ocl::KernelArg::WriteOnlyNoSize(dst),
                            ofs.x, ofs.y, src.cols, src.rows, wholecols, wholerows,
                            ocl::KernelArg::ReadOnlyNoSize(extraMat));
            else
                kernels[0].args(ocl::KernelArg::ReadOnlyNoSize(src), ocl::KernelArg::WriteOnlyNoSize(dst),
                            ofs.x, ofs.y, src.cols, src.rows, wholecols, wholerows);
    
            return kernels[0].run(2, globalThreads, localThreads, false);
        }
    
        for (int i = 0; i < iterations; i++)
        {
            UMat source;
            Size wholesize;
            Point ofs;
    
            if (i == 0)
            {
                int cols =  src.cols, rows = src.rows;
                src.locateROI(wholesize, ofs);
                src.adjustROI(ofs.y, wholesize.height - rows - ofs.y, ofs.x, wholesize.width - cols - ofs.x);
                if(src.u != dst.u)
                    source = src;
                else
                    src.copyTo(source);
    
                src.adjustROI(-ofs.y, -wholesize.height + rows + ofs.y, -ofs.x, -wholesize.width + cols + ofs.x);
                source.adjustROI(-ofs.y, -wholesize.height + rows + ofs.y, -ofs.x, -wholesize.width + cols + ofs.x);
            }
            else
            {
                int cols =  dst.cols, rows = dst.rows;
                dst.locateROI(wholesize, ofs);
                dst.adjustROI(ofs.y, wholesize.height - rows - ofs.y, ofs.x, wholesize.width - cols - ofs.x);
                dst.copyTo(source);
                dst.adjustROI(-ofs.y, -wholesize.height + rows + ofs.y, -ofs.x, -wholesize.width + cols + ofs.x);
                source.adjustROI(-ofs.y, -wholesize.height + rows + ofs.y, -ofs.x, -wholesize.width + cols + ofs.x);
            }
            source.locateROI(wholesize, ofs);
    
            if (haveExtraMat && iterations == i + 1)
                kernels[i].args(ocl::KernelArg::ReadOnlyNoSize(source), ocl::KernelArg::WriteOnlyNoSize(dst),
                    ofs.x, ofs.y, source.cols, source.rows, wholesize.width, wholesize.height,
                    ocl::KernelArg::ReadOnlyNoSize(extraMat));
            else
                kernels[i].args(ocl::KernelArg::ReadOnlyNoSize(source), ocl::KernelArg::WriteOnlyNoSize(dst),
                    ofs.x, ofs.y, source.cols, source.rows, wholesize.width, wholesize.height);
    
            if (!kernels[i].run(2, globalThreads, localThreads, false))
                return false;
        }
    
        return true;
    }

    opencv cv::hal::morph

    void morph(int op, int src_type, int dst_type,
               uchar * src_data, size_t src_step,
               uchar * dst_data, size_t dst_step,
               int width, int height,
               int roi_width, int roi_height, int roi_x, int roi_y,
               int roi_width2, int roi_height2, int roi_x2, int roi_y2,
               int kernel_type, uchar * kernel_data, size_t kernel_step,
               int kernel_width, int kernel_height, int anchor_x, int anchor_y,
               int borderType, const double borderValue[4], int iterations, bool isSubmatrix)
    {
        {
            bool res = halMorph(op, src_type, dst_type, src_data, src_step, dst_data, dst_step, width, height,
                                roi_width, roi_height, roi_x, roi_y,
                                roi_width2, roi_height2, roi_x2, roi_y2,
                                kernel_type, kernel_data, kernel_step,
                                kernel_width, kernel_height, anchor_x, anchor_y,
                                borderType, borderValue, iterations, isSubmatrix);
            if (res)
                return;
        }
    
        CV_IPP_RUN_FAST(ippMorph(op, src_type, dst_type, src_data, src_step, dst_data, dst_step, width, height,
                                roi_width, roi_height, roi_x, roi_y,
                                roi_width2, roi_height2, roi_x2, roi_y2,
                                kernel_type, kernel_data, kernel_step,
                                kernel_width, kernel_height, anchor_x, anchor_y,
                                borderType, borderValue, iterations, isSubmatrix));
    
        ocvMorph(op, src_type, dst_type, src_data, src_step, dst_data, dst_step, width, height,
                 roi_width, roi_height, roi_x, roi_y,
                 roi_width2, roi_height2, roi_x2, roi_y2,
                 kernel_type, kernel_data, kernel_step,
                 kernel_width, kernel_height, anchor_x, anchor_y,
                 borderType, borderValue, iterations);
    }

    代码参考:opencv3_4_1opencv-3.4.1modulesimgprocsrcmorph.cpp

    ##############################################

    QQ 3087438119
  • 相关阅读:
    Discrete Logging
    P1378 油滴扩展
    P3390 【模板】矩阵快速幂
    RMQ算法
    P1372 又是毕业季I
    P1440 求m区间内的最小值
    高效判断素数方法
    阿尔贝喝我
    浙江大学PAT上机题解析之2-11. 两个有序链表序列的合并
    顺序队列之C++实现
  • 原文地址:https://www.cnblogs.com/herd/p/15421862.html
Copyright © 2020-2023  润新知