2012-11-26 13 views
6

Ich muss eine spiralförmige Feder erkennen und ihre Spulenwindungen zählen.Wie man eine Spirale erkennt und zählt

ich versucht habe, wie folgt:

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

ich einige bin wie die Lage, die Feder zu erhalten, aber, wie die Zählungen zu erhalten. Ich suche nach Algorithmen. Ich suche derzeit keine Geschwindigkeitsoptimierung.

Dies ist ähnlich wie Finger zählen. Spiralfeder ist sehr dünn, um Kontur zu bekommen. Was kann noch getan werden? http://www.luna-arts.de/others/misc/HandsNew.zip

+0

Jeder, ich brauche eine richtige Richtung! – Rick2047

+0

Ich habe es noch mehr mit meinem eigenen Algo versucht. Aber dünne Objekte sind schwer zu erkennen (vorläufig kenne ich den Weg nicht). – Rick2047

Antwort

3

Sie haben eine gute endgültige Digitalisierung da drüben, aber es sieht so aus, als wäre man zu sehr auf diesen einen Fall beschränkt. Ich würde eine relativ einfachere, aber wahrscheinlich robustere Vorverarbeitung durchführen, um eine relativ gute Binärisierung zu ermöglichen. Aus der mathematischen Morphologie gibt es eine Transformation namens H-Dome, die verwendet wird, um irrelevante Minima/Maxima durch Unterdrücken von Minima/Maxima der Höhe < h zu entfernen. Diese Operation ist in Ihrer Bildverarbeitungsbibliothek möglicherweise nicht ohne weiteres verfügbar, aber es ist nicht schwer, sie zu implementieren. Um dieses vorverarbeitete Bild zu digitalisieren, habe ich mich für Otsus Methode entschieden, da diese automatisch und statistisch optimal ist. Hier

ist das Eingangsbild nach h-Dome-Transformationen und das binäre Bild:

enter image description hereenter image description here

Jetzt „dreht Spirale“ die Anzahl der zählen Ich habe etwas sehr einfach: ich aufgespalten Spiralen, damit ich sie als verbundene Komponenten zählen kann. Um sie zu teilen, habe ich eine einzige morphologische Öffnung mit einer vertikalen Linie gemacht, gefolgt von einer einzelnen Erweiterung um ein Elementarquadrat. Dadurch ergibt sich folgendes Bild:

enter image description here

die Komponenten Counting gibt 15. Da Sie 13 von ihnen haben, die nicht zu nahe beieinander liegen, ist dieser Ansatz sie alle korrekt gezählt. Die Gruppen links und rechts wurden als eine gezählt.

Der vollständige Matlab-Code verwendet, um diese Schritte zu tun:

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');