Trying to speed up a circle machine
4 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Hello All,
I have an algorithm that will draw a circle for each x and y pair, with a given a radius, within an arbitrary image dimension. I am trying to find overlapping pairs with the given radius.
The algorithm completion time increases with the number of particles. I am trying to find a way to decrease the completion time while keeping the number of coordinates pairs high. It would be great if I could have it run ~2000 pairs for ~10 seconds. Currently, it seems to be ~2000 pairs with about ~20 seconds. The bottle neck is in the first for loop as shown below.
The code is below. I am just stuck on how to revamp the code to make it run faster and I don't know of any resources which I can use to help. I am running with these parameters shown below and with the attached particle list.
Matlab '9.2.0.556344 (R2017a)' Intel® Core™ i5-4200M CPU @ 2.50 GHz RAM 8 GB
>> [C, keepers, overlapXY] = circleMachine_help(1024,6,pkList);
Elapsed time is 22.674214 seconds.
Elapsed time is 0.014354 seconds.
function [C, keepers, overlapXY] = circleMachine_help(imageSize,rejectRadius,pkList)
% Create the grid
[xx, yy] = meshgrid(1:imageSize);
% C = false(imageSize,imageSize);
C = zeros(imageSize,imageSize);
tic
% Create the circles on the grid
for n=1:size(pkList,1)
C = C + ...
(sqrt((xx-pkList(n,1)).^2+(yy-pkList(n,2)).^2)<=rejectRadius);
end
toc
% list of pks that overlap
overlapXY = zeros(size(pkList,1),2);
keepers = zeros(size(overlapXY,1),2);
tic
% Check to find particles which overlap if not put them on a keepers list
for n=1:size(pkList,1)
OverLapImage = C(...
pkList(n,2)-rejectRadius:pkList(n,2)+rejectRadius,...
pkList(n,1)-rejectRadius:pkList(n,1)+rejectRadius);
if isempty(OverLapImage(OverLapImage > 1)) == 0
overlapXY(n,:) = pkList(n,:);
else
keepers(n,:) = pkList(n,:);
end
end
toc
% clean up overlapXY and keeprs
overlapXY(overlapXY(:,1) == 0 & overlapXY(:,2) == 0,:) = [];
keepers(keepers(:,1) == 0 & keepers(:,2) == 0,:) = [];
% display image
figure;
imagesc(C);
hold on;
scatter(overlapXY(:,1),overlapXY(:,2),20,'r');
scatter(keepers(:,1),keepers(:,2),8,'g');
title(['Circles of original pkList.' ...
'Reds are overlaps and green are keepers.']);
hold off;
0 Kommentare
Antworten (3)
Rik
am 13 Sep. 2017
You can replace the first loop with this strategy: generate a logical the correct image size, set the center coordinates of each circle to true. Now you can create a structuring element and apply a dilate operation. I don't now if it is indeed faster, but I think it is.
A down-side to this is that if your centers are not integer values, this will return a different matrix. You could solve this by first running the first part for integer positions, and then doing the rest with your original loop.
If you encounter problems writing the code, just let me know.
0 Kommentare
Guillaume
am 13 Sep. 2017
I don't have matlab on this machine to test but replacing your circle creation loop with just
pkList2 = permute(pkList, [3 2 1]);
C = sum(hypot(xx - pkList(1, 1, :), yy - pkList(1, 2, :) <= rejectRadius, 3);
would probably be faster, at the expense of memory usage. The above requires a temporary matrix of size imageSize x ImageSize x size(pkList, 1).
Note that I'm using hypot instead of hand calculating the radial distance. It probably does not make a difference to speed (but is much easier on the eyes). For a probably infinitesimal speed boost, you could remove the sqrt calculation and instead compare to the square of rejectRadius.
Another option for massively boosting your loop would be to just do the comparison over
xx(max(pkList(n, 2)-rejectRadius, 1) : min(pkList(n, 2)+rejectRadius, imageSize),
max(pkList(n, 1)-rejectRadius, 1) : min(pkList(n, 1)-rejectRadius, imageSize))
%same for yy
Instead of testing imageSize x imageSize points at each step of the loop, only test rejectRadius^2 x rejectRadius^2 points around your centre. The others are guaranteed to be outside the circle.
0 Kommentare
bdatko
am 14 Sep. 2017
2 Kommentare
Image Analyst
am 14 Sep. 2017
How do we call that code? You didn't give us input values for rejectRadius,pkListMaxInt,imageSize so we don't know what to pass to the function. The mat file has this
pkListMaxInt: [1945×3 single]
but what about the other inputs???
Siehe auch
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
