2011-10-24 59 views

回答

6

下面是與watershed算法一起使用distance transform繪製用於橢圓維諾圖的算法。

%# first, define some ellipses (for simplicity, I use 0/90 orientation) 
ellipses = [10,20,5,10;30,10,10,7;40,40,8,3]; 

%# put the ellipses into an image (few pixels, therefore pixelated) 
img = false(50); 
[xx,yy]=ndgrid(1:50,1:50); 
for e = 1:size(ellipses,1),img = img | (xx-ellipses(e,1)).^2/ellipses(e,3)^2 + (yy-ellipses(e,2)).^2/ellipses(e,4)^2 <= 1;end 

enter image description here

%# perform the distance transform 
dt = bwdist(img); 

enter image description here

%# apply the watershed algorithm. 
%# ws==0 are the lines for the Voronoi diagram 
ws = watershed(dt); 

%# create a RGB image and display 
%# note: for yellow lines, replace the last 
%# "ws==0" by "zeros(size(ws))", so that you 
%# only put ws into the red and green channel (=yellow) 
rgb = cat(3,ws==0,ws==0,ws==0)); 
%# add the ellipses into the red channel 
rgb(:,:,1) = rgb(:,:,1) | img; 
imshow(rgb) 

enter image description here

+0

我能做些什麼來控制線條和橢圓的顏色? – Elsie

+0

@Ivy:'rgb = repmat(ws == 0,1,1,3); rgb(:,:,1)= rgb(:,:,1)| img; imshow(rgb)' – Jonas

+0

如何在圖像中同時顯示橢圓和線條?因爲我imshow(dt),只有橢圓形顯示,如果我imshow(ws),只有線。我試過rgb,'repmat'出現錯誤:輸入參數太多。我能做什麼? – Elsie

0

我不知道你在這裏用「省略號」表示的意思。但對於在C++ Stephan的財富/沙恩奧沙利文Voronoi圖一個實施方式中,

http://www.skynet.ie/~sos/mapviewer/voronoi.php

+0

省略號發生了由線圍成的 '點'(X,Y)的。 – Elsie

2

以防萬一,這是從數學的幫助系統中的示例:

(*Generate ellipses*) 
p= [email protected]@Table[ 
      Rotate[ 
       Disk[RandomReal[10, 2],   (*Rnd position*) 
        RandomReal[{.3, 1.5}, 2]], (*Rnd radii*) 
      RandomReal[Pi]], {i, 10}]   (*Rnd rotation*) 

(*Compute Voronoi*) 

LaplacianGaussianFilter[DistanceTransform[p], 2] // ImageAdjust 

enter image description here

這不是一個精確的計算,但對於實際應用不夠公平。

1

根據您最近的問題跟蹤,我瞭解到您一直在研究在RGB圖像頂部繪製rasterized橢圓。您希望能夠指定橢圓的位置,形狀和顏色。您希望邊界上的橢圓爲clipped,也可以爲non-overlapping。現在您正在尋找以類似於Voronoi圖的方式繪製劃分空間的線(但是使用橢圓而不是點)。

對於這個特定的問題,如@Jonas所示,解決方法是使用距離變換和分水嶺算法。

我想我繼續我的前一個例子,並用Jonas的想法擴展它來展示整個過程。希望你覺得它有用..

該代碼使用calculateEllipse函數來計算構成一個橢圓形,以及imoverlay對圖像的特定像素設置一些選定的顏色功能的點的座標。

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

%# random ellipses 
num = 20; 
centers = bsxfun(@times, rand(num,2), sz([2 1])); %# center x/y-coords 
radii = bsxfun(@times, rand(num,2), [300 50])+10; %# major/minor axis length 
angles = rand(num,1) .* 360;      %# angle of rotation 
ex = cell(num,1);         %# vertices x-coords 
ey = cell(num,1);         %# vertices y-coords 

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

%# randomly place ellipses one-at-a-time, skip if overlaps previous ones 
flag = false(num,1); 
for i=1:num 
    %# ellipse we would like to draw directly on image matrix 
    [ex{i},ey{i}] = calculateEllipse(centers(i,1),centers(i,2), ... 
     radii(i,1),radii(i,2), angles(i), 100); 

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

    %# check if there is no existing overlapping ellipse 
    if all(L(mask)==0) 
     %# use the mask to place the ellipse in the label image 
     L(mask) = sum(flag)+1; %# assign value using an increasing counter 
     flag(i) = true; 
    end 
end 

%# filter ellipses to only those that made through the overlap test 
num = sum(flag); 
centers = centers(flag,:); 
radii = radii(flag,:); 
angles = angles(flag); 
ex = ex(flag); 
ey = ey(flag); 

%# rasterized voroni diagram of the ellipses [Jonas] 
E = (L ~= 0);        %# ellipses as binary image 
WS = watershed(bwdist(E));    %# distance transform + watershed 
WS = (WS == 0);       %# WS==0 corresponds voronoi diagram 
WS = bwmorph(WS, 'thicken',1);   %# thicken the lines 

%# set pixels corresponding to voronoi diagram to white 
II = I; 
II = imoverlay(II, WS, [1 1 1]);   %# you can customize the color here 

%# set pixels corresponding to ellipses using specified colors 
clr = hsv(num);       %# color of each ellipse 
for i=1:num 
    mask = bwperim(L==i,8);    %# get perimeter of the ellipse mask 
    mask = bwmorph(mask, 'thicken',1); %# thicken the ellipse perimeter 
    II = imoverlay(II, mask, clr(i,:)); %# set those pixels with RGB color 
end 

%# show final rasterized image (image + ellipses + voronoi diagram) 
figure, imshow(II, 'InitialMagnification',100, 'Border','tight') 

screenshot

+0

我試圖畫出實心的橢圓,所以我拿出了'mask = bwperim(L == i,8)'這一行,即得到橢圓的周長,但是輸出結果與一個爲什麼會發生這種情況?這是否是一種邏輯錯誤? – Elsie

+0

@Ivy:如果你想繪製純的橢圓,你也應該在它之後立即刪除這條線(加粗周邊),因此你只會有:'mask =(L == i);' – Amro

+0

是的,刪除後兩行,改變'II = imoverlay(II,mask,clr(i,:));' 'II = imoverlay(II,L,clr(i,:));'也會起作用。順便說一句,如果我的I是'I =零(500,500,3)',如何將背景色從黑色改變爲(假設)cyan [1 0 1]?我是否需要再次應用imoverlay?或者有一個快速的方法? – Elsie