Matlab:如何避免图像中的椭圆重叠?

时间:2011-10-20 09:06:50

标签: image matlab ellipse

我一直在使用函数文件[ret]=drawellipse(x,y,a,b,angle,steps,color,img)。通过脚本文件调用函数以在图像中绘制随机椭圆。但是一旦我设置了随机中心点(x,y)和随机a,b,很可能会出现椭圆交点。我该如何防止交叉? (我应该画出彼此分开的椭圆) 好吧,在这里我有一个函数文件,用于检查省略号是否重叠,overlap = overlap_ellipses(x0,y0,a0,b0,angle0,x1,y1,a1,b1,angle1)。如果两个椭圆重叠,则'overlap = 1',否则'overlap = 0'。 基于所有这些,我在命令窗口中进行了测试:

x=rand(4,1)*400;  % x and y are the random coodinates for the center of ellipses
y=rand(4,1)*400;
a=[50 69 30 60];  % major axis   for a and b, i intend to use random also in the future
b=[20 40 10 40];  % minor axis
angle=[30 90 45 0]; % angle of ellipse
steps=10000;
color=[255 0 0];   % inputs for another function file to draw the ellipse
img=zeros(500,500,3);

以下我想显示省略号if overlap==0和'if overlap == 1',减少a和b,直到没有交集。最后,要简化img。

for i=1:length(x)
img=drawellipse(x(i),y(i),a(i),b(i),angle(i),steps,color,img);
end

对我来说,我很难对中间部分进行编码。我如何使用if语句获取overlap的值以及如何使索引对应于我需要绘制的椭圆。

我测试了一下像

for k=1:(length(x)-1)
overlap = overlap_ellipses(x(1),y(1),a(1),b(1),angle(1),x(1+k),y(1+k),a(1+k),b(1+k),angle(1+k))
end

它返回

overlap=0
overlap=0
overlap=1

不是[0 0 1]。我无法弄清楚,因此陷入了这个过程。 最终的图像看起来像这个voronoi diagram of ellipses中的图片。 (任何两个椭圆之间没有交叉点)

3 个答案:

答案 0 :(得分:3)

假设您正在将椭圆绘制成光栅图形图像,您可以计算要为椭圆绘制的像素,检查图像中的这些像素是否仍然是背景颜色,并仅在以下情况下绘制椭圆:答案是肯定的,否则拒绝它(因为其他东西,即另一个椭圆,挡路)并尝试其他xyab

或者,您可以将图像分割成矩形(不一定是相同大小),并在每个图像中放置一个椭圆,选择x,y,a,b,使椭圆不超过其矩形 - 然后椭圆也不会重叠,但这取决于你的椭圆放置应该有多少“随机性”,这是否足够。

数学上严谨的方法是存储每个绘制椭圆的x,y,a,b,并且对于每个新椭圆,通过求解两个二次方程组,对每个椭圆进行成对检查。但是,这可能有点复杂,特别是一旦角度不是0。

编辑以响应添加的代码:您可以在循环内确定它们,而不是在循环之前修复所有xy。既然您知道需要多少个省略号,而不知道需要多少省略号,则需要while循环。您给出的测试循环可能派上用场,但您需要将所有先前的省略号与循环迭代中创建的省略号进行比较,而不是第一次。

i=1;
while (i<=4) %# or length(a), or, more elegantly, some pre-defined max
    x(i) = rand*400; y(i) = rand*400; %# or take x and y as givren and decrease a and b
    %# now, check overlap for given center
    overlap = false;
    for k=1:(i-1)
       overlap = overlap || overlap_ellipses(x(i),y(i),a(i),b(i),angle(i),x(k),y(k),a(k),b(k),angle(k))
    end
    if (~overlap)
        img = drawellipse(x(i),y(i),a(i),b(i),angle(i),steps,color,img);
        i = i+1; %# determine next ellipse
    end %# else x(i) and y(i) will be overwritten in next while loop iteration
end

当然,如果ab是固定的,可能会发生这样的情况,即如果已经存在的椭圆不幸放置,则椭圆不适合图像尺寸,从而导致无限循环。 关于你离开中心的计划是否固定并减小椭圆的大小直到它适合:你的overlap_ellipses方法来自哪里?也许它可以被调整为返回一个因子,一个椭圆需要缩小以适合另一个椭圆(如果它已经适合,则为1)?

答案 1 :(得分:1)

一个选项是跟踪已绘制的所有椭圆,并确保下一组[x,y,a,b]不会产生与现有椭圆相交的新椭圆。你可以调用随机数,直到你找到一个满足条件的集合,或者一旦你有一个违反条件的集合,减少a和/或b的值,直到没有交集发生

答案 2 :(得分:1)

@arne.b(第一个)提出的解决方案是栅格化非重叠椭圆的好方法。

让我用一个例子说明这个想法。我将扩展我的previous answer

%# color image
I = imread('pears.png');
sz = size(I);

%# parameters of ellipses
num = 7;
h = zeros(1,num);
clr = lines(num);             %# color of each ellipse
x = rand(num,1) .* sz(2);     %# center x-coords
y = rand(num,1) .* sz(1);     %# center y-coords
a = rand(num,1) .* 200;       %# major axis length
b = rand(num,1) .* 200;       %# minor axis length
angle = rand(num,1) .* 360;   %# angle of rotation

%# label image, used to hold rasterized ellipses
BW = zeros(sz(1),sz(2));

%# randomly place ellipses one-at-a-time, skip if overlaps previous ones
figure, imshow(I)
axis on, hold on
for i=1:num
    %# ellipse we would like to draw directly on image matrix
    [ex,ey] = calculateEllipse(x(i),y(i), a(i),b(i), angle(i), 100);

    %# lets plot the ellipse (overlayed)
    h(i) = plot(ex,ey, 'LineWidth',2, 'Color',clr(i,:));

    %# create mask for image pixels inside the ellipse polygon
    mask = poly2mask(ex,ey,sz(1),sz(2));

    %# get the perimter of this mask
    mask = bwperim(mask,8);

    %# skip if there is an existing overlapping ellipse
    if any( BW(mask)~=0 ), continue, end

    %# use the mask to place the ellipse in the label image
    BW(mask) = i;
end
hold off
legend(h, cellstr(num2str((1:num)','Line%d')), 'Location','BestOutside')    %'

%# set pixels corresponding to ellipses using specified colors
clr = im2uint8(clr);
II = I;
for i=1:num
    BW_ind = bsxfun(@plus, find(BW==i), prod(sz(1:2)).*(0:2));
    II(BW_ind) = repmat(clr(i,:), [size(BW_ind,1) 1]);
end
figure, imshow(II, 'InitialMagnification',100, 'Border','tight')

all_overlayed_ellipses rasterized_nonoverlapping_ellipses

注意如何按照添加椭圆的顺序执行重叠测试,因此在绘制Line1(蓝色)和Line2(绿色)之后,将跳过Line3(红色),因为它与之前的一个重叠,因此其余的......