Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

You may want to start using a top hat operation. That will make you get rid of the blurry non black background:

static void Main(string[] args)
{
Image<Gray, byte> image = new Image<Gray, byte>(@"c:\im.png");

int morphOpSize = 5;
StructuringElementEx element =
    new StructuringElementEx(
        morphOpSize,
        morphOpSize,
        morphOpSize / 2,
        morphOpSize / 2,
        Emgu.CV.CvEnum.CV_ELEMENT_SHAPE.CV_SHAPE_ELLIPSE);

Image<Gray, byte> filtered;
filtered = image.MorphologyEx(
    element,
    Emgu.CV.CvEnum.CV_MORPH_OP.CV_MOP_TOPHAT,
    1);
ImageViewer.Show(image.ConcateHorizontal(filtered));
}

(Sorry for my emgu dialect.)

Then you may want to use findContours and do away with blobs that are more then e.g. twice as high as they are wide.

You may want to start using a top hat operation. That will make you get rid of the blurry non black background:

static void Main(string[] args)
{
Image<Gray, byte> image = new Image<Gray, byte>(@"c:\im.png");

int morphOpSize = 5;
StructuringElementEx element =
    new StructuringElementEx(
        morphOpSize,
        morphOpSize,
        morphOpSize / 2,
        morphOpSize / 2,
        Emgu.CV.CvEnum.CV_ELEMENT_SHAPE.CV_SHAPE_ELLIPSE);

Image<Gray, byte> filtered;
filtered = image.MorphologyEx(
    element,
    Emgu.CV.CvEnum.CV_MORPH_OP.CV_MOP_TOPHAT,
    1);
ImageViewer.Show(image.ConcateHorizontal(filtered));
}

(Sorry for my emgu dialect.)dialect.) You will get this result: image description

Then you may want to use findContours and do away with blobs that are more then e.g. twice as high as they are wide.

You may want to start using a top hat operation. That will make you get rid of the blurry non black background:background.

static void Main(string[] args)
{
Image<Gray, byte> image = new Image<Gray, byte>(@"c:\im.png");

int morphOpSize = 5;
StructuringElementEx element =
    new StructuringElementEx(
        morphOpSize,
        morphOpSize,
        morphOpSize / 2,
        morphOpSize / 2,
        Emgu.CV.CvEnum.CV_ELEMENT_SHAPE.CV_SHAPE_ELLIPSE);

Image<Gray, byte> filtered;
filtered = image.MorphologyEx(
    element,
    Emgu.CV.CvEnum.CV_MORPH_OP.CV_MOP_TOPHAT,
    1);
ImageViewer.Show(image.ConcateHorizontal(filtered));
}

(Sorry for my emgu dialect.) You will get this result: image descriptionSecond step would be binarization. I used a simple threshold, but there is still some work to be done here. Perhaps watersehd could help you.

Then you may want to use findContours and do away with blobs that are more then e.g. twice as high as they are wide.

static void Main(string[] args)
{
    Image<Bgr, byte> bgr = new Image<Bgr, byte>(@"k:\tomgoo\im.png");
    Image<Gray, byte> gray = bgr.Convert<Gray, byte>();

    // Perform top-hat
    int morphOpSize = 5;
    StructuringElementEx element =
        new StructuringElementEx(
            morphOpSize,
            morphOpSize,
            morphOpSize / 2,
            morphOpSize / 2,
            Emgu.CV.CvEnum.CV_ELEMENT_SHAPE.CV_SHAPE_ELLIPSE);

    Image<Gray, byte> filtered;
    filtered = gray.MorphologyEx(
        element,
        Emgu.CV.CvEnum.CV_MORPH_OP.CV_MOP_TOPHAT,
        1);

    // binarize image
    double thresh = CvInvoke.cvThreshold(
                    filtered,
                    filtered,
                    100,
                    255,
                    THRESH.CV_THRESH_BINARY);

    // find and filter out blobs
    Contour<Point> contours = filtered.FindContours(
        CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,
        RETR_TYPE.CV_RETR_CCOMP);

    Contour<Point> cont = contours;
    while (cont != null)
    {
        // Remember the next contour for later and isolate the current one
        Contour<Point> next = cont.HNext;
        cont.HNext = null;

        MCvBox2D minAreaRect = cont.GetMinAreaRect();
        if (minAreaRect.size.Height < 1.5 * minAreaRect.size.Width)
        {
            // Generate random color
            CvInvoke.cvDrawContours(
                bgr,
                cont,
                new MCvScalar(255, 0, 0),
                new MCvScalar(255, 0, 0),
                2,
                2,
                LINE_TYPE.EIGHT_CONNECTED,
                new Point(0, 0));
        }

        // Now go to the next contour
        cont = next;
    }
    bgr.Save(@"c:\out.png");
}

