2010-04-17 110 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