计算圆内的黑色像素

时间:2015-05-23 11:16:09

标签: matlab image-processing geometry pixel binary-image

我有一个半径向量和数百个[X,Y]坐标的第二个向量。对于每个可能的坐标半径对,我在输入二进制图像上计算一个圆(其中心位于坐标中)内的所有黑色像素。

最快的方法是什么?我唯一的想法是迭代图像的每个像素,检查圆方程,然后检查像素颜色,但它似乎没有为数百个这样的操作进行优化。

2 个答案:

答案 0 :(得分:1)

这是一个实现:

  

<强>优点:

     
      
  • loopsmeshgrid/ndgrid。而是使用更快bsxfunpdist2

  •   
  • 即使圆圈重叠,点数也只计算一次。

  •   
  • 使用变量radius(所有圆的半径不相同)

  •   

<强>代码:

%// creating a binary image with little black dots
A = randi(600,256); 
imbw = A ~= 1;

%// Your binary image with black dots
imshow(imbw);

%// getting the index of black dots
[dotY, dotX] = find(~imbw);

nCoords = 10;               %// required number of circles

%// generating its random coordinates as it is unknown here
Coords = randi(size(A,1),nCoords,2);

%// calculating the distance from each coordinate with every black dots
out = pdist2(Coords,[dotX, dotY]).';  %//'

%// Getting only the black dots within the radius
%// using 'any' avoids calculating same dot twice
radius = randi([10,25],1,size(Coords,1));
pixelMask = any(bsxfun(@lt, out, radius),2);
nPixels = sum(pixelMask);

%// visualizing the results by plotting
hold on
scatter(dotX(pixelMask),dotY(pixelMask));
viscircles([Coords(:,1),Coords(:,2)],radius.');    %//'
hold off

<强>输出:

>> nPixels

nPixels =

19

enter image description here

答案 1 :(得分:1)

由于矩阵语法,Matlab非常适合处理图像。它也适用于索引,所以大多数时候你可以避免&#34;迭代像素&#34; (虽然有时候你仍然需要)。

不是检查每个圆圈内的所有像素,而是必须检测两次像素的计数,另一种方法是创建一个与您的图像大小相同的遮罩。为每个圆圈清空此蒙版(因此重叠的像素只会被删除&#39;一次),然后在原始图片上应用蒙版并计算剩余的照明像素。

举个例子,我必须采取一些样本数据,图像:

source

treesBW

20个随机点/圆坐标(您可以轻松更改点数和最小/最大半径):

load trees
BW = im2bw(X,map,0.4);
imshow(BW)

然后我们建立你的自定义面具:

%// still building sample data
s = size(BW) ;
npt = 20 ; Rmin=5 ; Rmax=20 ; %// problem constants

x = randi([1 s(2)]   ,npt,1); %// random X coordinates
y = randi([1 s(1)]   ,npt,1); %//        Y
r = randi([Rmin Rmax],npt,1); %// radius size between 5 to 20 pixels.

bubbles

然后你只需应用面具并计算:

%// create empty mask with enough overlap for the circles on the border of the image
mask = false( s+2*Rmax ) ; 

%// prepare grid for a sub-mask of pixels, as wide as the maximum circle
xmask = -Rmax:Rmax ; 
[xg,yg] = ndgrid(xmask,xmask) ;
rg = sqrt( (xg.^2+yg.^2) ) ;    %// radius of each pixel in the subgrid

for ip=1:npt
    mrow = xmask+Rmax+y(ip) ;  %// calc coordinates of subgrid on original mask
    mcol = xmask+Rmax+x(ip) ;  %// calc coordinates of subgrid on original mask

    cmask = rg <= r(ip) ;      %// calculate submask for this radius
    mask(mrow,mcol) = mask(mrow,mcol) | cmask ; %// apply the sub-mask at the x,y coordinates
end
%// crop back the mask to image original size (=remove border overlap)
mask = mask(Rmax+1:end-Rmax,Rmax+1:end-Rmax) ;
imshow(mask)

treeMasked