2012-11-26 3 views
6

Devo rilevare una molla a forma di spirale e contare le spire della bobina.Come rilevare e contare i turni di una spirale

ho provato come segue:

Image<Bgr, Byte> ProcessImage(Image<Bgr, Byte> img) 
{ 
    Image<Bgr, Byte> imgClone = new Image<Bgr,byte>(img.Width, img.Height); 
    imgClone = img.Clone(); 
    Bgr bgrRed = new Bgr(System.Drawing.Color.Red); 


    #region Algorithm 1 


    imgClone.PyrUp(); 
    imgClone.PyrDown(); 
    imgClone.PyrUp(); 
    imgClone.PyrDown(); 
    imgClone.PyrUp(); 
    imgClone.PyrDown(); 

    imgClone._EqualizeHist(); 
    imgClone._Dilate(20); 
    imgClone._EqualizeHist(); 
    imgClone._Erode(10); 

    imgClone.PyrUp(); 
    imgClone.PyrDown(); 
    imgClone.PyrUp(); 
    imgClone.PyrDown(); 
    imgClone.PyrUp(); 
    imgClone.PyrDown(); 

    imgClone._EqualizeHist(); 
    imgClone._Dilate(20); 
    imgClone._EqualizeHist(); 
    imgClone._Erode(10); 


    Image<Gray, Byte> imgCloneGray = new Image<Gray, byte>(imgClone.Width, imgClone.Height); 

    CvInvoke.cvCvtColor(imgClone, imgCloneGray, Emgu.CV.CvEnum.COLOR_CONVERSION.CV_BGR2GRAY); 

    imgCloneGray = imgCloneGray.Canny(c_thresh, c_threshLink);//, (int)c_threshSize); 

    Contour<System.Drawing.Point> pts = imgCloneGray.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_EXTERNAL); 

    CvInvoke.cvCvtColor(imgCloneGray, imgCloneYcc, Emgu.CV.CvEnum.COLOR_CONVERSION.CV_GRAY2BGR); 

    if (null != pts) 
    { 
     imgClone.Draw(pts, bgrRed, 2); 
     imgClone.Draw(pts.BoundingRectangle, bgrRed, 2); 
    } 

    #endregion 

    return imgClone; 
} 

Input Image OutputImage

Io sono in qualche modo in grado di ottenere la molla ma come ottenere i conteggi. Sto cercando algoritmi. Attualmente non sto cercando l'ottimizzazione della velocità.

Questo è simile al conteggio delle dita. La spirale a spirale è molto sottile per ottenere il contorno. Cos'altro può essere fatto. http://www.luna-arts.de/others/misc/HandsNew.zip

+0

Chiunque, ho bisogno di una direzione corretta! – Rick2047

+0

L'ho provato ancora con il mio algo. Ma gli oggetti sottili sono difficili da rilevare (per il momento non conosco il modo). – Rick2047

risposta

3

Hai una buona binarizzazione finale laggiù, ma sembra essere troppo limitato a questo singolo caso. Farei una pre-elaborazione relativamente più semplice, ma probabilmente più robusta, per consentire una binarizzazione relativamente buona. Dalla morfologia matematica, esiste una trasformazione chiamata h-dome, che viene utilizzata per rimuovere minimi/massimi irrilevanti sopprimendo i minimi/massimi di altezza < h. Questa operazione potrebbe non essere facilmente disponibile nella libreria di elaborazione delle immagini, ma non è difficile da implementare. Per binarizzare questa immagine preelaborata ho optato per il metodo di Otsu, dato che è automatico e statisticamente ottimale.

Ecco l'immagine in ingresso dopo le trasformazioni h-cupola, e l'immagine binaria:

enter image description hereenter image description here

Ora, per contare il numero di "spire a spirale" Ho fatto qualcosa di molto semplice: ho diviso il spirali quindi posso contarle come componenti connesse. Per dividerli ho fatto una singola apertura morfologica con una linea verticale, seguita da una singola dilatazione da un quadrato elementare. Questo produce il seguente immagine:

enter image description here

Contando i componenti spedisce 15. Poiché si ha 13 di loro che non sono troppo vicini, questo approccio tutti contati correttamente. I gruppi a sinistra ea destra sono stati contati come uno solo.

Il codice completo Matlab usato per fare questi passi:

f = rgb2gray(imread('http://i.stack.imgur.com/i7x7L.jpg')); 
% For this image, the two next lines are optional as they will to lead 
% basically the same binary image. 
f1 = imhmax(f, 30); 
f2 = imhmin(f1, 30); 
bin1 = ~im2bw(f2, graythresh(f2)); 

bin2 = bwmorph(imopen(bin1, strel('line', 15, 90)), 'dilate');