1

我一直在使用函数文件[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,'如果重叠==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 椭圆图中的图片。(任何两个椭圆之间没有交集)

4

3 回答 3

3

假设您正在将椭圆绘制到光栅图形图像中,您可以计算您必须为椭圆绘制的像素,检查图像中的这些像素是否仍然是背景颜色,只有在答案是肯定的情况下才绘制椭圆, 否则拒绝它(因为其他东西,即另一个椭圆,在路上)并尝试其他x,y和.ab

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

数学上严格的方法是存储每个绘制的椭圆的 x,y,a,b,并且对于每个新椭圆,通过求解两个二次方程的系统,对它们中的每一个进行成对检查它们是否具有共同点。但是,这可能有点复杂,尤其是当角度不为 0 时。

编辑以响应添加的代码:您可以在循环内确定它们,而不是在循环之前修复所有x' 和'。y由于您知道需要多少个椭圆,但不知道必须采样多少个,因此您需要一个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)?

于 2011-10-20T11:07:19.280 回答
1

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

于 2011-10-20T11:06:13.990 回答
1

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

让我用一个例子来说明这个想法。我将扩展我之前的答案

%# 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(红色),因为它与之前的其中一个重叠,依此类推休息...

于 2011-10-25T23:52:09.073 回答