Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect and count a spiral's turns

I need to detect a spiral shaped spring and count its coil turns.

I have tried as follows:

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 ImageOutputImage

I am some how able to get the spring but how to get the counts. I am looking for algorithms. I am currently not looking for speed optimization.

This is similar like counting fingers. Spring spiral is very thin to get using contour. What else can be done. http://www.luna-arts.de/others/misc/HandsNew.zip

like image 735
Rick2047 Avatar asked Nov 26 '12 11:11

Rick2047


1 Answers

You have a good final binarization over there, but it looks like to be too restricted to this single case. I would do a relatively simpler, but probably more robust, preprocessing to allow a relatively good binarization. From Mathematical Morphology, there is a transform called h-dome, which is used to remove irrelevant minima/maxima by suppressing minima/maxima of height < h. This operation might not be readily available in your image processing library, but it is not hard to implement it. To binarize this preprocessed image I opted for Otsu's method, since it is automatic and statistically optimal.

Here is the input image after h-dome transformations, and the binary image:

enter image description hereenter image description here

Now, to count the number of "spiral turns" I did something very simple: I split the spirals so I can count them as connected components. To split them I did a single morphological opening with a vertical line, followed by a single dilation by an elementary square. This produces the following image:

enter image description here

Counting the components gives 15. Since you have 13 of them that are not too close, this approach counted them all correctly. The groups at left and right were counted as a single one.

The full Matlab code used to do these steps:

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');
like image 93
mmgp Avatar answered Sep 27 '22 19:09

mmgp