Matlab - Обведите контурную линию между двумя разными точками

У меня есть набор точек, представленный в виде матрицы из 2 строк по n столбцов. Эти точки составляют связную границу или ребро. Мне нужна функция, которая отслеживает этот контур от начальной точки P1 и останавливается в конечной точке P2. Он также должен иметь возможность отслеживать контур по часовой стрелке или против часовой стрелки. Мне было интересно, можно ли этого достичь с помощью некоторых функций Matlab.

Я попытался написать свою собственную функцию, но это было пронизано ошибками, и я также попытался использовать bwtraceboundary и индексацию, однако это имеет проблемные результаты, поскольку точки в матрице находятся не в том порядке, который создает контур.

Спасибо заранее за любую помощь.

Кстати, я включил ссылку на график набора точек. Это половина контура руки.

Функция идеально проследила бы контур от эфира красной звезды до зеленого треугольника. Возврат точек в порядке обхода.

РЕДАКТИРОВАТЬ: это, возможно, решение более крупной проблемы, которую я пытаюсь решить, но можно ли проверить, связана ли точка на синем граничном крае с контуром, который находится между красными звездами или зелеными треугольными точками.

то есть для точки на синей границе, если вы должны были провести контур вручную от левых красных звездочек до зеленого треугольника, функция вернет true, если точка находится на соединенной границе между двумя точками, и false в противном случае.

альтернативный текст http://img717.imageshack.us/img717/9814/hand1.png < / а>


person Community    schedule 17.04.2010    source источник
comment
почему это вики сообщества, кстати?   -  person Jonas    schedule 17.04.2010
comment
извините, я, должно быть, был на автопилоте   -  person binarycreations    schedule 17.04.2010


Ответы (1)


Если точки расположены так близко друг к другу, вы сможете выполнить трассировку, всегда ища следующую ближайшую точку в списке.

Если бы точки находились дальше друг от друга, проблема не была бы разрешима - представьте себе пять точек, где четыре являются углами, а одна находится в центре: каков «правильный» способ провести линию?

%%# 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')
person Community    schedule 17.04.2010
comment
Спасибо, Джонас, я не понимал, что это может быть неразрешимо! - person binarycreations; 17.04.2010
comment
Я бы не назвал это неразрешимым, скорее, неразрешимым. - person Amro; 17.04.2010
comment
@Jonas - Спасибо за предоставленный фрагмент кода. Я столкнулся с одной проблемой, которая связана с разделом о запрете поворота назад, вместо того, чтобы просто пометить последнюю точку как NaN, я выбрал все ранее выбранные точки как NaN. вместо: Distance (newIdx, traceIdx (traceCt-1)) = NaN; расстояния (:, traceIdx (1: traceCt)) = NaN; (он думает о своей макушке) Между прочим, Джонас, я очень впечатлен твоими навыками работы с Matlab! - person binarycreations; 25.04.2010