sepFilter2D Opencv出乎意料的结果

时间:2014-02-20 18:59:55

标签: c++ matlab opencv image-processing

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

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

  

Kernel = ones(n);
      没有zeropadding的conv 2的%             LimgLarge = padarray(Limg,[n n],'circular');
         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自己处理这些区域。

非常感谢任何帮助

2 个答案:

答案 0 :(得分:0)

由于您说您只是在显示的代码段之前加载图像,因此我可以看到两个潜在的缺陷。

首先,如果您在加载源图片和代码片段之间不执行任何操作,那么您的源图像将是一个8位图像,因为您设置了函数参数{{1对ddepth,您还要求一个8位目标图像。

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

您可以尝试使用以下行:

ddepth

第二次,检查您是否使用标记sepFilter2D(m_logImage,m_filteredImage,CV_32F,m_kernelX,m_kernelY,Point(-1,-1),0,BORDER_REPLICATE); 加载了源图像,以便它只有一个频道而不是三个。

答案 1 :(得分:0)

我一行一行地跟着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,点(-1,-1),0,BORDER_REPLICATE);

     

m_filteredImage = m_filteredImage /(m_kernelSize * m_kernelSize);