美文网首页
高效实现卷积运算

高效实现卷积运算

作者: coolTigers | 来源:发表于2020-04-27 00:49 被阅读0次

    假设有如下锐化公式:
    sharpened_pixel = 5 * current - left - right - up - down
    代码实现如下:

    void Sharpen(const cv::Mat& image, cv::Mat& result)
    {
    #ifndef _USE_KERNEL
        result.create(image.size(), image.type());
        int nchannels = image.channels();
    
        for (int i = 1; i < image.rows - 1; i++) {
            const uchar* previous = image.ptr<const uchar>(i - 1); // 上一行
            const uchar* current = image.ptr<const uchar>(i); // 当前行
            const uchar* next = image.ptr<const uchar>(i + 1); // 下一行
            uchar* output = result.ptr<uchar>(i);
            for (int j = 0; j < (image.cols - 1) * nchannels; j++) {
                // 应用锐化算子
                *output++ = cv::saturate_cast<uchar>(
                    5 * current[j] - current[j - nchannels] - current[j + nchannels] - previous[j] - next[j]);
            }
        }
        result.row(0).setTo(cv::Scalar(0));
        result.row(result.rows - 1).setTo(cv::Scalar(0));
        result.col(0).setTo(cv::Scalar(0));
        result.col(result.cols - 1).setTo(cv::Scalar(0));
        return;
    #endif // !_USE_KERNEL
        cv::Mat kernel(3,3,CV_32F, Scalar(0));
        kernel.at<float>(1, 1) = 5.0;
        kernel.at<float>(0, 1) = -1.0;
        kernel.at<float>(2, 1) = -1.0;
        kernel.at<float>(1, 0) = -1.0;
        kernel.at<float>(1, 2) = -1.0;
        cout << image.depth() << endl;
        cv::filter2D(image, result, image.depth(), kernel);
    }
    

    其中卷积函数:

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

    src :输入图像
    dst:输出图像
    ddepth:目标图像的期望深度
    kernel:卷积核
    anchor:内核的锚点,表示内部经过过滤的点的相对位置内核;锚应该位于内核内;默认值(-1,-1)表示锚点在内核中心
    delta:offset值,默认为0
    borderType:边界填充的类型,在滤波的过程中,会根据滤波器的尺寸在图像的边界填充一定的数量的像素值,以保证输入与输出具有相同的尺寸,这个参数指定边界填充的规则;目前支持一下几种规则

    enum BorderTypes {
        BORDER_CONSTANT    = 0, //!< `iiiiii|abcdefgh|iiiiiii`  with some specified `i`
        BORDER_REPLICATE   = 1, //!< `aaaaaa|abcdefgh|hhhhhhh`
        BORDER_REFLECT     = 2, //!< `fedcba|abcdefgh|hgfedcb`
        BORDER_WRAP        = 3, //!< `cdefgh|abcdefgh|abcdefg`
        BORDER_REFLECT_101 = 4, //!< `gfedcb|abcdefgh|gfedcba`
        BORDER_TRANSPARENT = 5, //!< `uvwxyz|abcdefgh|ijklmno`
    
        BORDER_REFLECT101  = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101
        BORDER_DEFAULT     = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101
        BORDER_ISOLATED    = 16 //!< do not look outside of ROI
    };
    

    参考博客:https://cloud.tencent.com/developer/article/1350371

    相关文章

      网友评论

          本文标题:高效实现卷积运算

          本文链接:https://www.haomeiwen.com/subject/fpcewhtx.html