How to create 2D sub arrays by sampling every n by n points

3 ビュー (過去 30 日間)
Yiwu Ding
Yiwu Ding 2019 年 12 月 10 日
コメント済み: Adam Danz 2019 年 12 月 12 日
Hi, I want to create 2D sub arrays by sampling every n by n points. Specifically, I have an array with size of 280x280. I want to sample every 8 by 8 points and form a 3D array with size of (35,35,64).
Currently I am using loop (refer to below) which takes abut 0.25msec on my Laptop. I am wondering if there is a more elegent and faster way to create the 3D array by taking advantage of matlab internal indexing capability.
Thank you!
%%%%%
%A=rand(280,280);
A = double(imread('AT3_1m4_01.tif'));
A = A(1:1:280,1:1:280)/256;
B=zeros(35,35,64);
numIter=1000;
tic
for iter=1:numIter
for i=1:1:8
for j=1:1:8
indx1=(i-1)*8+j;
B(:,:,indx1)=A(i:8:end,j:8:end);
end
end
end
disp(toc/numIter);
figure(1); montage(B);
%%%%%%%%%%%%%%%%%%%%%%%%%%

採用された回答

Yiwu Ding
Yiwu Ding 2019 年 12 月 10 日
Thank you all for your comments and time.
Referring to the following updated code, was able to improve the code speed from 0.25msec to 0.14msec by using the vector indexing.
Note iter of 1000 is used to get more accurate timing for single run.
Plots are used for data verification.
close all;
clear;
%A=rand(280,280);
A = double(imread('AT3_1m4_01.tif'));
A = A(1:1:280,1:1:280)/256;
B=zeros(35,35,64);
%%%%Approach#1 iteration
numIter=1000;
tic
for iter=1:numIter
for i=1:1:8
for j=1:1:8
indx1=(i-1)*8+j;
B(:,:,indx1)=A(i:8:end,j:8:end);
end
end
end
toc
disp('Approach#1 time: single iter')
disp(toc/numIter);
figure(1); montage(B);
%%%%%%%%%%%%%%%%%%%%%
%%%%Approach#2 vector indexing
tic
for iter=1:numIter
rngY=1:280;
rngY_permute=reshape(rngY,8,35);
rngY_permute=rngY_permute';
B1=A(rngY_permute,rngY_permute);
B2=reshape(B1,35,8,35,8);
B3=permute(B2,[1,3,4,2]);
B4=reshape(B3,35,35,64);
end
toc
disp('Approach#2 time: single iter')
disp(toc/numIter);
figure(2); montage(B4);
figure(3); montage(B4-B); title('\Delta');
max(max(max(abs(B4-B))))
  1 件のコメント
Adam Danz
Adam Danz 2019 年 12 月 12 日
You're adding the iter-loop just to add extra time to your computation for whatever reason. There are much better ways to building in time if you need to add delays.
You could use a timer function or the pause() command. Both offer much better control over timing and much less computational cost than this "Approach #2" .
This is not a good solution to your problem.

サインインしてコメントする。

その他の回答 (2 件)

Ridwan Alam
Ridwan Alam 2019 年 12 月 10 日
B = reshape(A,35,35,[]);
  2 件のコメント
Adam Danz
Adam Danz 2019 年 12 月 10 日
The indexing isn't consecutive, though.
B(:,:,indx1)=A(i:8:end,j:8:end);
Adam Danz
Adam Danz 2019 年 12 月 10 日
B = permute(A,dimorder) rearranges the dimensions of A. The loop in the OP's code is extracting every 8 rows and every 8 columns so it's not clear to me how permute() would help.

サインインしてコメントする。


Adam Danz
Adam Danz 2019 年 12 月 10 日
編集済み: Adam Danz 2019 年 12 月 10 日
The iter-loop is completely unnecessary and is merely doing the same exact work 1000 times.
numIter=1000;
tic
% for iter=1:numIter Remove this line
for i=1:1:8
for j=1:1:8
indx1=(i-1)*8+j;
B(:,:,indx1)=A(i:8:end,j:8:end);
end
end
% end Remove this line
Removing that reduces the processing time to 0.000047 sec. Since you're indexing non-consecutively, the loop method (without the iter-loop) will be quite fast and I doubt an ugly vectorized approach will be faster.

カテゴリ

Help Center および File ExchangeMatrix Indexing についてさらに検索

製品


リリース

R2019a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by