c++ - 基于 OpenCV DFT 的卷积被移位

标签 c++ opencv filtering fft dft

我尝试在基于 this OpenCV example 的频谱中实现图像过滤来自文档并为方便起见复制在这里:

void convolveDFT(InputArray A, InputArray B, OutputArray C)
{
  C.create(abs(A.rows - B.rows)+1, abs(A.cols - B.cols)+1, A.type());
  Size dftSize;
  // calculate the size of DFT transform
  dftSize.width = getOptimalDFTSize(A.cols + B.cols - 1);
  dftSize.height = getOptimalDFTSize(A.rows + B.rows - 1);

  // allocate temporary buffers and initialize them with 0's
  Mat tempA(dftSize, A.type(), Scalar::all(0));
  Mat tempB(dftSize, B.type(), Scalar::all(0));

  // copy A and B to the top-left corners of tempA and tempB, respectively
  Mat roiA(tempA, Rect(0,0,A.cols,A.rows));
  A.copyTo(roiA);
  Mat roiB(tempB, Rect(0,0,B.cols,B.rows));
  B.copyTo(roiB);

  // now transform the padded A & B in-place;
  // use "nonzeroRows" hint for faster processing
  dft(tempA, tempA, 0, A.rows);
  dft(tempB, tempB, 0, B.rows);

  // multiply the spectrums;
  // the function handles packed spectrum representations well
  mulSpectrums(tempA, tempB, tempA);

  // transform the product back from the frequency domain.
  // Even though all the result rows will be non-zero,
  // you need only the first C.rows of them, and thus you
  // pass nonzeroRows == C.rows
  dft(tempA, tempA, DFT_INVERSE + DFT_SCALE, C.rows);

  // now copy the result back to C.
  tempA(Rect(0, 0, C.cols, C.rows)).copyTo(C);
}

我使用 Lena 图像作为 A(512x512) 和身份过滤器(除了中心的所有条目设置为 0)作为 B(41x41)。


Original filtered

图像的底部和右侧部分似乎被裁剪了。此外,虽然由于 SO 格式而在此处不可见,但过滤后的图像比原始图像小(因为函数的第一行)。

如何修改代码,使其像 filter2D 函数一样过滤图像?所以在这种情况下,结果将是原始图像。

最佳答案

卷积结果的大小应该是A.cols + B.cols - 1 by A.rows + B.rows - 1(就像getOptimalDFTSize 调用)。所以,为了得到完整的卷积结果,例子的第一行应该改为:

C.create(A.rows + B.rows - 1, A.cols + B.cols - 1, A.type());

这应该会为您提供一个比原始图像稍大的结果图像,包括一个与卷积尾部相对应的边界(过滤在此处向上和向下倾斜)。

filter2D另一方面不返回完整的卷积,因为输出仅限于与原始图像大小相同的图像,删除了卷积尾部。为此,filter2D 假定一个线性内核,它沿列和 (B.rows - 1) 引入了 (B.cols - 1)/2 的偏移)/2 沿行。因此,可以使用以下方法提取过滤后的图像:

C.create(A.rows, A.cols, A.type());
...
tempA(Rect((B.cols-1)/2, (B.rows-1)/2, A.cols, A.rows).copyTo(C);

关于c++ - 基于 OpenCV DFT 的卷积被移位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43306576/

相关文章:

c++ - 如何在 Qt/C++ 中创建属性绑定(bind)?

android - 如何使用级联分类器减少错误识别

c++ - 如何使用 Opencv 2.3 更改灰度图像的像素值?

c++ - 具有通用类型函数的动态库 [c++]

c++ - 可以将空字符串文字传递给用户定义的原始文字运算符吗?

c++ - 从 matlab 代码创建静态库

php - 在 Windows 下安装 OpenCV 作为 php 扩展

reactjs - 使用 react-data-table-component 过滤数据表

sql - 查询过滤,在灵活性和易于执行之间找到平衡

javascript - 在对象数组中,返回任何值与特定字符串匹配的对象