我已经看过这个问题fftshift/ifftshift C/C++ source code
我正在尝试从matlab实现fftshift
这是来自matlab* 函数的代码 *,用于1D数组
numDims = ndims(x);
idx = cell(1, numDims);
for k = 1:numDims
m = size(x, k);
p = ceil(m/2);
idx{k} = [p+1:m 1:p];
end
y = x(idx{:});
我的c++/openCV代码是,fftshift基本上是交换某个枢纽位置的值。
因为我似乎不明白如何在opencv中为复数构建矩阵。
这里说
http://docs.opencv.org/modules/core/doc/operations_on_arrays.html#dft
复共轭对称
我想把复数分成真实的和虚数,交换它们,然后合并成一个矩阵会更容易。
cv::vector<float> distanceF (f.size());
//ff = fftshift(ff);
cv::Mat ff;
cv::dft(distanceF, ff, cv::DFT_COMPLEX_OUTPUT);
//Make place for both the complex and the real values
cv::Mat planes[] = {cv::Mat::zeros(distanceF.size(),1, CV_32F), cv::Mat::zeros(distanceF.size(),1, CV_32F)};
cv::split(ff, planes); // planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))
int numDims = ff.dims;
for (int i = 0; i < numDims; i++)
{
int m = ff.rows;
int p = ceil(m/2);
}
我的问题是,因为我对DFT的输入是vector<float>
,我似乎无法创建平面矩阵来拆分复数?
你能想到一个更好的方法来交换cv::mat数据结构中的值吗?
8条答案
按热度按时间waxmsbnn1#
好的,这个线程可能是过时的同时,但可能对其他用户。.看看示例:
(第66 - 80行)
我认为这是一个简短而清晰的方式为不同的维度。
mtb9vblg2#
我知道,这是一个相当老的线程,但我发现它今天在寻找一个解决方案,以转移fft-result.也许我写的小函数的帮助下,这个网站和其他来源,可以帮助未来的读者搜索网络,并最终在这里了。
pod7payv3#
使用adjustROI和copyTo代替.at()怎么样?它肯定会更高效:
行中的内容(对于一维情况):
对于2D情况,应再添加两行,并修改行范围...
nwnhqdif4#
我一直在根据这篇文章自己实现它,我用的是Fabian实现,工作正常。但有一个问题,当有奇数行或列时,移位就不正确。
然后,您需要填充矩阵,然后,删除多余的行或列。
ca1c2owp5#
下面是我所做的(快速和肮脏,可以优化):
tuwxkamq6#
以下内容供将来参考:经过测试,对于1D具有位精度
6yt4nkrj7#
在前面的答案中,没有任何实现可以正确处理奇数大小的图像。
fftshift
将原点从左上方移动到中心(在size/2
处)。ifftshift
将原点从中心移动到左上方。这两个操作对于偶数尺寸是相同的,但对于奇数尺寸是不同的。对于奇数大小,
fftshift
将前(size+1)/2
个像素与剩余的size/2
个像素交换,这会将索引为0的像素移动到size/2
。ifftshift
执行相反的操作,用剩下的(size+1)/2
像素交换第一个size/2
像素。这段代码是我能想到的这两个操作的最简单的实现。(请注意,如果size
为偶数,则(size+1)/2 == size/2
为偶数。)这段代码将整个图像复制两次,但实现起来简单快捷。一个性能更好的实现是就地交换值。This answer有正确的代码在一行上执行此操作,它必须应用于图像的每一列和每一行。
pprl5pva8#
在Matlab的实现中,主要代码有两行:
第一个获取相对于原始索引的正确索引顺序;然后第二个按照索引顺序对输出数组赋值,因此,如果你想重写Matlab的实现而不进行数据交换,你需要分配一个新的数组并对数组赋值。