User Tools

Site Tools


opencv_tutorials_t5

Tutorial 5

On this tutorial you will learn the principles of color threshold. It is a very useful tool to filter objects in an image by its color . Can be used together with tracking algorithm or Edge/Contours detectors to filter a specific object in an image.

Doing the threshold is very simple , just adjust the slider bars created on the trackbar window to filter the color that you want , move the bars to make the object that you want as white , and all the other undesired object as black.

I recommend you to type the code on your own to get familiarized with the program language. If you have trouble , the original code is attached bellow ( Running on Visual Studio 2015 + OpenCV 3.1 ) * Check the installation guide to make sure that you linked all the OpenCV modules to your Visual Studio.

Color Threshold


Color Threshold

<Code:clinenums:1> //Initializing the modules that will be used #include <sstream> #include <iostream> #include <opencv/highgui.h> #include <opencv/cv.h> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #define _CRT_SECURE_NO_WARNINGS //defining the namespace used ( no need to use cv:: or std:: before the API's) using namespace cv; using namespace std; //Values to be used on the HSV trackbar //these will be changed using trackbars int iLowH = 0; int iHighH = 179; int iLowS = 0; int iHighS = 255; int iLowV = 0; int iHighV = 255; //default capture width and height const int FRAME_WIDTH = 640; const int FRAME_HEIGHT = 480; //Function to create a window with the Trackbars to apply the Threshold. void createTrackbars() { //Open the window to display the Trackbars namedWindow("Trackbars", CV_WINDOW_AUTOSIZE); //Hue values (0 - 179) cvCreateTrackbar("LowH", "Trackbars", &iLowH, 179); cvCreateTrackbar("HighH", "Trackbars", &iHighH, 179); //Saturation Values (0-255) cvCreateTrackbar("LowS", "Trackbars", &iLowS, 255); cvCreateTrackbar("HighS", "Trackbars", &iHighS, 255); //Value (0-255) cvCreateTrackbar("LowV", "Trackbars", &iLowV, 255); cvCreateTrackbar("HighV", "Trackbars", &iHighV, 255); } //Function to apply the erode and dilate features. void DilateAndErode(Mat &image) { //Defining the erode and dilate properties //the erode element chosen here is a 3x3 piexels rectangle. //Change the Size argument to optimize your threshold. //dilate with 8x8 size element to make the threshold object more visible Mat erodeElement = getStructuringElement(MORPH_RECT, Size(3, 3)); Mat dilateElement = getStructuringElement(MORPH_RECT, Size(8, 8)); //Apply erode and dilate erode(image, image, erodeElement); dilate(image, image, dilateElement); } int main(int argc, char* argv[]) { //auxiliar variable to control the actions of the program int key; bool useFeatures = true; //Matrix to store the webcam image, the HSV image and the Threshold image Mat colorimage; Mat HSV; Mat threshold; //Call the function to create the window with the trackbars createTrackbars(); //Initialize the webcam capture VideoCapture capture; capture.open(0); //set height and width of capture frame capture.set(CV_CAP_PROP_FRAME_WIDTH, FRAME_WIDTH); capture.set(CV_CAP_PROP_FRAME_HEIGHT, FRAME_HEIGHT); char key = 0; //Until the User press q the loop will run //Get the image from the webcam -> convert to HSV -> Threshold the image //using the HSV max and min set on the Trackbar window. // When m is pressed the morphological transform will be applied. while (key != 'q') { if (key == 'm') { useFeatures = !useFeatures; } //Get the image from the webcam capture >> colorimage //Convert the frame from BGR (RGB) to HSV cvtColor(colorimage, HSV, COLOR_BGR2HSV); //filter the HSV image using the minimum and maximum values set on the //Trackbars window using the inRange function. inRange(HSV, Scalar(iLowH, iLowS, iLowV), Scalar(iHighH, iHighS, iHighV), threshold); //If the key M is pressed the dilate and erode features will be activated. if (useFeatures) { DilateAndErode(threshold); } //show Threshold , Webcam and HSV images. imshow("Threshold", threshold); imshow("Webcam", colorimage); imshow("HSV filter", HSV); key = waitKey(25); } return 0; } </Code> ---- ===== Understanding the code ===== <Code:c++ linenums:20> //Values to be used on the HSV trackbar //these will be changed using trackbars int iLowH = 0; int iHighH = 179; int iLowS = 0; int iHighS = 255; int iLowV = 0; int iHighV = 255; //default capture width and height const int FRAME_WIDTH = 640; const int FRAME_HEIGHT = 480; </Code> Some variables will be used inside the functions and inside the main program , so is convenient to set them as global variables (defined outside all ). We will create slider bars to adjust the Hue, Saturation and Value to Threshold our image , so we define the minimum and maximum value that each of this variables can get . Also we initialize the size of the captured image from our webcam as 640x480 pixels. ---- <Code:c++ linenums:35> //Function to create a window with the Trackbars to apply the Threshol. void createTrackbars() { //Open the window to display the Trackbars namedWindow("Trackbars", CV_WINDOW_AUTOSIZE); //Hue values (0 - 179) cvCreateTrackbar("LowH", "Trackbars", &iLowH, 179); cvCreateTrackbar("HighH", "Trackbars", &iHighH, 179); //Saturation Values (0-255) cvCreateTrackbar("LowS", "Trackbars", &iLowS, 255); cvCreateTrackbar("HighS", "Trackbars", &iHighS, 255); //Value (0-255) cvCreateTrackbar("LowV", "Trackbars", &iLowV, 255); cvCreateTrackbar("HighV", "Trackbars", &iHighV, 255); } </Code> Our first function is the function that will create a window to display the slider bars to adjust the HSV Threshold. First we create a new window using **"namedWindow"** to display the slider bars. Each slider bar is created using the command **"cvCreateTrackbar"** . The first argument is the name of the slider bar , the second argument is where it will be displayed (put the same name as the window that you opened using the **namedWindow** ).The third argument is the value that this track bar will store , and the fourth argument is the maximum value that can be assigned. We need to create six of these sliders, because our threshold will be made between a minimum and a maximum value of each H,S,V values. So we create slider bars for minimum and maximum Hue , minimum and maximum Saturation and minimum and maximum Value. ---- <Code:c++ linenums:57> //Function to apply the erode and dilate features. void DilateAndErode(Mat &image) { //Defining the erode and dilate properties //the erode element chosen here is a 3x3 piexels rectangle. //Change the Size argument to optimize your threshold. //dilate with 8x8 size element to make the threshold object more visible Mat erodeElement = getStructuringElement(MORPH_RECT, Size(3, 3)); Mat dilateElement = getStructuringElement(MORPH_RECT, Size(8, 8)); //Apply erode and dilate erode(image, image, erodeElement); dilate(image, image, dilateElement); } </Code> This function will be used to apply the morphological transformations erode and dilate. Both are used to make the threshold object more visible . Erode is useful to reject small noises in our threshold image (the noise is all the white little points that are thresholded together with the object but is not part of the object). Dilate is useful to be used after the erosion, because it will make the threshold object more visible , and will not amplify the noise because all the noise was already filtered by the erosion. Read more about morphological transformations [[http://docs.opencv.org/3.1.0/d9/d61/tutorial_py_morphological_ops.html#gsc.tab=0 linenums:77> int main(int argc, char* argv[]) {

