User Tools

Site Tools


opencv_tutorials_t4

Tutorial 4

On this tutorial you will learn how to detect edges and contours on in image using simple OpenCV functions and how to draw these contours in a new image. The most practical way to detect edges and contours in videos is using color Thresholding , so the tutorial with the edge and contours detected in a video will be introduced after the tutorial that will explain how the Threshold works.

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.

Detecting Edges and Contours


Detecting Edges and Contours

<Code:clinenums:1> //Blocks that we will need on this program #include "opencv2/highgui/highgui.hpp" #include "opencv2/core/core.hpp" #include "opencv2/imgproc/imgproc.hpp" // declaring the namespaces using namespace std; using namespace cv; int main(int argc, char *argv[]) { //FINDING EDGES //Variables to store the opened image , a gray version , edge and cedge Mat coloredimage; Mat grayimage; Mat edge; //Edge detection Threshold int edgeThreshold = 10; //Read image and convert to gray scale coloredimage = imread("C:/Users/jcunhamatos/Desktop/ec.jpg"); cvtColor(coloredimage, grayimage, CV_BGR2GRAY); imshow("Original Image", coloredimage); //Canny is a openCV function (Canny Algorithm to edge detection ) //Canny(source image , output image , threshold 1 , threshold 2 (usually 3 times threshold1) , kernel size ) Canny(grayimage, edge, edgeThreshold, edgeThreshold * 3, 3); imshow("Edge Detector", edge); //END OF EDGE DETECTOR //FINDING CONTOUR //The function findContours Use the output of the Canny function as input //Initializing two vectors to be used on the findContours function vector<vector<Point> > contours; vector<Vec4i> hierarchy; // Find contours findContours(edge, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0)); // Initialize drawing variable to store the image with the contours Mat drawing = Mat::zeros(edge.size(), CV_8UC3); //Loop to draw the contours into the drawing image //Use the function drawContours. for (int i = 0; i< contours.size(); i++) { drawContours(drawing, contours, i, Scalar(0, 0, 255), 2, 8, hierarchy, 0, Point()); } // Show image with contours in a new window. imshow("Find Contours", drawing); waitKey(0); return 0; } </Code> ---- ===== Understanding the Code ===== <Code:c++ linenums:15> //FINDING EDGES //Variables to store the opened image , a gray version , edge and cedge Mat coloredimage; Mat grayimage; Mat edge; //Edge detection Threshold int edgeThreshold = 10; </Code> We start defining the variables that we will need. The function to detect the edges uses a thresholded version of the original image (we can use gray scale) , and asks for a threshold value - so we define these two variables. The function to detect contours will use the image with the edge detected and will output an image with the contours. ---- <Code:c++ linenums:25> //Read image and convert to gray scale coloredimage = imread("C:/Users/jcunhamatos/Desktop/ec.jpg"); cvtColor(coloredimage, grayimage, CV_BGR2GRAY); imshow("Original Image", coloredimage); //Canny is a openCV function (Canny Algorithm to edge detection ) //Canny(source image , output image , threshold 1 , threshold 2 (usually 3 times threshold1) , kernel size ) Canny(grayimage, edge, edgeThreshold, edgeThreshold * 3, 3); imshow("Edge Detector", edge); //END OF EDGE DETECTOR </Code> First we need to detect the edges. We start opening our colored image using **"imread"** , we create a gray scale version using **"cvtColor"** and display the original image in a new window. The OpenCV function to detect the edges is **"Canny"** and it takes the gray scale image as input , and will create an image with all the edges detected defined on the second argument. The threshold can be adjusted on the second and third argument (max and min). We display the image with the edges detected in a new window using the **"imshow"**. ---- <Code:c++ linenums:39> //FINDING CONTOUR //The function findContours Use the output of the Canny function as input //Initializing two vectors to be used on the findContours function vector<vector<Point> > contours; vector<Vec4i> hierarchy; // Find contours findContours(edge, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0)); </Code> Now that we have an image with the edges detected , we can use it as input on the function that will find the contours.First need to be declared the vector that will store the points of the contours detected and a vector to define the hierarchy - the hierarchy vector contain as many element as the number of contours found (if we know its size , we know how many contours were found) , and contains information about the image topology. The function is **"findContours"** and will take as input the edge image and will give as output a vector with the contours point ( that we will need to draw this vector on the image after ). The rest of the arguments we does not need to change for the most of applications. The last argument can be useful in some situations , as it define a contour offset (shift every point of the detected contour ). You can read more about it [[http://docs.opencv.org/2.4/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=findcontours linenums:49> Initialize drawing variable to store the image with the contours Mat drawing = Mat::zeros(edge.size(), CV_8UC3); Loop to draw the contours into the drawing image

//Use the function drawContours.
for (int i = 0; i< contours.size(); i++)
{
	drawContours(drawing, contours, i, Scalar(0, 0, 255), 2, 8, hierarchy, 0, Point());
}

</Code>

The vector with the points that define all the detected contours is stored on the “contours” vector. We want to draw all these points in an image and display it. First we set a new variable that will store the new image with the contours drawn. To avoid errors , we initialize this variable with the same size of the image with the edges and containing just 0 values ( all black ).

Now we will use a “ for “ loop to draw all the contours points on our new image variable called drawing. It starts from 0 and goes to the size of the contours vector. The function to draw the contours is “drawContours” . The first argument is where the contours will be drawn , the second argument is the vector with the contours points and the third argument is the color of the drawn contours ( on this case Scalar(0,0,255) is pure red).


<Code:c++ linenums:58> Show image with contours in a new window. imshow(“Find Contours”, drawing); waitKey(0); return 0; </Code> Finally we display the image with the contours drawn using “imshow”, and close the program when any key is pressed “waitKey(0)“

The video below demonstrates the program being run in real time.

opencv_tutorials_t4.txt · Last modified: 2017/05/13 17:32 by acater