How to optimise/vectorize loop containing the function "imrotate", using multiple images and angles as input

2 views (last 30 days)
I have approximately 900 B&W images (k) which I have to rotate 360 degrees with steps of 0.25 degrees (i). I use two loops and the function imrotate. The process time is 30-60 min, which I would like to optimise/vectorize to make it faster.
Any suggestion?
I have pasted my code:
for i = 1:360*4
for k =1:numReg
D=sum(imrotate(Subim{k},i/4)); %rotate B&W image k by 0.25 degrees
DD=D(D>0); %find column with pixels
DDD(i,k)=sum(DD(1:3)); %find sum of pixels in the first 3 columns containing pixels.
end
end
[~,Y]=max(DDD); %find rotation which result in maximum pixel sum.
figure, hist(Y/4,60) % plot distribution of angles resulting in max sum

Accepted Answer

Matt J
Matt J on 3 Dec 2013
Your code doesn't make too much sense to me, but it looks like you're re-inventing the RADON command, in various places.

More Answers (2)

Sean de Wolski
Sean de Wolski on 3 Dec 2013
Edited: Sean de Wolski on 3 Dec 2013
  • Do you have the parallel computing toolbox? If so, this might be something well-suited for parfor. I.e. you can do all 360deg rotations on one worker at once and return just the results you need.
  • I agree with Matt as well, this could be something radon might be able to handle.
  • Also, if you're just trying to maximize the number of pixels, you might be able to start with a smaller number of rotations and then refine it. I.e. only rotate integer degrees, pick the five that maximize this, and look closely near them.
  • Also (2), are the images related to each other? Can you reuse information obtained from one image to look near that point in the next?
  2 Comments
Oliver Woodford
Oliver Woodford on 4 Dec 2013
For such simple, batch-job-style for loops, you don't even need the PCT to parallelize this across cores or even other PCs. There are several alternatives on the FEX: 13775, 44077, 44128. However, if you only have one PC the speedup will depend on how parallelized the code already is; if imrotate is already multi-threaded this approach won't be much better.
jesper
jesper on 4 Dec 2013
Thanks, the radon is a great solution for my purpose.
I do not have parallel-toolbox.
Also a good idea to start with few numbers and refine, I will do that next time when radon can not help me:-)

Sign in to comment.


Oliver Woodford
Oliver Woodford on 3 Dec 2013
Assuming your 900 input images are all the same size, you could:
  1. For each rotation angle, compute the location of each rotated pixel in the original image.
  2. Concatenate all the sample locations for each pixel and angle into a long vector.
  3. Sample each image at all these locations at once, using a fast image interpolation method from the file exchange, e.g. 20342, 24183 or 23795 ( very fast, but requires an nVidia gpu).
  4. Reshape the output samples to the correct shape, and do your computation on all the angles simultaneously.
  5. Repeat steps 3 and 4 for each image.
  2 Comments
Oliver Woodford
Oliver Woodford on 3 Dec 2013
If you have the Parallel Computing Toolbox and R2013b you can load the sample locations onto the GPU once, then use interp2 (only optimized in R2013b) to compute the rotations for each image, and it will be even faster.
Oliver Woodford
Oliver Woodford on 4 Dec 2013
You could also avoid sampling outside the bounds of the original image, and use accumarray for the sum, for a further speed up.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!