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

조회 수: 5 (최근 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 CenterFile Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기

제품


릴리스

R2019a

Community Treasure Hunt

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

Start Hunting!

Translated by