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

发布于 2024-12-11 03:11:58 字数 1377 浏览 0 评论 0原文

我一直在使用函数文件[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);

下面我想显示省略号ifoverlap==0,和'ifoverlap==1',减少a和b,直到出现是没有交集。最后,imshow 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 图中的图片。 (任意两个椭圆之间不相交)

I've been using a function file [ret]=drawellipse(x,y,a,b,angle,steps,color,img). Calling the function through a script file to draw random ellipses in image. But once i set the random center point(x,y), and random a, b, there is high possibility that the ellipses intersection would occur. How can i prevent the intersection? (I'm supposed to draw the ellipses that are all separate from each other)
Well, over here i have a function file which is to check whether the ellipses got overlap or not,overlap = overlap_ellipses(x0,y0,a0,b0,angle0,x1,y1,a1,b1,angle1). If the two ellipses are overlap, then the 'overlap=1', otherwise 'overlap=0'.
Based on all these, i tested in the command window:

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);

The following i want to dispaly the ellipses if overlap==0, and 'if overlap==1', decrease the a and b, till there is no intersection. Lastly, to imshow the img.

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

For me now, i have difficulty in coding the middle part. How can i use the if statement to get the value of overlap and how to make the index corresponding to the ellipse i need to draw.

i tested a bit like

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

it returns

overlap=0
overlap=0
overlap=1

it is not [0 0 1]. I can't figure it out, thus stuck in the process.
The final image shoule look like the picture in this voronoi diagram of ellipses.
(There is no intersection between any two ellipses)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

刘备忘录 2024-12-18 03:11:58

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

或者,您可以将图像分割成矩形(不一定大小相等),并在每个矩形中放置一个椭圆,选择 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)?

Assuming you are drawing the ellipses into a raster graphics image, you could calculate the pixels you would have to draw for an ellipse, check whether these pixels in the image are still of the background color, and draw the ellipse only if the answer is yes, otherwise reject it (because something else, i.e. another ellipse, is in the way) and try other x,y,a and b.

Alternatively, you could split your image into rectangles (not neccessarily of equal size) and place one ellipse in each of those, picking x,y,a,b such that no ellipse exceeds its rectangle - then the ellipses cannot overlap either, but it depends on how much "randomness" your ellipse placing should have whether this suffices.

The mathematically rigorous way would be to store x,y,a,b of each drawn ellipse and for each new ellipse, do pairwise checks with each of those whether they have common points by solving a system of two quadratic equations. However, this might be a bit complicated, especially once the angle is not 0.

Edit in response to the added code: Instead of fixing all x's and y's before the loop, you can determine them inside the loop. Since you know how many ellipses you want, but not how many you have to sample, you need a while loop. The test loop you give may come in handy, but you need to compare all previous ellipses to the one created in the loop iteration, not the first one.

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

Of course, if a and b are fixed, it may happen that no ellipse fits the image dimensions if the already present ones are unfortunately placed, resulting in an infinite loop.
Regarding your plan of leaving the center fixed and decreasing the ellipse's size until it fits: where does your overlap_ellipses method come from? Maybe itcan be adapted to return a factor by which one ellipse needs to be shrinked to fit next to the other (and 1 if it fits already)?

红尘作伴 2024-12-18 03:11:58

@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(红色)将被跳过,因为它与前面的其中一个重叠,其余的依此类推......

The solution proposed by @arne.b (the first one) is a good way to rasterize non-overlapping ellipses.

Let me illustrate that idea with an example. I will be extending my 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

Note how the overlap test is performed in the order the ellipses are added, thus after Line1 (blue) and Line2 (green) are drawn, Line3 (red) will be skipped because it overlaps one of the previous ones, and so on for the rest...

白云悠悠 2024-12-18 03:11:58

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

One option is to keep track of all the ellipses already drawn, and to make sure the next set of [x,y,a,b] does not produce a new ellipse which intersects with the existing ones. You can either invoke random numbers until you come up with a set that fulfills the condition, or once you have a set which violates the condition, decrease the values of a and/or b until no intersection occurs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文