【问题标题】:sepFilter2D Opencv unexpected resultssepFilter2D Opencv 意外结果
【发布时间】:2014-03-21 22:38:21
【问题描述】:

我正在尝试在图像上应用 8X8 可分离均值滤波器 过滤器是 2D 可分离的。

我正在从 Matlab 转换以下代码,

内核 = 个(n);
% for conv 2 without zeropadding
LimgLarge = padarray(Limg,[n n],'圆形');
LimgKer = conv2(LimgLarge,Kernel,'same')/(n^2);
LKerCorr = LimgKer(n+1:end-n,n+1:end-n);

第一次我用过滤器大小填充图像,然后关联 2d,最后裁剪图像区域。

现在,我正在尝试使用 opencv 在 C++ 中实现相同的功能

我已经加载了图像,然后调用了以下命令:

m_kernelSize = 8;   
m_kernelX = Mat::ones(m_kernelSize,1,CV_32FC1);
m_kernelX = m_kernelX / m_kernelSize;

m_kernelY = Mat::ones(1,m_kernelSize,CV_32FC1);
m_kernelY = m_kernelY / m_kernelSize;

sepFilter2D(m_logImage,m_filteredImage,m_logImage.depth(),m_kernelX,m_kernelY,Point(-1,-1),0,BORDER_REPLICATE);

我希望得到相同的结果,但我仍然从 Matlab 得到完全不同的结果。

我宁愿不填充图像,进行关联,最后再次裁剪图像,我希望使用 BORDER_REPLICATE 参数得到相同的结果。

顺便说一句,我知道 copyMakeBorder 函数,但不使用它,因为 sepFilter2D 自己处理区域。

【问题讨论】:

  • 能否上传原图、matlab结果和OpenCV结果?
  • 当然可以,但这需要我几个小时,你可以使用任何虚拟图像来代替
  • 定义“不同的结果”
  • 这些不是数值差异,算法差异很大,我会尽快更新帖子

标签: c++ matlab opencv image-processing


【解决方案1】:

既然你说你只是在你展示的代码 sn-p 之前加载图像,我可以看到两个潜在的缺陷。

首先,如果您在加载源图像和您的代码 sn-p 之间什么都不做,那么您的源图像将是一个 8 位图像,并且由于您设置了函数参数 @ 987654322@ 到 m_logImage.depth(),您还请求 8 位目标图像。

但是,在阅读了documentation of sepFilter2D 之后,我不确定这是src.depth() 和ddepth 的有效组合。

您可以尝试使用以下行吗:

sepFilter2D(m_logImage,m_filteredImage,CV_32F,m_kernelX,m_kernelY,Point(-1,-1),0,BORDER_REPLICATE);

第二,检查您是否使用标志CV_LOAD_IMAGE_GRAYSCALE 加载了源图像,以便它只有一个通道而不是三个。

【讨论】:

    【解决方案2】:

    我一行一行地跟着Matlab,错误在别的地方。

    不管怎样,下面两个方法返回的结果是一样的

    使用 8X8 过滤器

    // Big filter mode - now used only for debug mode 
    m_kernel = Mat::ones(m_kernelSize,m_kernelSize,type);
    cv::Mat LimgLarge(m_logImage.rows + m_kernelSize*2, m_logImage.cols + m_kernelSize*2,m_logImage.depth());
    cv::copyMakeBorder(m_logImage, LimgLarge, m_kernelSize, m_kernelSize,
        m_kernelSize, m_kernelSize, BORDER_REPLICATE);
    
    // Big filter 
    filter2D(LimgLarge,m_filteredImage,LimgLarge.depth(),m_kernel,Point(-1,-1),0,BORDER_CONSTANT );
    m_filteredImage = m_filteredImage /  (m_kernelSize*m_kernelSize); 
    
    cv::Rect roi(cv::Point(0+m_kernelSize,0+m_kernelSize),cv::Point(m_filteredImage.cols-m_kernelSize, m_filteredImage.rows-m_kernelSize));
    cv::Mat croppedImage = m_filteredImage(roi);
    m_diffImage = m_logImage - croppedImage;
    

    第二种方法,使用可分离的8x8过滤器

    sepFilter2D(m_logImage,m_filteredImage,m_logImage.depth(),m_kernelX,m_kernelY,Point(-1,-1),0,BORDER_REPLICATE);

    m_filteredImage = m_filteredImage / (m_kernelSize*m_kernelSize);

    【讨论】:

      猜你喜欢
      • 2015-04-30
      • 2012-10-09
      • 2018-09-04
      • 2017-06-02
      • 2021-11-11
      • 2019-03-23
      • 1970-01-01
      • 1970-01-01
      • 2016-01-30
      相关资源
      最近更新 更多