opencv_tutorials_t6
Differences
This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
opencv_tutorials_t6 [2016/06/06 14:05] – created joaomatos | opencv_tutorials_t6 [2017/05/13 17:53] (current) – [Understanding the code] acater | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | Tutorial 6 | + | ===== Tutorial 6 ===== |
+ | |||
+ | On this tutorial you will learn how to use the Threshold together with tracking algorithm to track an object by its contour. The object will be defined as the biggest contour found.The idea is to mix Tutorial 4 ( Detecting edges and contours ) and Tutorial 5 ( Threshold ). | ||
+ | |||
+ | 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. | ||
+ | |||
+ | {{:: | ||
+ | |||
+ | ---- | ||
+ | |||
+ | ===== Tracking an object by its contour ===== | ||
+ | {{ :: | ||
+ | |||
+ | < | ||
+ | // | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | |||
+ | #define _CRT_SECURE_NO_WARNINGS | ||
+ | |||
+ | //defining the namespace used ( no need to use cv:: or std:: before the API' | ||
+ | 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(" | ||
+ | |||
+ | //Hue values (0 - 179) | ||
+ | cvCreateTrackbar(" | ||
+ | cvCreateTrackbar(" | ||
+ | |||
+ | // | ||
+ | cvCreateTrackbar(" | ||
+ | cvCreateTrackbar(" | ||
+ | |||
+ | //Value (0-255) | ||
+ | cvCreateTrackbar(" | ||
+ | cvCreateTrackbar(" | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | //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, | ||
+ | Mat dilateElement = getStructuringElement(MORPH_RECT, | ||
+ | |||
+ | //Apply erode and dilate | ||
+ | erode(image, | ||
+ | dilate(image, | ||
+ | |||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | int main(int argc, char *argv[]) | ||
+ | { | ||
+ | |||
+ | |||
+ | // | ||
+ | Mat coloredimage; | ||
+ | Mat edge; | ||
+ | Mat HSV; | ||
+ | Mat threshold; | ||
+ | |||
+ | |||
+ | //Edge detection Threshold | ||
+ | int edgeThreshold = 10; | ||
+ | |||
+ | |||
+ | //auxiliar variables to control the actions of the program | ||
+ | char key = 0; | ||
+ | bool useFeatures = true; | ||
+ | |||
+ | |||
+ | |||
+ | //Call the function to create the window with the trackbars | ||
+ | createTrackbars(); | ||
+ | // | ||
+ | VideoCapture capture; | ||
+ | capture.open(0); | ||
+ | |||
+ | //set height and width of capture frame | ||
+ | capture.set(CV_CAP_PROP_FRAME_WIDTH, | ||
+ | capture.set(CV_CAP_PROP_FRAME_HEIGHT, | ||
+ | |||
+ | //Until the User press ' | ||
+ | //Get the image from the webcam -> convert to HSV -> Threshold the image | ||
+ | //using the HSV max and min set on the Trackbar window. | ||
+ | //The threshold image will be used into the findcontours function to find the contours. | ||
+ | //The largest contour will be draw on the webcam frame. | ||
+ | while (key != ' | ||
+ | { | ||
+ | |||
+ | |||
+ | //Get the image from the webcam | ||
+ | capture >> coloredimage; | ||
+ | //Convert the frame from BGR (RGB) to HSV | ||
+ | cvtColor(coloredimage, | ||
+ | |||
+ | |||
+ | //filter the HSV image using the minimum and maximum values set on the | ||
+ | // | ||
+ | inRange(HSV, | ||
+ | |||
+ | if (key == ' | ||
+ | { | ||
+ | useFeatures = !useFeatures; | ||
+ | } | ||
+ | |||
+ | //If the key M is pressed the dilate and erode features will be activated. | ||
+ | if (useFeatures) | ||
+ | { | ||
+ | DilateAndErode(threshold); | ||
+ | } | ||
+ | |||
+ | //Show Threshold image | ||
+ | imshow(" | ||
+ | |||
+ | //Canny is a openCV function | ||
+ | // | ||
+ | Canny(threshold, | ||
+ | |||
+ | |||
+ | // | ||
+ | vector< | ||
+ | vector< | ||
+ | |||
+ | //The function findContours | ||
+ | |||
+ | findContours(edge, | ||
+ | |||
+ | |||
+ | //Find the largest contour to be draw on the image | ||
+ | int largest_area = 0; | ||
+ | int largest_contour_index = 0; | ||
+ | |||
+ | for (int i = 0; i < contours.size(); | ||
+ | { | ||
+ | double a = contourArea(contours[i], | ||
+ | if (a > largest_area) | ||
+ | { | ||
+ | largest_area = a; | ||
+ | largest_contour_index = i; //Store the index of largest contour | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | //draw the largest contour on the image | ||
+ | drawContours(coloredimage, | ||
+ | |||
+ | |||
+ | // Show image with contours in a new window. | ||
+ | imshow(" | ||
+ | |||
+ | key = waitKey(25); | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | return 0; | ||
+ | |||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | ---- | ||
+ | |||
+ | ===== Understanding the code ===== | ||
+ | |||
+ | < | ||
+ | //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(" | ||
+ | |||
+ | //Hue values (0 - 179) | ||
+ | cvCreateTrackbar(" | ||
+ | cvCreateTrackbar(" | ||
+ | |||
+ | // | ||
+ | cvCreateTrackbar(" | ||
+ | cvCreateTrackbar(" | ||
+ | |||
+ | //Value (0-255) | ||
+ | cvCreateTrackbar(" | ||
+ | cvCreateTrackbar(" | ||
+ | |||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | The code begins with the same idea of image threshold. Declaring the variables to be used on the Trackbars windows and defining the function to create the slider bars. You can see the commentaries | ||
+ | |||
+ | |||
+ | ---- | ||
+ | |||
+ | < | ||
+ | //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, | ||
+ | Mat dilateElement = getStructuringElement(MORPH_RECT, | ||
+ | |||
+ | //Apply erode and dilate | ||
+ | erode(image, | ||
+ | dilate(image, | ||
+ | |||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | Again the same idea of the image threshold code. To track an object first we need to obtain a binary image with only the object visible - and the morphological transform helps to optimaze the visibility of the thresholded object in the binary image by filtering the noise and expanding the object contour.After obtaining the binary image , we can apply the edge and contour detector and we can track the object by its contour - because the object contour will be the only contour shown in the binary image. | ||
+ | |||
+ | |||
+ | ---- | ||
+ | |||
+ | < | ||
+ | int main(int argc, char *argv[]) | ||
+ | { | ||
+ | |||
+ | |||
+ | // | ||
+ | Mat coloredimage; | ||
+ | Mat edge; | ||
+ | Mat HSV; | ||
+ | Mat threshold; | ||
+ | |||
+ | |||
+ | //Edge detection Threshold | ||
+ | int edgeThreshold = 10; | ||
+ | |||
+ | |||
+ | //auxiliar variables to control the actions of the program | ||
+ | char key = 0; | ||
+ | bool useFeatures = true; | ||
+ | |||
+ | </ | ||
+ | |||
+ | Our main program start with the variables declaration.The coloredimage variable will store the web camera frame , the edge will store the output from **" | ||
+ | |||
+ | Also we declare the key variable to control the loop ( to end the program when ' | ||
+ | |||
+ | |||
+ | ---- | ||
+ | |||
+ | < | ||
+ | //Call the function to create the window with the trackbars | ||
+ | createTrackbars(); | ||
+ | // | ||
+ | VideoCapture capture; | ||
+ | capture.open(0); | ||
+ | |||
+ | //set height and width of capture frame | ||
+ | capture.set(CV_CAP_PROP_FRAME_WIDTH, | ||
+ | capture.set(CV_CAP_PROP_FRAME_HEIGHT, | ||
+ | |||
+ | </ | ||
+ | |||
+ | We call the **" | ||
+ | |||
+ | The web camera video is initialize using the **" | ||
+ | |||
+ | |||
+ | ---- | ||
+ | |||
+ | < | ||
+ | //Until the User press ' | ||
+ | //Get the image from the webcam -> convert to HSV -> Threshold the image | ||
+ | //using the HSV max and min set on the Trackbar window. | ||
+ | //The threshold image will be used into the findcontours function to find the contours. | ||
+ | //The largest contour will be draw on the webcam frame. | ||
+ | while (key != ' | ||
+ | { | ||
+ | |||
+ | |||
+ | //Get the image from the webcam | ||
+ | capture >> coloredimage; | ||
+ | //Convert the frame from BGR (RGB) to HSV | ||
+ | cvtColor(coloredimage, | ||
+ | |||
+ | </ | ||
+ | |||
+ | The main loop of the program will stop when ' | ||
+ | |||
+ | Using the **" | ||
+ | |||
+ | |||
+ | ---- | ||
+ | |||
+ | < | ||
+ | //filter the HSV image using the minimum and maximum values set on the | ||
+ | // | ||
+ | inRange(HSV, | ||
+ | |||
+ | if (key == ' | ||
+ | { | ||
+ | useFeatures = !useFeatures; | ||
+ | } | ||
+ | |||
+ | //If the key M is pressed the dilate and erode features will be activated. | ||
+ | if (useFeatures) | ||
+ | { | ||
+ | DilateAndErode(threshold); | ||
+ | } | ||
+ | |||
+ | //Show Threshold image | ||
+ | imshow(" | ||
+ | |||
+ | </ | ||
+ | |||
+ | Now the threshold is done by the **" | ||
+ | |||
+ | The ' | ||
+ | |||
+ | |||
+ | ---- | ||
+ | |||
+ | < | ||
+ | //Canny is a OpenCV function | ||
+ | // | ||
+ | Canny(threshold, | ||
+ | </ | ||
+ | |||
+ | As we used on the Tutorial from [[http:// | ||
+ | |||
+ | |||
+ | ---- | ||
+ | |||
+ | < | ||
+ | // | ||
+ | vector< | ||
+ | vector< | ||
+ | |||
+ | //The function findContours | ||
+ | |||
+ | findContours(edge, | ||
+ | |||
+ | </ | ||
+ | |||
+ | To use the function to find the contours " | ||
+ | |||
+ | The " | ||
+ | |||
+ | |||
+ | ---- | ||
+ | |||
+ | < | ||
+ | //Find the largest contour to be draw on the image | ||
+ | int largest_area = 0; | ||
+ | int largest_contour_index = 0; | ||
+ | |||
+ | for (int i = 0; i < contours.size(); | ||
+ | { | ||
+ | double a = contourArea(contours[i], | ||
+ | if (a > largest_area) | ||
+ | { | ||
+ | largest_area = a; | ||
+ | largest_contour_index = i; //Store the index of largest contour | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | After applying the **" | ||
+ | |||
+ | For sure we know that the object that we want to track will be the biggest contour on the binary image , so we can use a **" | ||
+ | |||
+ | |||
+ | ---- | ||
+ | < | ||
+ | //draw the largest contour on the image | ||
+ | drawContours(coloredimage, | ||
+ | |||
+ | |||
+ | // Show image with contours in a new window. | ||
+ | imshow(" | ||
+ | |||
+ | key = waitKey(25); | ||
+ | </ | ||
+ | |||
+ | | ||
+ | |||
+ | We show the image with the web camera frame and the contour drawn using the **" | ||
+ | \\ | ||
+ | \\ | ||
+ | The video below demonstrates the program running in real time. | ||
+ | {{youtube> |
opencv_tutorials_t6.1465247157.txt.gz · Last modified: by joaomatos