OpenCV中的Conv2函数

4
我正在进行图像处理工作,需要知道在c++ OpenCV中与Matlab的conv2等效的函数。
我找到了此链接,但它不符合我的要求。
我遇到的问题是,我需要用一个二维double数组对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}  
};

谢谢您。

2个回答

5

解决方案

使用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执行的是相关操作而不是卷积操作? - RAM
不,来自OpenCV文档:“filter2D-使用卷积核对图像进行卷积。” - ibezito
但是在同一份文档中,它的说明是:“该函数实际上计算的是相关性,而不是卷积:也就是说,核心不会围绕锚点进行镜像翻转。如果您需要一个真正的卷积,请使用flip()翻转核心,并将新的锚点设置为(kernel.cols - anchor.x - 1, kernel.rows - anchor.y - 1)。”那这个怎么样呢? - RAM

4

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

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 );
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接