我正在尝试在图像上应用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自己处理这些区域。非常感谢任何帮助
答案 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);