2

数据:假设我有一个 2000 行 x 500 列的矩阵(图片)

我需要什么:通过上述数据的 10 列块计算 64 行的 FFT。换句话说,我想计算在整个数据矩阵中运行的 64X10 窗口的 F​​FT。FFT 结果用于计算标量值(例如峰值幅度频率),用于创建新的“FFT 值”图像。

现在,我需要最终的 FFT 图像与原始数据 (2000 X 500) 大小相同。

在 MATLAB 中完成此任务的最快方法是什么?我目前正在使用相对较慢的 for 循环。我还使用插值将最终图像调整为原始数据大小。

4

2 回答 2

2

正如@EitanT 指出的那样,您可以blockproc用于图像的批处理块J.但是您应该将函数句柄定义为

fun = @(block_struct) fft2(block_struct.data);
B = blockproc(J, [64 10], fun);

对于[2000 x 500]矩阵,这将为您提供[2000 x 500]复数傅立叶值的输出,在局部支持(FFT 的输入大小)为 的子采样像素位置进行评估[64 x 10]。现在,要将这些值替换为单个值,例如峰值对数幅度,您可以进一步指定

fun = @(block_struct) max(max(log(abs(fft2(block_struct.data)))));
B = blockproc(J, [64 10], fun);

然后输出是块补丁值的 [2000/64 x 500/10] 输出,您可以通过最近邻插值(或其他更平滑的版本)将其大小调整为所需的 [2000 x 500] 原始大小

C = imresize(B, [2000 500], 'nearest');

如果它会进一步帮助,我可以包含一个真实的图像示例。

更新:要获得重叠块,您可以通过设置重叠使用'Bordersize'选项,以便最终窗口大小仍为 [64, 10] 大小。例子:blockproc[V H][M + 2*V, N + 2*H]

fun = @(block_struct) log(abs(fft2(block_struct.data)));
V = 16; H = 3; % overlap values
overlap = [V H]; 
M = 32; N = 4; % non-overlapping values
B1 = blockproc(J, [M N], fun, 'BorderSize', overlap); % final windows are 64 x 10

但是,这将保持完整的傅立叶响应,而不是上面的单值版本max(max())

另请参阅这篇文章,了解如何使用blockproc:处理“真正大”的图像进行过滤:块处理

于 2012-09-10T23:13:36.390 回答
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对其应用,返回每列的最大幅度值。

需要注意的重要事项:

  1. 由于这个提到的临时矩阵包括所有可能的“滑动”块,内存可能是一个限制。因此,为了在计算中使用更少的内存,colfilt将原始矩阵A分解为 的子矩阵temp_size,并分别对每个子矩阵进行计算。当然,生成的矩阵 B 仍然是相同的。

  2. 结果矩阵中的每个元素B都是根据相应的块邻域计算的。图像越大,需要处理的块就越多,因此计算时间将呈几何级数增加。我相信您必须等待一段时间,直到 MATLAB 处理完您的 2000×500 矩阵上的所有滑动窗口。

于 2012-09-10T22:54:39.623 回答