从元胞数组中提取内容
Extract contents from cell array
我有一系列图像,存储在数组 A 中。因此 A 的每个条目都包含一个图像(矩阵)。所有矩阵大小相同。
现在我想提取特定位置(像素)的值,但我目前的做法似乎很慢,我认为可能有更好的方法来做。
% Create data that resembles my problem
N = 5
for i = 1:N
A{i} = rand(5,5);
end
% my current approach
I = size(A{1},1);
J = size(A{1},2);
val = zeros(N,1);
for i = 1:I
for j = 1:J
for k = 1:N
B(k) = A{k}(i,j);
end
% do further operations on B for current i,j, don't save B
end
end
我在想应该有一些方法可以遵循 A{:}(i,j)
或 vertcat(A{:}(i,j))
但两者都会导致
??? Bad cell reference operation.
我正在使用 Matlab2008b。
有关详细信息,我之后在 B 上使用 fft。
以下是 Cris
的回答结果
| Code | # images | Extracting Values | FFT | Overall |
|--------------|----------|-------------------|----------|-----------|
| Original | 16 | 12.809 s | 19.728 s | 62.884 s |
| Original | 128 | 105.974 s | 23.242 s | 177.280 s |
| ------------ | -------- | ----------------- | ------- | --------- |
| Answer | 16 | 42.122 s | 27.382 s | 104.565 s |
| Answer | 128 | 36.807 s | 26.623 s | 102.601 s |
| ------------ | -------- | ----------------- | ------- | --------- |
| Answer (mod) | 16 | 14.772 s | 27.797 s | 77.784 s |
| Answer (mod) | 128 | 13.637 s | 28.095 s | 83.839 s |
答案代码 mod 改为 double(squeeze(A(i,j,:)));
因为没有双倍 FFT 花费的时间更长。
答案 (mod) 使用 double(A(i,j,:));
所以改进似乎真的适用于更大的图像集,但是我目前计划每个 运行 处理 ~ 500 张图像。
更新
用profile
函数测量,using/omitting挤压的结果
| Code | # Calls | Time |
|--------------------------------|---------|----------|
| B = double(squeeze(A(i,j,:))); | 1431040 | 36.325 s |
| B= double(A(i,j,:)); | 1431040 | 14.289 s |
A{:}(i,j)
不起作用,因为 A{:}
是一个以逗号分隔的元素列表,等同于 A{1},A{2},A{3},...A{end}
。索引到这样的数组是没有意义的。
为了加快您的操作速度,我建议您从数据中创建一个 3D 矩阵,如下所示:
A3 = cat(3,A{:});
当然,这只有在 A
的所有元素都具有相同大小(如问题中最初指定的那样)时才有效。
现在您可以像这样快速访问数据:
for i = 1:I
for j = 1:J
B = squeeze(A3(i,j,:));
% do further operations on B for current i,j, don't save B
end
end
根据您应用于每个 B
的操作,您也可以对这些操作进行向量化。
编辑: 因为你将 fft
应用到每个 B,你也可以在没有循环的情况下获得它:
B_fft = fft(A3,[],3); % 3 is the dimension along which to apply the FFT
我有一系列图像,存储在数组 A 中。因此 A 的每个条目都包含一个图像(矩阵)。所有矩阵大小相同。
现在我想提取特定位置(像素)的值,但我目前的做法似乎很慢,我认为可能有更好的方法来做。
% Create data that resembles my problem
N = 5
for i = 1:N
A{i} = rand(5,5);
end
% my current approach
I = size(A{1},1);
J = size(A{1},2);
val = zeros(N,1);
for i = 1:I
for j = 1:J
for k = 1:N
B(k) = A{k}(i,j);
end
% do further operations on B for current i,j, don't save B
end
end
我在想应该有一些方法可以遵循 A{:}(i,j)
或 vertcat(A{:}(i,j))
但两者都会导致
??? Bad cell reference operation.
我正在使用 Matlab2008b。
有关详细信息,我之后在 B 上使用 fft。
以下是 Cris
的回答结果| Code | # images | Extracting Values | FFT | Overall |
|--------------|----------|-------------------|----------|-----------|
| Original | 16 | 12.809 s | 19.728 s | 62.884 s |
| Original | 128 | 105.974 s | 23.242 s | 177.280 s |
| ------------ | -------- | ----------------- | ------- | --------- |
| Answer | 16 | 42.122 s | 27.382 s | 104.565 s |
| Answer | 128 | 36.807 s | 26.623 s | 102.601 s |
| ------------ | -------- | ----------------- | ------- | --------- |
| Answer (mod) | 16 | 14.772 s | 27.797 s | 77.784 s |
| Answer (mod) | 128 | 13.637 s | 28.095 s | 83.839 s |
答案代码 mod 改为 double(squeeze(A(i,j,:)));
因为没有双倍 FFT 花费的时间更长。
答案 (mod) 使用 double(A(i,j,:));
所以改进似乎真的适用于更大的图像集,但是我目前计划每个 运行 处理 ~ 500 张图像。
更新
用profile
函数测量,using/omitting挤压的结果
| Code | # Calls | Time |
|--------------------------------|---------|----------|
| B = double(squeeze(A(i,j,:))); | 1431040 | 36.325 s |
| B= double(A(i,j,:)); | 1431040 | 14.289 s |
A{:}(i,j)
不起作用,因为 A{:}
是一个以逗号分隔的元素列表,等同于 A{1},A{2},A{3},...A{end}
。索引到这样的数组是没有意义的。
为了加快您的操作速度,我建议您从数据中创建一个 3D 矩阵,如下所示:
A3 = cat(3,A{:});
当然,这只有在 A
的所有元素都具有相同大小(如问题中最初指定的那样)时才有效。
现在您可以像这样快速访问数据:
for i = 1:I
for j = 1:J
B = squeeze(A3(i,j,:));
% do further operations on B for current i,j, don't save B
end
end
根据您应用于每个 B
的操作,您也可以对这些操作进行向量化。
编辑: 因为你将 fft
应用到每个 B,你也可以在没有循环的情况下获得它:
B_fft = fft(A3,[],3); % 3 is the dimension along which to apply the FFT