2010-04-17 111 views
1

我有一組點表示爲2行n列矩陣。這些點組成一個連接的邊界或邊緣。我需要一個從起點P1開始追蹤輪廓並在終點P2停止的功能。它還需要能夠以順時針或逆時針方向追蹤輪廓。我想知道是否可以通過使用Matlab的一些函數來實現。Matlab - 在兩個不同點之間跟蹤輪廓線

我試圖寫我自己的功能,但是這是充滿了bug,我也嘗試使用bwtraceboundary和索引但是這有問題的結果,因爲矩陣內的點不是創建輪廓的順序。

非常感謝您的幫助。

順便說一句,我已經包含了一組鏈接到一組點。它是一隻手的輪廓的一半。

該函數將理想地追蹤從紅色星形到綠色三角形的輪廓。按遍歷順序返回點。

編輯:這也許是一個解決更大的問題,我試圖解決,但它是可能的,以測試如果一個點上的藍色邊界邊緣連接到輪廓之間的紅色星星或綠色三角點。

即對於藍色邊界上的點,如果您要手動從左側紅色星號到綠色三角形跟蹤輪廓,則該函數將返回true,如果點位於兩點之間的連接邊界上,並且爲false除此以外。

alt text http://img717.imageshack.us/img717/9814/hand1.png

+0

爲什麼這是社區wiki,btw? – Jonas 2010-04-17 13:43:37

+0

對不起,我一直在自動駕駛 – binarycreations 2010-04-17 15:22:47

回答

2

如果點的距離太近了,你應該能夠一直在尋找列表中的下一個最接近的點做跟蹤。

如果這個觀點相距較遠,這個問題就不可能解決 - 想象出四個角點和一個點在中心的五個點:跟蹤線的「正確」方式是什麼?

%%# create some points 
npts = 100; 
x = linspace(-1,1,100)'; %' 
y = 1 - x.^2; 
pts = [x,y]; 

%# shuffle the points 
newOrder = randperm(npts); 
pts = pts(newOrder,:); 

%# find index of start, end point 
startIdx = find(newOrder == 1); 
endIdx = find(newOrder == npts); 

%# this brings us to where you are - pts as a nx2 array 
%# startIdx indicates the star, and endIdx indicates the triangle. 

%# pre-assign output - traceIdx, which contains the ordered indices of the point on the trace 
traceIdx = NaN(npts,1); 

%# create distance matrix 
distances = squareform(pdist(pts)); 

%# eliminate zero-distance along the diagonal, b/c we don't want points linking to themselves 
distances(logical(eye(npts))) = NaN; 

%# starting from startIdx: always find the closest next point, store in traceIdx, 
%# check whether we've arrived at the end, and repeat if we haven't 
done = false; 
traceCt = 1; 
traceIdx(1) = startIdx; 

while ~done 
    %# find the index of the next, closest point 
    [dummy,newIdx] = min(distances(traceIdx(traceCt),:)); 

    %# store new index and up the counter 
    traceCt = traceCt + 1; 
    traceIdx(traceCt) = newIdx; 

    %# check whether we're done 
    if newIdx == endIdx 
     done = true; 
    else 
     %# mask the backward distance so that there's no turning back 
     distances(newIdx,traceIdx(traceCt-1)) = NaN; 
    end %# if 
end %# while ~done 

%# remove NaNs 
traceIdx(~isfinite(traceIdx)) = []; 

%# plot result with a line connecting the dots to demonstrate that everything went well. 
figure, 
plot(pts(traceIdx,1),pts(traceIdx,2),'-o') 
hold on, 
plot(pts(startIdx,1),pts(startIdx,2),'*r') 
plot(pts(endIdx,1),pts(endIdx,2),'>g') 
+0

謝謝喬納斯我沒有意識到,這實際上可能無法解決! – binarycreations 2010-04-17 15:22:30

+1

我不會稱之爲無法解決,但相當棘手。 – Amro 2010-04-17 16:11:46

+0

@Jonas - Thankyou提供您的代碼片段。我確實遇到了一個涉及無回頭路段的問題,而不是僅僅標記NaN的最後一點,我選擇了所有先前選擇的點到NaN。而不是:距離(newIdx,traceIdx(traceCt-1))= NaN;距離(:,traceIdx(1:traceCt))= NaN; (他想到了他的頭頂) Btw喬納斯,我對你的matlab技能​​印象非常深刻! – binarycreations 2010-04-25 16:29:23