高效实现卷积运算

2020-04-27  本文已影响0人  coolTigers

假设有如下锐化公式:
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

上一篇下一篇

猜你喜欢

热点阅读