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

1 回表示 (過去 30 日間)
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

採用された回答

Matt J
Matt J 2013 年 12 月 3 日
Your code doesn't make too much sense to me, but it looks like you're re-inventing the RADON command, in various places.
  1 件のコメント
jesper
jesper 2013 年 12 月 4 日
Thanks, I was not aware of RADON. However, Radon is perfect for my purpose

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

その他の回答 (2 件)

Sean de Wolski
Sean de Wolski 2013 年 12 月 3 日
編集済み: Sean de Wolski 2013 年 12 月 3 日
  • 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 件のコメント
Oliver Woodford
Oliver Woodford 2013 年 12 月 4 日
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 2013 年 12 月 4 日
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:-)

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


Oliver Woodford
Oliver Woodford 2013 年 12 月 3 日
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 件のコメント
Oliver Woodford
Oliver Woodford 2013 年 12 月 3 日
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 2013 年 12 月 4 日
You could also avoid sampling outside the bounds of the original image, and use accumarray for the sum, for a further speed up.

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

Community Treasure Hunt

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

Start Hunting!

Translated by