Thresholding

Thresholding is an basic technique in which some objects are identified on image/videos with the help of colour values. Objects like A red can, green ball are easily identified with Thresholding on color values. The following tutorial shows you how to extract green colour from the following images :

This Example will find out red regions in the upper Image.
 
Remember, thresholding isn’t the best algorithm (as you’ll see later)… but it gives reasonably good results for many images (as you can see in the image above).

Step 1 :

Make a New Project add two of the following header files .

#include <cv.h>
#include <highgui.h>

Step 2 :

Load an Image file :

IplImage* img = cvLoadImage("image1.jpg");

Step 3

Now, we’ll create 3 grayscale images. These 3 images will hold the red, green and blue channels of the image img. Add these lines to the main function:

IplImage* channelRed = cvCreateImage(cvGetSize(img), 8, 1);
IplImage* channelGreen = cvCreateImage(cvGetSize(img), 8, 1);
IplImage* channelBlue = cvCreateImage(cvGetSize(img), 8, 1);

The cvCreateImage function allocates memory for an image. Currently, all these images are the same blank… each pixel is black.

Step 4 :

Now, we’ll copy each channel into these images… one at a time:

cvSplit(img, channelBlue, channelGreen, channelRed, NULL);

The cvSplit command split the 3 channel image img into three different channels. The order is Blue, Green and Red because thats how its stored in memory.

Step 5 :

To extract actual red areas, we remove areas common with the green and blue channels… something like this: Just red = red channel – (green channel + blue channel). And we implement this in code using the following commands (add these to the main function):

cvAdd(channelBlue, channelGreen, channelGreen);
cvSub(channelRed, channelGreen, channelRed);

Basically, what we’ve done is add the blue and green channels, and store the result in the green channel. Then, subtract this green channel from the red channel. And store the result in red channel.

Step : 6

Now, we do the thresholding. Add these lines to the main function:

cvThreshold(channelRed, channelRed, 0, 255, CV_THRESH_BINARY);

The Threahold function has the following Syntax :
void cvThreshold( IplImage* src, IplImage* dst, float thresh, float maxvalue,CvThreshType type);

src Source image.
dst Destination image; can be the same as the parameter src.
thresh Threshold parameter.
maxvalue Maximum value; parameter, used with threshold types, CV_THRESH_BINARY, CV_THRESH_BINARY_INV, and CV_THRESH_TRUNC.
type Thresholding type; must be one of CV_THRESH_BINARY, CV_THRESH_BINARY_INV, CV_THRESH_TRUNC, CV_THRESH_TOZERO, CV_THRESH_TOZERO_INV,

Now the image will be displayed as :

See how the red region turn bright? This is segmentation. You create segments… White=red in the original image… black=non red.
 
Now, an analysis of what actually happens in the cvThreshold function. The function goes through each pixel of the image. If the value of the pixel is greater than 20 (the third parameter)… it changes it to a 255 (the fourth parameter). Thats the reason all the reds turn bright.
 
The first parameter is the source image. The second is the destination image.
 
And see the last parameter? (CV_THRESH_BINARY) This parameter decides the behaviour of this function. CV_THRESH_BINARY change the value to 255 when the value is greater than 20. An other possible value is: CV_THRESH_BINARY_INV… which is the reverse: if the value is greater than 20, it is set it 0… else it is set to 255.

Step 7 :

Now that we’ve thresholded the image, all we need to do is display it. Add these lines:

cvNamedWindow("original");
cvNamedWindow("red");
cvShowImage("original", img);
cvShowImage("red", channelRed);
cvWaitKey(0);
return 0;