//auxiliar variable to control the actions of the program
bool useFeatures = true;

Matrix to store the webcam image, the HSV image and the Threshold image Mat cameraFeed; Mat HSV; Mat threshold; Call the function to create the window with the trackbars

createTrackbars();
//Initialize the webcam capture
cv::VideoCapture capture;	
capture.open(0);

set height and width of capture frame capture.set(CV_CAP_PROP_FRAME_WIDTH, FRAME_WIDTH); capture.set(CV_CAP_PROP_FRAME_HEIGHT, FRAME_HEIGHT); </Code> Our main program will start defining the variables to be used to store the web camera video , the HSV version of the web camera video and the threshold version of the web camera video.Also a boolean variable will be declared to control the on/off use of the morphological transformations. We call the function that we made to create a window to display the slider bars to apply the threshold using “createTrackbars()“. The “Video Capture” followed by the capture.open(0) will store the web camera frame(default video source (0)) into the capture variable. We set the capture frame width and height using “capture.set”. —- <Code:c++ linenums:98> char key = 0; Until the User press q the loop will run

//Get the image from the webcam -> convert to HSV -> Threshold the image
//using the HSV max and min set on the Trackbar window.
      // When m is pressed the morphological transform will be applied.
while (key != 'q') 
{
	if (key == 'm')
	{
		useFeatures = !useFeatures;
	}
	//Get the image from the webcam
	capture >> colorimage
	//Convert the frame from BGR (RGB) to HSV
	cvtColor(colorimage, HSV, COLOR_BGR2HSV);

</Code>

Now we start our loop to capture frames from the webcam and work with these frames. The loop will run until the “q” key is pressed. The morphological transform will be turned on/off whenever “m” is pressed - we just use “useFeatures = !useFeatures” to change the value from TRUE to FALSE and vice-versa each time m is pressed. We get the frame from the webcam using “capture » “ and store it on the colorimage variable. We use the function “cvtColor” to convert the image from RGB to HSV.


<Code:c++ linenums:117>

              //filter the HSV image using the minimum and maximum values set on the 
	//Trackbars window using the inRange function.		
	inRange(HSV, Scalar(iLowH, iLowS, iLowV), Scalar(iHighH, iHighS, iHighV), threshold);

If the key M is pressed the dilate and erode features will be activated. if (useFeatures) { DilateAndErode(threshold); } </Code> We will threshold the HSV version because the colors are easily detected on the HSV version. We will threshold the image sliding the HSV bars on the Trackbars window , change the upper and lower values until only the object that you want to filter is visible ( it will be all black and the object white ). The threshold creates a binary image , where 0 is black and 1 is white - all the 1's will represent our object. Now with this binary image is easier to apply object tracking algorithm and find edges and contours. The threshold is done by the “inRange” function , that will turn white all the pixels that are in the range specified by it. The first argument is the HSV image , the second argument contains the minimum values of H , S and V. The third argument contains the maximum values of H , S and V and the last argument is the variable that will store the binary image. Every pixel that are between these minimum/maximum values will be turned into ones , and everything that is not will be turned into zeros ( this is the origin of the binary image (black/white). These minimum/maximum values will be updated every time that we move the slider bars on the Trackbars window. A conditional statement is introduced , whenever the boolean “useFeatures” is true ( when you press m it changes from true to false and vice-versa) it will call the “DilateAndErode” functions using the threshold image provided by the “inRange” as argument. As said on the “DilateAndErode” function explanation , the output will be stored into the same variable. —- <Code:c++ linenums:129> show Threshold , Webcam and HSV images.

	imshow("Threshold", threshold);
	imshow("Webcam", colorimage);
	imshow("HSV filter", HSV);

key = waitKey(25); </Code>

Finally , we show the original image , thresholded image and HSV image in three different windows using “imshow” . We update the key value whenever any key is pressed.

Below is a video demonstrating the program in real time.

opencv_tutorials_t5.txt · Last modified: 2017/05/13 17:44 by acater