opencv中的Conv2

Posted

技术标签:

【中文标题】opencv中的Conv2【英文标题】:Conv2 in opencv 【发布时间】:2017-06-12 05:21:23 【问题描述】:

我正在研究图像处理,需要知道 c++ OpenCV 中 Matlab 的 conv2 等价物。 我找到了this link,但它不符合我的要求。

我面临的问题是我需要用二维双数组对 Mat 图像进行卷积,而上面的链接中没有给出这种情况。

matlab代码为:

img = conv2(img1,Mx,'same')

在哪里

Mx =   
  0, 0, 0, 0, 0, 0 ,   
  0, -0.0003, -0.0035, 0, 0.0035, 0.0003 ,   
  0, -0.0090, -0.0903, 0, 0.0903, 0.0090 , 
  0, -0.0229, -0.2292, 0, 0.2292, 0.0229 ,   
  0, -0.0090, -0.0903, 0, 0.0903, 0.0090 ,   
  0, -0.0003, -0.0035, 0, 0.0035, 0.0003  
;

谢谢。

【问题讨论】:

【参考方案1】:

解决方案

使用 OpenCV 的 filter2D 函数。

代码示例

//initializes matrix
cv::Mat mat = cv::Mat::ones(50, 50, CV_32F); 

//initializes kernel
float  Mx[36] =  0, 0, 0, 0, 0, 0 ,
     0, -0.0003, -0.0035, 0, 0.0035, 0.0003  ,
     0, -0.0090, -0.0903, 0, 0.0903, 0.0090  ,
     0, -0.0229, -0.2292, 0, 0.2292, 0.0229  ,
     0, -0.0090, -0.0903, 0, 0.0903, 0.0090  ,
     0, -0.0003, -0.0035, 0, 0.0035, 0.0003 
;
cv::Mat kernel(6, 6, CV_32F, Mx);

//convolove
cv::Mat dst;
cv::filter2D(mat, dst, mat.depth(), kernel);

【讨论】:

但我听说,Filter2D 做的是相关性,而不是卷积? 否,来自 OpenCV 文档:“filter2D - 将图像与内核卷积。” 但是在同一个文档中,它被给出为:“该函数实际上计算的是相关性,而不是卷积:也就是说,内核不是围绕锚点镜像的。如果你需要一个真正的卷积,使用 flip() 翻转内核并将新锚设置为 (kernel.cols - anchor.x - 1, kernel.rows - anchor.y - 1)。"那怎么办?【参考方案2】:

这是我的尝试,我不确定它是否准确,但对于极少量的测试数据,它对我有用:

enum Conv2DShape 
    FULL,
    SAME,
    VALID,
;

Mat conv2D( const Mat& input, const Mat& kernel, const Conv2DShape shape )
    Mat flipped_kernel;
    flip( kernel, flipped_kernel, -1 );

    Point2i pad;
    Mat result, padded;

    switch( shape ) 
        case SAME:
            padded = input;
            pad = Point2i( 0, 0 );
            break;

        case VALID:
            padded = input;
            pad = Point2i( kernel.cols - 1, kernel.rows - 1);
            break;

        case FULL:
            pad = Point2i( kernel.cols - 1, kernel.rows - 1);
            copyMakeBorder( input, padded, pad.y, pad.y, pad.x, pad.x, BORDER_CONSTANT );
            break;

        default:
            throw runtime_error("Unsupported convolutional shape");
    

    Rect region = Rect( pad.x / 2, pad.y / 2, padded.cols - pad.x, padded.rows - pad.y);
    filter2D( padded, result , -1, flipped_kernel, Point(-1, -1), 0, BORDER_CONSTANT );

    return result( region );

【讨论】:

以上是关于opencv中的Conv2的主要内容,如果未能解决你的问题,请参考以下文章

Keras 中的 conv2d 和 Conv2D 有啥区别?

如何正确从 keras 中的 Conv2D 获取层权重?

PyTorch中的Conv2d使用

如何访问 tf.layers.conv2d 中的内核变量?

Python中的2D卷积类似于Matlab的conv2

python中的一维卷积conv1d和二维卷积conv2d