4

I am trying to make an colored object tracker which uses a binary image and blob detector to follow the target sort of like this: https://www.youtube.com/watch?v=9qky6g8NRmI . However I can not figure out how the ThresholdBinary() method work and if it is even the right one.

Here is a relevant bit of the code:

cam._SmoothGaussian(3);

blobDetector.Update(cam);
Image<Bgr,byte> binaryImage = cam.ThresholdBinary(new Bgr(145,0,145),new Bgr(0,0,0));
Image<Gray,byte> binaryImageGray = binaryImage.Conver<Gray,byte>();

blobTracker.Process(cam, binaryImageGray);

foreach (MCvBlob blob in blobTracker)
{
   cam.Draw((Rectangle)blob, new Bgr(0,0,255),2);
}

When I display the binaryImage I do not even get blobs. I just get a black image.

e_phi
  • 166
  • 1
  • 9

1 Answers1

3

Typically, the colored blob detection part of such an application works along the lines of:

  1. Convert the image to HSV (hue, saturation, value) color space.
  2. Filter the hue channel for all pixels with a hue value near the target value. Thresholding will typically give you all pixels with a value above or below the threshold. You are interested in the pixels near some target value.
  3. Filter the obtained mask some more, possibly using the saturation/value channels or by removing small blobs. Ideally only the target blob remains.

Some sample code that aims to find a green object (hue ~50) such as the green ball shown in the video:

// 1. Convert the image to HSV
using (Image<Hsv, byte> hsv = original.Convert<Hsv, byte>())
{
    // 2. Obtain the 3 channels (hue, saturation and value) that compose the HSV image
    Image<Gray, byte>[] channels = hsv.Split(); 

    try
    {
        // 3. Remove all pixels from the hue channel that are not in the range [40, 60]
        CvInvoke.cvInRangeS(channels[0], new Gray(40).MCvScalar, new Gray(60).MCvScalar, channels[0]);

        // 4. Display the result
        imageBox1.Image = channels[0];
    }
    finally
    {
        channels[1].Dispose();
        channels[2].Dispose();
    }
}
TC.
  • 4,133
  • 3
  • 31
  • 33
  • That is exactly what I needed Thanks. In hindsight using HSV does also make my life a whole lot easier as well. – e_phi Jun 04 '14 at 07:52
  • Is there any way I can create a range for the Saturation as well? – e_phi Jun 04 '14 at 09:41
  • Yes, by repeating the process above for the saturation channel and then combining both channels using binary AND: channels[0]._And(channels[1]); – TC. Jun 04 '14 at 10:11