Есть несколько вещей, которые вы можете сделать, чтобы сделать ваш код более эффективным, хотя некоторые из них зависят от того, что именно вы хотите в итоге, и от того, какие предположения вы можете сделать относительно кругов (например, могут ли они перекрываться? Много ли подобных радиусы?).
Ниже приведено решение, которое предполагает, что между радиусами очень мало повторений, а координаты центра всегда являются целочисленными значениями пикселей.
%# image
dim_x = 1000;
dim_y = 1000;
A=rand(dim_x,dim_y);
%# center positions and ...
c = [222 111; 878 112; 81 718; 89 112; 222 111; 878 112; 81 718; 89 112; 222 111; 878 112; 81 718; 89 112; 222 111; 878 112; 81 718; 89 112; 222 111; 878 112; 81 718; 89 112];
%#... radii of the circles
r = [10 33 55 2 22 10 33 55 2 22 10 33 55 2 22 10 33 55 2 22];
%# find the largest circle...
rMax = max(r);
%#... and create a distance array
distFromCenterSquared = bsxfun(@plus,(-rMax:rMax).^2,transpose(-rMax:rMax).^2);
%# now we can loop over the radii to create the logical mask for all circles
mask = false(dim_x,dim_y); %# initialize inside the loop if you want one circle at a time
for i=1:length(r)
%# create logical mini-circle mask
miniMask = distFromCenterSquared(rMax-r(i)+1:end-(rMax-r(i)),rMax-r(i)+1:end-(rMax-r(i)))...
< r(i)^2;
%# add to the mask. The ranges need to be fixed, obviously, if
%# circles can be only partially inside the image
%# also, the "or" is only necessary if you're adding to
%# a mask, instead of recreating it each iteration
mask(c(i,1)-r(i):c(i,1)+r(i),c(i,2)-r(i):c(i,2)+r(i)) = ...
mask(c(i,1)-r(i):c(i,1)+r(i),c(i,2)-r(i):c(i,2)+r(i)) | ...
miniMask;
end
Кстати: если у вас есть непересекающиеся круги, вы можете использовать bwlabel
после цикла (или использовать find и sub2ind для записи i
в отдельные круги), так что вы можете обрабатывать все круги в одном перейти с использованием accumarray
.