2
votes

I am using EmguCV 2.3.0.1416 from a simple console application (.net 4.0 and c#) and I have a question around canny's, edge detection etc. Given the following code:

var colours = new[]
                  {
                      new Bgr(Color.YellowGreen),
                      new Bgr(Color.Turquoise),
                      new Bgr(Color.Blue),
                      new Bgr(Color.DeepPink)
                  };

// Convert to grayscale, remove noise and get the canny
using (var image = new Image<Bgr, byte>(fileName)
    .Convert<Gray, byte>()
    .PyrDown()
    .PyrUp()
    .Canny(new Gray(180),
           new Gray(90)))
{
    // Save the canny out to a file and then get each contour within
    // the canny and get the polygon for it, colour each a different
    // colour from a selection so we can easily see if they join up
    image.Save(cannyFileName);

    var contours = image
        .FindContours(CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,
                      RETR_TYPE.CV_RETR_EXTERNAL);

    using (var debug = new Image<Bgr, byte>(image.Size))
    {
        int colIndex = 0;
        for (; contours != null; contours = contours.HNext)
        {
            Contour<Point> poly = contours
                .ApproxPoly(contours.Perimeter*0.05,
                            contours.Storage);

            debug.Draw(poly, colours[colIndex], 1);

            colIndex++;
            if (colIndex > 3) colIndex = 0;
        }

        debug.Save(debugFileName);
    }
}

I get this output (this is actually just a part of the image but it shows what I am asking about):

Canny Edge

As you can see it has a blue line with a little bit of pink and then a green line. The real thing has just a solid edge here so I want this to be a single line in order that I can be sure it is the edge of what I am looking at.

The original image looks like this (I have zoomed it but you can see it has a very distinctive edge that I was expecting to be able to find easily).

Orignal

If I look at just the canny I can see the gap there so I tried adjusting the parameters for creating the canny (the threshold and linking threshold) but they have made no difference.

I also dilated and then eroded the canny (using the same value for the iterations parameter - 10 incidentally) and that seemed to do the trick but could I lose accuracy by doing this (it just feels a bit wrong somehow)?

So, how should I ensure that I get a single line in this instance?

3

3 Answers

2
votes

Did you try smoothing before canny?

I found this link, maybe useful for you

http://www.indiana.edu/~dll/B657/B657_lec_hough.pdf

0
votes

What exactly do you mean by single line? Perhaps you are trying to thicken your line:

debug.Draw(poly, colours[colIndex], 2);

Instead of:

debug.Draw(poly, colours[colIndex], 1);

Or whatever thickness of line you want. Here's the emgucv Draw Method for polygon. Perhaps look at this link too.

0
votes

The first argument in the approxPoly() function is exactly what you are looking for. Just fiddle with that and you will get exactly what you want.