2011-10-20 20 views
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)。 2つの楕円が重複している場合は 'overlap = 1'、それ以外の場合は 'overlap = 0'です。 は、これらすべてに基づいて、私は、コマンドウィンドウでテスト:Matlab:イメージに楕円が重ならないようにする方法は?

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

を交差部分が存在しなくなるまで「重複== 1の場合は、」、AとBを減らす以下は、私が楕円if overlap==0をdispalyにしたい、と。最後に、imgをimgします。

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

私にとって、私は中間部分をコーディングするのが難しいです。 if文を使用してoverlapの値を取得する方法と、描画する必要がある楕円に対応するインデックスを作成する方法

iはビット

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 

ように試験し、それが[0 0 1]ない

overlap=0 
overlap=0 
overlap=1 

を返します。私はそれを把握することができないので、プロセスに固執しています。 最終的なイメージシャウルは、このvoronoi diagram of ellipsesの画像のように見えます。

答えて

1

@arne.b(最初のもの)によって提案された解決策は、重複しない楕円をラスタライズするのに適した方法です。

例をあげて説明しましょう。 、オーバーラップ試験をこうしてライン1(青色)と回線2(緑色)が描画された後、楕円が追加された順序で実行される方法

%# 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

注:私は私のprevious answerを拡張しますLine3(赤)は前のものの1つと重複しているのでスキップされます。残りの部分についても同様に続きます...

1

1つのオプションは、既に描画されている楕円をすべて追跡し、次のセット[x,y,a,b]が既存の楕円と交差する新しい楕円を生成しないようにすることです。条件を満たすセットが出るまで乱数を呼び出すか、条件に違反するセットを取得したら、交差が発生しなくなるまでaおよび/またはbの値を減らします。

+0

私のスクリプトファイルでは、forループを使って一度に楕円を描画します。 'img'、彼らは同時に出てくるだろう。どのように私はそれらを1つずつ追跡することができますか? – Elsie

3

楕円をラスターグラフィックスイメージに描画すると仮定すると、楕円を描画する必要があるピクセルを計算し、イメージ内のこれらのピクセルが依然として背景色であるかどうかを確認し、答えは「はい」です。それ以外の場合は拒否します(他の楕円が途中にあるため)。xyabを試してください。

また、画像を矩形に分割して(同じサイズでなくてもかまいません)、楕円が四角形を超えないようにx、y、a、bを選択すると、それぞれに楕円を1つ配置できます。いずれかですが、楕円配置でどれくらいの "ランダム性"があれば十分かどうかによって異なります。

数学的に厳密な方法は、描かれた楕円それぞれのx、y、a、bを保存し、新しい楕円ごとに、2つの2次方程式の系を解くことによって共通点を持つかどうかをペアごとにチェックします。しかし、これは角度が追加されたコードに応じて編集していない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つの楕円を他の楕円の次に収まるように縮小する必要がある要素を返すように適応させることができます(すでに適合している場合は1)。

+0

関数ファイル 'overlap_ellipses'は、ここ[link](http://www.mathworks.com/matlabcentral/fileexchange/25389-synthetic-microstructure-generator)から来ます。 – Elsie

+0

交わりが起こったら、aとbを減らしたいのはかなり複雑です。 – Elsie

関連する問題