Accord Framework中2D互相关后零频分量中心化问题求助
Implementing
fftshift Equivalent for 2D Cross-Correlation in Accord Framework (C#) 我之前用Accord Framework做2D频域互相关时,也碰到过找不到fftshift的问题!确实Accord没有提供现成的这个函数,但它的核心逻辑很直观,我们完全可以自己实现一个,完美匹配MATLAB中fftshift的中心化效果。
先搞懂fftshift的核心逻辑
2D场景下,fftshift的作用就是把位于矩阵左上角的零频分量(也就是互相关的峰值位置)移到矩阵中心,本质是交换矩阵的四个象限:
- 左上角象限 ↔ 右下角象限
- 右上角象限 ↔ 左下角象限
如果矩阵的行/列数是奇数,还要单独处理中间的行和列。
自定义实现FFTShift方法
下面是针对Accord Framework Complex[,]类型的实现,兼容奇偶尺寸的矩阵:
using Accord.Math; using Accord.Math.ComplexNumbers; public static class FftHelper { public static Complex[,] FFTShift(Complex[,] input) { int rows = input.GetLength(0); int cols = input.GetLength(1); Complex[,] shifted = new Complex[rows, cols]; // 计算半尺寸,自动适配奇偶情况 int halfRows = rows / 2; int halfCols = cols / 2; // 交换左上 ↔ 右下象限 for (int i = 0; i < halfRows; i++) { for (int j = 0; j < halfCols; j++) { shifted[i + halfRows, j + halfCols] = input[i, j]; shifted[i, j] = input[i + halfRows, j + halfCols]; } } // 交换右上 ↔ 左下象限 for (int i = 0; i < halfRows; i++) { for (int j = halfCols; j < cols; j++) { shifted[i + halfRows, j - halfCols] = input[i, j]; shifted[i, j] = input[i + halfRows, j - halfCols]; } } // 处理奇数行数的中间行 if (rows % 2 != 0) { int midRow = halfRows; for (int j = 0; j < halfCols; j++) { shifted[midRow, j + halfCols] = input[midRow, j]; shifted[midRow, j] = input[midRow, j + halfCols]; } } // 处理奇数列数的中间列 if (cols % 2 != 0) { int midCol = halfCols; for (int i = 0; i < halfRows; i++) { shifted[i + halfRows, midCol] = input[i, midCol]; shifted[i, midCol] = input[i + halfRows, midCol]; } } return shifted; } }
集成到你的互相关流程中
按照你给出的互相关公式,在完成逆傅里叶变换后,直接调用这个自定义方法就能实现中心化,和MATLAB的流程完全对齐:
// 假设 aPadded 和 bPadded 是补零后的Complex[,]输入矩阵 Complex[,] fftA = Fft2(aPadded); // 使用Accord的2D FFT方法 Complex[,] fftB = Fft2(bPadded); // 计算频域共轭相乘 Complex[,] fftProduct = Elementwise.Multiply(fftA, fftB.Conjugate()); // 逆傅里叶变换得到原始互相关结果 Complex[,] corrResult = Ifft2(fftProduct); // 应用FFTShift实现中心化,和MATLAB的fftshift效果一致 Complex[,] centeredCorr = FftHelper.FFTShift(corrResult);
额外注意点
- Accord的
Fft2和Ifft2方法默认输出的零频分量位置和MATLAB一致(左上角),所以这个自定义实现完全兼容。 - 如果需要对FFT的输出先做shift再处理,直接把
fftProduct传入FFTShift即可,逻辑是一样的。
内容的提问来源于stack exchange,提问作者Trion
相关产品推荐
相关产品推荐

