2009-02-25 4 views
6

Я пытаюсь написать алгоритм обнаружения гребня, и все найденные мной источники, похоже, объединяют обнаружение края с обнаружением гребня. Прямо сейчас, я реализовал алгоритм обнаружения края Canny, но это не то, что я хочу: например, учитывая одну строку на изображении, она эффективно переведет ее на двойную линию ребер (поскольку она будет записывать как стороны линии) - я просто хочу, чтобы он читал одну строку.Реализация определения гребня

wikipedia article об обнаружении хребта имеет кучу математики, но этот вид не помогает мне в качестве программиста (не то, чтобы я противился математике, но это не мое поле, и я не понимаю как перевести их дифференциальные уравнения в код). Есть ли хороший источник для реализации этого? Или, если на то пошло, есть ли хорошая реализация с открытым исходным кодом?

Редактировать: вот простой пример. Мы начнем с простой линией:

http://img24.imageshack.us/img24/8112/linez.th.png

и запустить Осторожный алгоритм, чтобы получить:

http://img12.imageshack.us/img12/1317/canny.th.png

(вы можете увидеть, что это толще здесь - если нажать на изображение, вы увидите, что это действительно две смежные линии с заготовкой между ними)

Кроме того, я написал g на C++, но это не имеет большого значения. Но я хочу закодировать алгоритм , а не только написать SomePackage::findRidges() и сделать с ним.

+0

На каком языке вы пишете? У Matlab есть функции, которые обрабатывают именно это. Я был бы удивлен, если у R тоже не было этого. –

+0

C++, но я ищу алгоритм! –

+0

Я думаю, что у вас проблема с порогом, а не проблема поиска гребня. –

ответ

5

Возможно, вам нужно подумать об очистке линии, которую у вас уже есть, а не об обнаружении крошечного края. Чувствуется, что вы должны что-то сделать с image morphology, в частности, я думаю о скелетонизованных и конечных типах операций с точечными точками. Используемые соответственно они должны удалить из вашего изображения любые функции, которые не являются «линиями» - я считаю, что они реализованы в библиотеке Intel OpenCV.

Вы можете восстановить одну линию из вашей двойной линии, сгенерированной с использованием фильтра Canny, используя одну операцию расширения, а затем 3 эра (я попробовал это в ImageJ) - это также должно удалить любые края.

2

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

http://en.wikipedia.org/wiki/Hough_transform

Вы должны быть в состоянии получить фактическое уравнение линии от этого, так что вы можете сделать это как тонкий или толстый, как вам нравится. Единственная сложная часть - выяснить, где заканчивается линия.

Вот код, который я написал для преобразования hough несколько лет назад, написанного на MATLAB. Я не уверен, как хорошо это работает, но это должно дать вам общую идею. Он найдет все линии (не сегменты) на изображении

im = imread('cube.tif'); 
[bin1,bin2,bin3] = canny(im); 

%% define constants 
binary = bin1; 
distStep = 10; % in pixels 
angStep = 6; % in degrees 
thresh = 50; 

%% vote 
maxDist = sqrt((size(binary,1))^2+(size(binary,2))^2); 
angLoop = 0:angStep*pi/180:pi; 
origin = size(binary)/2; 
accum = zeros(ceil(maxDist/distStep)+1,ceil(360/angStep)+1); 

for y=1:size(binary,2) 
    for x=1:size(binary,1) 
    if binary(x,y) 
     for t = angLoop 
     dx = x-origin(1); 
     dy = y-origin(2); 
     r = x*cos(t)+y*sin(t); 
     if r < 0 
      r = -r; 
      t = t + pi; 
     end 
     ri = round(r/distStep)+1; 
     ti = round(t*180/pi/angStep)+1; 
     accum(ri,ti) = accum(ri,ti)+1; 
     end 
    end 
    end 
end 
imagesc(accum); 

%% find local maxima in accumulator 
accumThresh = accum - thresh; 
accumThresh(logical(accumThresh<0)) = 0; 
accumMax = imregionalmax(accumThresh); 
imagesc(accumMax); 

%% calculate radius & angle of lines 
dist = []; 
ang = []; 
for t=1:size(accumMax,2) 
    for r=1:size(accumMax,1) 
    if accumMax(r,t) 
     ang = [ang;(t-1)*angStep/180*pi]; 
     dist = [dist;(r-1)*distStep]; 
    end 
    end 
end 
scatter(ang,dist); 
+0

Я уже делаю это - проблема в том, что алгоритм Canny дает двойные ребра, как я описал. Итак, мне нужен лучший шаг # 1 :) –

+0

Ну, если все ваши изображения выглядят так, вы можете пропустить шаг 1. В противном случае, если вы используете фактическое изображение, у вас не должно быть таких тонких линий, как canny не должно вызывать никаких проблем, нет? Просто мысль. – mpen

+0

Я считаю, что проблема Джесси состоит в том, как * отметить * линию гребня, после чего, конечно, вы можете применить преобразование Хафа для получения параметров линии, но это не его точка здесь. – jasxun