2009-02-25 9 views
6

Estoy tratando de escribir un algoritmo de detección de cresta, y todas las fuentes que he encontrado parecen confundir la detección de bordes con la detección de cresta. En este momento, he implementado el algoritmo de detección de bordes Canny, pero no es lo que quiero: por ejemplo, dada una sola línea en la imagen, se traducirá efectivamente a una línea doble de bordes (ya que registrará ambos lados de la línea) - Solo quiero que lea la línea.Implementación de detección de cresta

wikipedia article sobre la detección de cresta tiene un montón de matemáticas, pero este tipo de esto no me ayuda como programador (no es que sea contrario a las matemáticas, pero no es mi campo, y no entiendo cómo traducir sus ecuaciones diferenciales en código). ¿Hay una buena fuente para realmente implementar esto? O, para el caso, ¿hay una buena implementación de código abierto?

Editar: aquí está el ejemplo simple. Comenzamos con una línea sencilla:

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

y ejecutar el Canny Algoritmo para obtener:

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

(se puede ver que es más gruesa aquí - si hace clic en la imagen, se dará cuenta de que lo que realmente es de dos líneas adyacentes con un espacio en blanco en el medio)

Además, estoy writin g en C++, pero eso no debería importar. Pero quiero codificar el algoritmo , no solo escribir SomePackage::findRidges() y terminarlo.

+0

¿en qué idioma está escribiendo? Matlab tiene funciones que manejan precisamente eso. Me sorprendería si R no tiene eso también. –

+0

C++, ¡pero estoy buscando el algoritmo! –

+0

Creo que tienes un problema de umbral, en lugar de un problema para encontrar cresta. –

Respuesta

5

Tal vez necesite pensar en términos de limpieza de la línea que ya tiene, en lugar de una detección de borde tipo Canny. Se siente como si pudieras hacer algo con image morphology, en particular, estoy pensando en las operaciones de esqueleto y último tipo de puntos erosionados. Si se utilizan adecuadamente, deberían eliminar de su imagen las características que no son 'líneas', creo que están implementadas en la biblioteca OpenCV de Intel.

Puede recuperar una sola línea de su línea doble generada utilizando el filtro Canny usando una operación de dilatación seguida de 3 erosiones (lo probé en ImageJ); esto también debería eliminar los bordes.

2

Iba a sugerir la limpieza de sus líneas como Ian dijo, pero si usted no quiere hacer eso, también se puede mirar en hacer alguna variante de una transformada de Hough.

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

Usted debe ser capaz de obtener la ecuación para la línea real de esto, por lo que puede que sea lo más delgado o grueso como te gusta. La única parte difícil es averiguar dónde termina la línea.

Aquí está el código que escribí para una transformada hace algunos años, escrito en MATLAB. No estoy seguro de qué tan bien funciona, pero debería darle una idea general. Encontrará todas las líneas (no segmentos) en una imagen

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

Ya estoy haciendo esto, el problema es que el algoritmo de Canny da doble filo, como he descrito. Necesito un mejor Paso # 1 :) –

+0

Bueno, si todas sus imágenes se ven así, puede saltear el paso 1. De lo contrario, si está usando una imagen real, no debería tener líneas delgadas como esa, y astuto no debería darte ningún problema, ¿no? Solo un pensamiento. – mpen

+0

Creo que el problema de Jesse es cómo * marcar * la línea de cresta, después de eso, por supuesto, puedes aplicar la transformada de Hough para obtener los parámetros de la línea, pero ese no es su punto aquí. – jasxun