Существует два этапа получения кодов цепочки: отслеживание границы и кодирование координат в виде кодов цепочки.Этот последний шаг тривиален, я не буду вдаваться в подробности.Об этой границе я думаю, что это трассировка.
Обычно прослеживаются пиксели объекта, которые образуют границу (т.е. имеют по крайней мере одного соседа по фону).Важно, чтобы это происходило по порядку, просто перечисления этих пикселей недостаточно.Но обратите внимание, что это описание границы смещено: истинный объект больше, чем многоугольник, образованный соединением центров пикселей на границе объекта.Вычисление периметра должно принимать это во внимание (как обсуждено в сообщении в блоге, которое вы связали).
Этот код немного адаптирован из этого сообщения в блоге .img
- это логический массив:
% Data for chain code encoding:
directions = [ 1, 0
1,-1
0,-1
-1,-1
-1, 0
-1, 1
0, 1
1, 1];
% Get a start point, any pixel on the boundary is OK:
indx = find(img,1)-1; % 0-based indexing is easier
% Image sizes
sz = [size(img,2),size(img,1)]; % x,y sizes, rather than y,x sizes
% Coordinates for start point
start = [floor(indx/sz(2)),0];
start(2) = indx-(start(1)*sz(2));
% Initialize algorithm
cc = []; % The chain code
coord = start; % Coordinates of the current pixel
dir = 1; % The starting direction
% Loop till full boundary is traced
while 1
newcoord = coord + directions(dir+1,:);
if all(newcoord>=0) && all(newcoord<sz) ...
&& img(newcoord(2)+1,newcoord(1)+1)
cc = [cc,dir];
coord = newcoord;
dir = mod(dir+2,8);
else
dir = mod(dir-1,8);
end
if all(coord==start) && dir==1 % back to starting situation
break;
end
end
Как вы можете видеть здесь, алгоритм запускается со случайного пикселя и выбирает направление для обхода.Затем он следует за границей, находя следующего соседа в заданном направлении.В связанном сообщении блога есть детали, объясняющие, как этот сосед найден.Короче говоря, вы смотрите в текущем направлении, на первый пиксель соседнего объекта, у которого есть сосед фона.Учитывая текущее местоположение и направление, из которого мы пришли, можно предположить, что сосед в определенном направлении будет фоновым пикселем.Двигаясь по часовой стрелке (или против часовой стрелки, выберите одно) направление вокруг текущей точки, начиная с этого фонового пикселя, первый пиксель объекта будет гарантированно быть граничным пикселем.Мы добавляем это в наш список и продолжаем.
Алгоритм завершается, когда мы достигаем начальной позиции и направления .Таким образом, участок объекта толщиной в 1 пиксель будет посещен дважды, чтобы завершить трассировку границы.