OPenCV contour discovery

Introduction to contour discovery

Definition of profile

An outline represents a series of points (pixels), which form an ordered point set, so an outline can be understood as an ordered point set.

Contour discovery definition

Contour discovery is a method to find object contour based on image edge extraction.
Therefore, the threshold selection of edge extraction will affect the final contour discovery result

Related API

findContours find contours

Function function:
In OpenCV, a function is provided to return or output an ordered point set or a set of ordered point sets (referring to multiple ordered point sets). The function findContour calculates the contour from the binary image. It can use the Canny() function to process the image, because such image contains edge pixels; You can also use threshold() or adaptive threshold() to process the image, and its edge is hidden at the junction of positive and negative regions. This function is declared as follows:

Function prototype:

void findContours(
	InputOutputArray image, 
	OutputArrayOfArrays contours,
	OutputArray hierarchy, 
	int mode,int method, 
	Point offset = Point()
);

Function parameters:

  • Image: single channel image matrix, which can be gray image, but more commonly used is binary image, which is generally binary image processed by Canny, Laplace and other edge detection operators;

  • Contours: vector < vector > type is a vector and a double vector. Each element in the vector holds a vector of a set of points composed of continuous Point points. Each set of Point points is an outline. The vector contours has as many elements as there are contours.

  • Hierarchy: vector type. Vec4i is the alias of VEC < int, 4 >, that is, each element in the container is a vector containing four int variables. Therefore, from the definition, hierarchy is also a vector, and each element in the vector stores an array containing four int integers.

    Supplementary note: the elements in the vector hiararchy correspond to the elements in the contour vector contour one by one, and the capacity of the vector is the same. The four int variables of each element in the hierarchy vector - hierarchy[i][0] ~hierarchy[i][3], respectively represent the index numbers of the next contour, the previous contour, the parent contour and the embedded contour of the ith contour. If the current contour does not have a corresponding next contour, previous contour, parent contour or embedded contour, the corresponding bits of hierarchy[i][0] ~hierarchy[i][3] are set to the default value of - 1.

  • Mode: type int, which defines the retrieval mode of the contour:

Valuemeaning
CV_RETR_EXTERNALOnly the outermost contour is detected, and the inner contour contained in the outer contour is ignored;
CV_RETR_LISTDetect all contours, including inner and outer contours, but the detected contours do not establish a hierarchical relationship, are independent of each other, and have no hierarchical relationship, which means that there is no parent contour or embedded contour in this retrieval mode, so the 3rd and 4th components of all elements in the hierarchy vector will be set to - 1, which will be discussed below;
CV_RETR_CCOMPAll contours are detected, but only two hierarchical relationships are established for all contours. The periphery is the top layer. If the inner contour in the periphery also contains other contour information, all contours in the inner circumference belong to the top layer;
CV_RETR_TREE, detect all contours, and establish a hierarchical tree structure for all contours. The outer contour contains the inner contour, and the inner contour can continue to contain the embedded contour.
  • Method: type int, which defines the approximate method of the contour:
Valuemeaning
CV_CHAIN_APPROX_NONESave all continuous contour points on the object boundary into the contour vector;
CV_CHAIN_APPROX_SIMPLEOnly the inflection point information of the contour is saved, and all the points at the inflection point of the contour are saved into the contour vector, and the information points on the straight line segment between the inflection point and the inflection point are not retained;
CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS uses teh chinl chain approximation algorithm;
  • Point: offset, the offset of all contour information relative to the corresponding point of the original image, which is equivalent to adding the offset to each detected contour point, and point can also be a negative value.

matters needing attention:
Obviously, the meaning of "looking for outline" can be seen from the function name.

We can get the edge binary image or foreground binary image through the edge detection algorithm. The edge pixels or foreground pixels of the binary image can be seen to be composed of multiple contours (point sets).

The function findContours is used to split the edge pixels or foreground pixels of the binary image into multiple contours, which is convenient for discussing each contour separately. The parameter image represents a binary image, and contours represents multiple contours output.

For the C++API of this function, a contour is described by vector, so how to represent multiple contours (multiple point sets)? That is, what data structure is the parameter contours?

In C++API, vector < vector > is used to describe multiple contours, that is, multiple contours exist in one vector.

Draw contours

Function function:
OpenCV provides a function to draw multiple contours found by findContours

Function prototype:

void drawContours(
	InputOutputArray image, 
	InputArrayOfArrays contours, 
	int contourIdx,
	const Scalar& color,
	int thickness = 1,
	int lineType = 8, 
	InputArray hierarchy = noArray(),
	int maxLevel = INT_MAX, 
	Point offset = Point()
)

The parameters are explained as follows:

  • Image: represents the input image matrix and draws the outline on the figure;
  • Contours: is the set of a series of points obtained, representing multiple contours;
  • contourIdx: it is an index, which represents the outline in the contours drawn;
  • Color: the filled color. Monochrome can be set to Scalar(255), etc;
  • Thickness: the line thickness of the drawn Contour. If the parameter value is less than 0, it means to fill the area in the whole Contour;
  • lineType: line connectivity;
  • hierarchy: optional hierarchical information structure, which is the contour based hierarchical information found by findContours;
  • maxLevel: the maximum level at which the profile is drawn. If the level is 0, draw a separate profile. If it is 1, draw the contour and then the contour at the same level. If the value is 2, all contours are. If the level is 2, draw all contours at the same level and all contours at the lower level, and so on. If the value is negative, the function does not draw the contour of the same level, but draws the sub contour up to the level of abs(max_level)-1 in ascending order
  • Offset: move the coordinates of each contour point according to the given offset This parameter is used when the contour is extracted from some regions of interest (ROI), and then the ROI offset needs to be considered in the operation.

Code example


#include <iostream>
#include <math.h>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/highgui/highgui_c.h> 

using namespace std;
using namespace cv;

Mat src, dst;
const char* output_win = "findcontours-demo";
int threshold_value = 100;
int threshold_max = 255;
RNG rng;
void Demo_Contours(int, void*);
int main(int argc, char** argv) 
{
	src = imread("./test2.jpg");
	if (src.empty()) {
		printf("could not load image...\n");
		return -1;
	}
	namedWindow("input-image", CV_WINDOW_AUTOSIZE);
	namedWindow(output_win, CV_WINDOW_AUTOSIZE);
	imshow("input-image", src);
	cvtColor(src, src, CV_BGR2GRAY);

	const char* trackbar_title = "Threshold Value:";
	createTrackbar(trackbar_title, output_win, &threshold_value, threshold_max, Demo_Contours);
	Demo_Contours(0, 0);

	waitKey(0);
	return 0;
}

void Demo_Contours(int, void*) {
	Mat canny_output;
	vector<vector<Point>> contours;
	vector<Vec4i> hierachy;
	Canny(src, canny_output, threshold_value, threshold_value * 2, 3, false);
	imshow("canny_output", canny_output);
	findContours(canny_output, contours, hierachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));

	dst = Mat::zeros(src.size(), CV_8UC3);
	RNG rng(12345);
	for (size_t i = 0; i < contours.size(); i++) {
		Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
		drawContours(dst, contours, i, color, 2, 8, hierachy, 0, Point(0, 0));
	}
	imshow(output_win, dst);
}

Keywords: OpenCV AI Computer Vision

Added by advoor on Wed, 26 Jan 2022 21:36:19 +0200