2016-05-31 38 views
9

Sto provando a progettare un modo per rilevare la curvatura di questo tubo. Ho provato ad applicare la trasformazione di hough e ho trovato la linea rilevata, ma non si trovano lungo la superficie del tubo, quindi la levigatura per adattarsi a una curva di beizer non funziona. Si prega di suggerire un buon modo per iniziare l'immagine in questo modo. [sample pictureCurva di calcolo di un tubo piegato utilizzando l'elaborazione dell'immagine (rilevamento parabola trasformazione Hough)

L'immagine ottenuta da Hough Transform per rilevare le linee è la seguente [Hough_transformed Sto usando il codice Matlab standard per il rilevamento di linee di trasformazione di hitch probabilistico che genera segmenti di linea che circondano la struttura. Essenzialmente la forma del tubo assomiglia a una parabola, ma per la rilevazione della parabola di hough ho bisogno di fornire l'eccentricità del punto prima del rilevamento. Si prega di suggerire un buon metodo per trovare punti discreti lungo la curvatura che possono essere montati su una parabola. Ho dato tag a opencv e ITK quindi se c'è una funzione che può essere implementata su questa particolare immagine, suggerire la funzione che proverò per vedere i risultati.

img = imread('test2.jpg'); 
rawimg = rgb2gray(img); 
[accum, axis_rho, axis_theta, lineprm, lineseg] = Hough_Grd(bwtu, 8, 0.01); 
figure(1); imagesc(axis_theta*(180/pi), axis_rho, accum); axis xy; 
xlabel('Theta (degree)'); ylabel('Pho (pixels)'); 
title('Accumulation Array from Hough Transform'); 
    figure(2); imagesc(bwtu); colormap('gray'); axis image; 
    DrawLines_2Ends(lineseg); 
    title('Raw Image with Line Segments Detected'); 

La mappa bordo dell'immagine è il seguente edge map e il risultato generato dopo l'applicazione sulla trasformata di Hough bordo mappa non è buona. Stavo pensando a una soluzione che il rilevamento generale della forma parametrica come questa curva possa essere espresso come una famiglia di parabole e quindi eseguiamo una curva adatta a stimare i coefficienti mentre si curva per analizzare la sua curvatura. Devo progettare una procedura in tempo reale, quindi per favore suggerisci qualcosa in questa direzione. Processed Edge map

+0

Umm, solo indovinando: cosa succede se si passa l'originale attraverso un rilevatore di bordo canny prima? – jjmontes

+0

Ho provato ad applicare la trasformazione di hough a una mappa dei bordi, ma non ha comportato un rilevamento della linea migliore dalla trasformazione di hough. –

+1

Vedo. Risultato molto peggiore per le linee rette, ma forse meglio per una parabola. Forse potresti ottenere punti affidabili usando l'intersezione delle linee nel tuo primo approccio: sembra che ci sia una maggiore densità di intersezioni nel bordo del tubo, ma non so se questo sarà generalizzato bene ad altre immagini. Sono un novizio in CV, se nessuno risponde qui, posso solo suggerire di chiedere nei siti 'dsp' o' cv' StackExchange. – jjmontes

risposta

12

suggerisco il seguente approccio:

Prima tappa: generare una segmentazione del tubo.

  1. eseguire la soglia sull'immagine.
  2. trova i componenti connessi nell'immagine con soglia.
  3. cerca un componente collegato che rappresenta la pipe. Il componente connesso che rappresenta la pipa dovrebbe avere una mappa dei bordi che è divisa nei bordi superiore e inferiore (vedi immagine allegata). I bordi superiore e inferiore dovrebbero avere dimensioni simili e dovrebbero avere una distanza relativamente costante l'uno dall'altro. In altre parole, la varianza delle loro distanze per pixel dovrebbe essere bassa.

enter image description here

Seconda fase - estratto curva

In questa fase, si dovrebbe estrarre i punti della curva per l'esecuzione di Beizer montaggio. È possibile eseguire questo calcolo sul bordo superiore o sul bordo inferiore. un'altra opzione è quella di farlo sullo scheletro della segmentazione del tubo.

Risultati

Il tubo di segmentazione. I bordi superiore e inferiore sono contrassegnati con blu e rosso in modo corrispondente.

