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

5 visualizzazioni (ultimi 30 giorni)
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);
%%%%%%%%%%%%%%%%%%%%%%%%%%

Risposta accettata

Yiwu Ding
Yiwu Ding il 10 Dic 2019
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 Commento
Adam Danz
Adam Danz il 12 Dic 2019
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.

Accedi per commentare.

Più risposte (2)

Ridwan Alam
Ridwan Alam il 10 Dic 2019
B = reshape(A,35,35,[]);
  2 Commenti
Adam Danz
Adam Danz il 10 Dic 2019
The indexing isn't consecutive, though.
B(:,:,indx1)=A(i:8:end,j:8:end);
Adam Danz
Adam Danz il 10 Dic 2019
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.

Accedi per commentare.


Adam Danz
Adam Danz il 10 Dic 2019
Modificato: Adam Danz il 10 Dic 2019
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.

Prodotti


Release

R2019a

Community Treasure Hunt

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

Start Hunting!

Translated by