2012-11-26 30 views
6

Muszę wykryć sprężynę w kształcie spirali i policzyć jej zwojów cewki.Jak wykrywać i liczyć spiralne zwoje

Próbowałem następująco:

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

Jestem trochę jak w stanie uzyskać sprężynę ale jak się liczniki. Szukam algorytmów. Obecnie nie szukam optymalizacji prędkości.

Jest to podobne do liczenia palców. Spirala sprężynowa jest bardzo cienka, aby uzyskać kontur. Co jeszcze można zrobić. http://www.luna-arts.de/others/misc/HandsNew.zip

+0

Każdy, potrzebuję właściwy kierunek! – Rick2047

+0

Próbowałem go jeszcze raz z moim własnym algo. Ale cienkie obiekty są trudne do wykrycia (na razie nie znam drogi). – Rick2047

Odpowiedz

3

Masz dobrą finalną binaryzację, ale wygląda na to, że jest zbyt ograniczona do tego pojedynczego przypadku. Zrobiłbym stosunkowo prostsze, ale prawdopodobnie bardziej niezawodne, wstępne przetwarzanie, aby umożliwić względnie dobrą binaryzację. Z morfologii matematycznej powstaje transformacja o nazwie h-dome, która służy do usuwania nieistotnych minimów/maksimów poprzez tłumienie minimów/maksimów wysokości < h. Ta operacja może nie być łatwo dostępna w bibliotece przetwarzania obrazu, ale nietrudno ją wdrożyć. Aby dokonać binaryzacji tego przetworzonego obrazu, wybrałem metodę Otsu, ponieważ jest ona automatyczna i statystycznie optymalna.

Oto obraz wejściowy po przekształceniach h-Dome, a obraz binarny:

enter image description hereenter image description here

Teraz, aby policzyć „spiralnych zwojów” Zrobiłem coś bardzo proste: ja podzieliła spirale, więc mogę je policzyć jako połączone komponenty. Aby je podzielić, zrobiłem jedno morfologiczne otwarcie z pionową linią, a następnie pojedyncze rozszerzenie przez elementarny kwadrat. To daje następujący obraz:

enter image description here

licząc składników daje 15. Skoro masz 13 z nich, które nie są zbyt blisko, to podejście liczono je wszystkie prawidłowo. Grupy po lewej i prawej stronie zostały policzone jako pojedyncze.

pełny kod Matlab czynili kroki:

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