数据:假设我有一个2000行乘500列矩阵(图像)
我需要:计算64行的FFT乘以上列数据的10列。换句话说,我想计算在整个数据矩阵中运行的64X10窗口的FFT。 FFT结果用于计算标量值(比如峰值幅度频率),用于创建新的“FFT值”图像。
现在,我需要最终的FFT图像与原始数据(2000 X 500)相同。
在MATLAB中实现这一目标的最快方法是什么?我目前正在使用相对较慢的循环。我还使用插值将最终图像调整为原始数据大小。
答案 0 :(得分:2)
正如@EitanT指出的那样,您可以使用blockproc
进行图像J.
的批处理块处理。但是您应该将函数句柄定义为
fun = @(block_struct) fft2(block_struct.data);
B = blockproc(J, [64 10], fun);
对于[2000 x 500]
矩阵,这将为您提供复数傅立叶值的[2000 x 500]
输出,在具有{{1的本地支持(FFT输入的大小)的子采样像素位置处进行评估}}。现在,用单个值替换这些值,例如使用峰值对数幅度,您可以进一步指定
[64 x 10]
然后输出是块补丁值的[2000/64 x 500/10]输出,您可以通过最近邻插值(或其他更平滑的版本)将其调整为所需的[2000 x 500]原始值大小
fun = @(block_struct) max(max(log(abs(fft2(block_struct.data)))));
B = blockproc(J, [64 10], fun);
我可以提供一个真实的图片示例,如果它会进一步帮助。
更新:要获得重叠的阻止,您可以使用C = imresize(B, [2000 500], 'nearest');
的{{1}}选项设置重叠'Bordersize'
,以便最终的窗口大小为{{ 1}}仍然是[64,10]的大小。示例:
blockproc
但是,这可以保留完整的傅里叶响应,而不是上面带有[V H]
的单值版本。
另请参阅此帖子,了解如何使用[M + 2*V, N + 2*H]
Dealing with “Really Big” Images: Block Processing进行过滤。
答案 1 :(得分:1)
如果要在较大矩阵中的各个不同块上应用相同的函数(在您的情况下,二维傅里叶变换),您可以使用blkproc
函数执行此操作,该函数将在较新的位置替换MATLAB由blockproc
发布。
但是,我推断您希望以“滑动窗口”方式对重叠块应用fft2
。为此,您可以将colfilt
与'sliding'
选项一起使用。请注意,我们在每个块上应用的函数是fft:
block_size = [64, 10];
temp_size = 5 * block_size;
col_func = @(x)cellfun(@(y)max(max(abs(fft2(y)))), num2cell(x, 1), 'Un', 0);
B = colfilt(A, block_size, 10 * block_size, 'sliding', col_func);
这是如何工作的? colfilt
通过将每个“滑动”块重新排列到新临时矩阵的单独列中来处理矩阵A
,然后将col_func
应用于此新矩阵。 col_func
依次将每列恢复为原始块并在其上应用fft2
,为每列返回最大幅度值。
需要注意的重要事项:
由于这个提到的临时矩阵包括所有可能的“滑动”块,因此内存可能是一种限制。因此,为了在计算中使用更少的内存,colfilt
将原始矩阵A
分解为temp_size
的子矩阵,并分别对每个矩阵执行计算。当然,结果矩阵B仍然是相同的。
结果矩阵B
中的每个元素都是从相应的块邻域计算出来的。图像越大,处理的块越多,因此计算时间将以几何方式增加。我相信你必须等待很长时间,直到MATLAB完成处理2000 x 500矩阵上的所有滑动窗口。