enter image description here

Codice

I = mat2gray(imread('ILwH7.jpg')); 
im = rgb2gray(I); 

%constant values to be used later on 
BW_THRESHOLD = 0.64; 
MIN_CC_SIZE = 50; 
VAR_THRESHOLD = 2; 
SIMILAR_SIZE_THRESHOLD = 0.85; 

%stage 1 - thresholding & noise cleaning 
bwIm = im>BW_THRESHOLD; 
bwIm = imfill(bwIm,'holes'); 
bwIm = imopen(bwIm,strel('disk',1)); 


CC = bwconncomp(bwIm); 
%iterates over the CC list, and searches for the CC which represents the 
%pipe 
for ii=1:length(CC.PixelIdxList) 
    %ignore small CC 
    if(length(CC.PixelIdxList{ii})<50) 
     continue; 
    end 
    %extracts CC edges 
    ccMask = zeros(size(bwIm)); 
    ccMask(CC.PixelIdxList{ii}) = 1; 
    ccMaskEdges = edge(ccMask); 

    %finds connected components in the edges mat(there should be two). 
    %these are the top and bottom parts of the pipe. 
    CC2 = bwconncomp(ccMaskEdges); 
    if length(CC2.PixelIdxList)~=2 
     continue; 
    end 

    %tests that the top and bottom edges has similar sizes 
    s1 = length(CC2.PixelIdxList{1}); 
    s2 = length(CC2.PixelIdxList{2}); 
    if(min(s1,s2)/max(s1,s2) < SIMILAR_SIZE_THRESHOLD) 
     continue; 
    end 

    %calculate the masks of these two connected compnents 
    topEdgeMask = false(size(ccMask)); 
    topEdgeMask(CC2.PixelIdxList{1}) = true; 
    bottomEdgeMask = false(size(ccMask)); 
    bottomEdgeMask(CC2.PixelIdxList{2}) = true; 

    %tests that the variance of the distances between the points is low 
    topEdgeDists = bwdist(topEdgeMask); 
    bottomEdgeDists = bwdist(bottomEdgeMask); 
    var1 = std(topEdgeDists(bottomEdgeMask)); 
    var2 = std(bottomEdgeDists(topEdgeMask)); 

    %if the variances are low - we have found the CC of the pipe. break! 
    if(var1<VAR_THRESHOLD && var2<VAR_THRESHOLD) 
     pipeMask = ccMask; 
     break; 
    end 


end 

%performs median filtering on the top and bottom boundaries. 
MEDIAN_SIZE =5; 
[topCorveY, topCurveX] = find(topEdgeMask); 
topCurveX = medfilt1(topCurveX); 
topCurveY = medfilt1(topCurveY); 
[bottomCorveY, bottomCurveX] = find(bottomEdgeMask); 
bottomCurveX = medfilt1(bottomCurveX); 
bottomCorveY = medfilt1(bottomCorveY); 

%display results 
imshow(pipeMask); hold on; 
plot(topCurveX,topCorveY,'.-'); 
plot(bottomCurveX,bottomCorveY,'.-'); 

Commenti

  1. In questo esempio specifico, acquisendo la segmentazione del tubo da sogliatura era relativamente facile. In alcune scene potrebbe essere più complesso. in questi casi, è possibile utilizzare l'algoritmo di crescita della regione per generare la segmentazione della tubazione.

  2. Rilevare il componente collegato che rappresenta il tubo può essere fatto utilizzando un po 'più hueristics. Ad esempio, la curvatura locale dei suoi confini dovrebbe essere bassa.

5

È possibile trovare i componenti collegati (CC) dell'immagine della mappa laterale invertita. Quindi puoi in qualche modo filtrare quei componenti, ad esempio, in base al loro numero di pixel, usando le proprietà della regione. Ecco i componenti collegati che ho ottenuto usando il codice Octave dato. Ora è possibile adattare un modello a ciascuno di questi CC utilizzando qualcosa come nlinfit o qualsiasi metodo appropriato.

ccs

im = imread('uFBtU.png'); 
gr = rgb2gray(uint8(im)); 
er = imerode(gr, ones(3)) < .5; 

[lbl, n] = bwlabel(er, 8); 
imshow(label2rgb(lbl))