【问题标题】:Conv2 in opencvopencv中的Conv2
【发布时间】: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}  
};

谢谢。

【问题讨论】:

    标签: c++ matlab opencv


    【解决方案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 );
    }
    

    【讨论】:

      猜你喜欢
      • 2013-04-14
      • 1970-01-01
      • 2022-10-06
      • 1970-01-01
      • 2015-09-17
      • 1970-01-01
      • 2013-04-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多