(Sorry for my emgu dialect.) You will get this result: image description and image description

You may want to start using a top hat operation. That will make you get rid of the blurry non black background.

Second step would be binarization. I used a simple threshold, but there is still some work to be done here. Perhaps watersehd could help you.

Then you may want to use findContours and do away with blobs that are more then e.g. twice 1.5 times as high as they are wide.

static void Main(string[] args)
{
    Image<Bgr, byte> bgr = new Image<Bgr, byte>(@"k:\tomgoo\im.png");
    Image<Gray, byte> gray = bgr.Convert<Gray, byte>();

    // Perform top-hat
    int morphOpSize = 5;
    StructuringElementEx element =
        new StructuringElementEx(
            morphOpSize,
            morphOpSize,
            morphOpSize / 2,
            morphOpSize / 2,
            Emgu.CV.CvEnum.CV_ELEMENT_SHAPE.CV_SHAPE_ELLIPSE);

    Image<Gray, byte> filtered;
    filtered = gray.MorphologyEx(
        element,
        Emgu.CV.CvEnum.CV_MORPH_OP.CV_MOP_TOPHAT,
        1);

    // binarize image
    double thresh = CvInvoke.cvThreshold(
                    filtered,
                    filtered,
                    100,
                    255,
                    THRESH.CV_THRESH_BINARY);

    // find and filter out blobs
    Contour<Point> contours = filtered.FindContours(
        CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,
        RETR_TYPE.CV_RETR_CCOMP);

    Contour<Point> cont = contours;
    while (cont != null)
    {
        // Remember the next contour for later and isolate the current one
        Contour<Point> next = cont.HNext;
        cont.HNext = null;

        MCvBox2D minAreaRect = cont.GetMinAreaRect();
        if (minAreaRect.size.Height < 1.5 * minAreaRect.size.Width)
        {
            // Generate random color
            CvInvoke.cvDrawContours(
                bgr,
                cont,
                new MCvScalar(255, 0, 0),
                new MCvScalar(255, 0, 0),
                2,
                2,
                LINE_TYPE.EIGHT_CONNECTED,
                new Point(0, 0));
        }

        // Now go to the next contour
        cont = next;
    }
    bgr.Save(@"c:\out.png");
}

(Sorry for my emgu dialect.) You will get this result: image description and image description

You may want to start using a top hat operation. That will make you get rid of the blurry non black background.

Second step would be binarization. I used a simple threshold, but there is still some work to be done here. Perhaps watersehd watershed could help you.

Then you may want to use findContours and do away with blobs that are more then e.g. 1.5 times as high as they are wide.

static void Main(string[] args)
{
    Image<Bgr, byte> bgr = new Image<Bgr, byte>(@"k:\tomgoo\im.png");
    Image<Gray, byte> gray = bgr.Convert<Gray, byte>();

    // Perform top-hat
    int morphOpSize = 5;
    StructuringElementEx element =
        new StructuringElementEx(
            morphOpSize,
            morphOpSize,
            morphOpSize / 2,
            morphOpSize / 2,
            Emgu.CV.CvEnum.CV_ELEMENT_SHAPE.CV_SHAPE_ELLIPSE);

    Image<Gray, byte> filtered;
    filtered = gray.MorphologyEx(
        element,
        Emgu.CV.CvEnum.CV_MORPH_OP.CV_MOP_TOPHAT,
        1);

    // binarize image
    double thresh = CvInvoke.cvThreshold(
                    filtered,
                    filtered,
                    100,
                    255,
                    THRESH.CV_THRESH_BINARY);

    // find and filter out blobs
    Contour<Point> contours = filtered.FindContours(
        CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,
        RETR_TYPE.CV_RETR_CCOMP);

    Contour<Point> cont = contours;
    while (cont != null)
    {
        // Remember the next contour for later and isolate the current one
        Contour<Point> next = cont.HNext;
        cont.HNext = null;

        MCvBox2D minAreaRect = cont.GetMinAreaRect();
        if (minAreaRect.size.Height < 1.5 * minAreaRect.size.Width)
        {
            // Generate random color
            CvInvoke.cvDrawContours(
                bgr,
                cont,
                new MCvScalar(255, 0, 0),
                new MCvScalar(255, 0, 0),
                2,
                2,
                LINE_TYPE.EIGHT_CONNECTED,
                new Point(0, 0));
        }

        // Now go to the next contour
        cont = next;
    }
    bgr.Save(@"c:\out.png");
}

(Sorry for my emgu dialect.) You will get this result: image description and image description