Opencv -- contour discovery and analysis
Only oneself is strong 2021-06-04 10:35:28


One of the most common ways of binary image analysis is Contour discovery And Profile analysis , The purpose of contour discovery is to prepare for contour analysis , After contour analysis, we can get all kinds of useful attribute information of contour .

Here's edge detection , And the difference between contour extraction :

Edge detection is mainly used to detect the sharp change of light and dark in digital image by some means ( That is, the gradient change is relatively large ) Pixel point , Biased to changes in pixels in the image . Such as canny edge detection , The results are usually stored in edge maps of the same size and type as the source image . 
Contour detection refers to the detection of object boundaries in an image , They prefer to focus on the upper semantic objects . Such as OpenCV Medium findContours() function , It gets every contour and stores it as a point vector , In addition, we also get the topological information of an image , That is, the next contour of a contour 、 The previous profile 、 Index numbers of parent and embedded profiles . 

One , Discovery and drawing of contour

  stay OpenCV Inside use findContours() Functions and drawContours() Function to achieve this function .

  • findContours() function
void findContours(
InputArray image,
OutputArrayOfArrays contours,
OutputArray hierarchy,
int mode,
int method,
Point offset = Point()

Parameter one : image, The input image 、 Eight bit single channel , Binary image with black background .( It's usually after Canny、 Laplace and other edge detection operators processed binary image )

Parameter two :contours, Output contour image . It's a vector , Every element of a vector is an outline . therefore , Every element of this vector is still a vector . namely :

 vector<vector<Point> > contours;

Parameter 3 :hierarchy, Output the inheritance relationship of each contour .hierarchy It's also a vector , Length and contours equal , Each element and contours The elements of are corresponding to .hierarchy Each element of is a vector of four integers . namely :

 vector<Vec4i> hierarchy;

Parameter 4 :mode, The method of detecting contour . There are four ways :

  1. RETR_EXTERNAL: Only the outer contour is detected . Ignore the holes inside the profile .
  2. RETR_LIST: Detect all contours , But don't build inheritance ( contain ) Relationship .
  3. RETR_TREE: Detect all contours , And build all the inheritance ( contain ) Relationship .
  4. RETR_CCOMP: Detect all contours , But only two levels of inclusion are established .

Parameter 5 :method, Coding information for each profile . There are also four ( The first two are often used )

  1. CHAIN_APPROX_NONE: Store all the points on the contour .
  2. CHAIN_APPROX_SIMPLE: Only inflection points on the contour are stored .
  3. CHAIN_APPROX_TC89_L1,CHAIN_APPROX_TC89_KCOS Use teh-Chinl chain The approximate algorithm

Parameter 6 : Point, Offset . The default is 0

Be careful This function treats the white area as a foreground object . therefore findContours() The function is to find a white outline on a black background .( important !!!)

  • drawContours() function
InputOutputArray binImg, // Output image 
OutputArrayOfArrays contours,// All found contour objects 
Int contourIdx// Outline index number ,-1 Means to draw all the contours 
const Scalar & color,// When drawing, color 
int thickness,// Draw line width ,-1 Represents the interior of the fill profile 
int lineType,// The type of wire LINE_8
InputArray hierarchy,// Topology diagram 
int maxlevel,// Maximum number of layers , 0 Just draw the current ,1 Represents the drawing of the current and its embedded contours 
Point offset = Point()// Contour displacement , Optional 

Two , Profile analysis

  After getting the outline of the image , We can do profile analysis . After contour analysis, we can get all kinds of useful attribute information of contour 、 The common ones are as follows :

  • Calculate the contour area : 

contourArea(contour, oriented = False) // Calculate the area of the contour 

Parameter description :contour For the input single contour value ;oriented: Contour direction , The default value is false.
If true, This function returns a signed area , It depends on the direction of the contour ( Clockwise or counterclockwise ).
If it's the default value false, The area is returned as an absolute value .
According to this feature, the position of the contour can be determined by the symbol of the area .
  • Calculate contour perimeter :arcLength()

arcLength(contour, closed) // Calculate the perimeter of the contour 
Parameter description :contour For the input single contour value ,closed Indicates whether the contour is closed (true For closure ,false For not closing )
  • Calculate the geometric moment and the center distance : moments()

 Moments m = moments(contours[t]); // Get the distance of the contour
// Calculate the centroid of the contour 
double cx = m.m10 / m.m00;
double cy = m.m01 / m.m00;
  • The circumscribed rectangle of the outline

There are two kinds of circumscribed rectangles of contours , Here's the picture , The green one is called the circumscribed rectangle boundingRect(), Represents a rectangle that does not consider rotation and can contain the entire contour . The blue one is called the smallest circumscribed rectangle minAreaRect(), Consider rotation

1️⃣ Outside rectangle boundingRect()

Rect rect = boundingRect(Mat(contours[i]));// Get the outline circumscribed positive rectangle 
rectangle(src, rect, (0, 0, 255), 2, 8, 0);

2️⃣ Minimum circumscribed rectangle minAreaRect()

RotatedRect rect = minAreaRect(contours[i]);// Get the minimum circumscribed rectangle of the contour 
Point2f P[4];
rect.points(P);// Get the four vertex coordinates 
for (int j = 0; j <= 3; j++)
line(src, P[j], P[(j + 1) % 4], Scalar(0,0,255), 1);// Connect in turn 
  • The smallest circumscribed circle / Fitting circle :minEnclosingCircle()

void minEnclosingCircle(InputArray points, Point2f& center, float& radius);
points, Input two-dimensional point set , It can be vector or Mat type .
center, The output center of a circle .
radius, The output radius of the circle .
for example :
findContours(bin_img, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
// Look for the smallest circle of the outline of the package 
vector<Point2f>centers(contours.size());// The number of centers of a circle 
vector<float>radius(contours.size());// The number of radii 
for (int i = 0; i < contours.size(); i++) 
// Find and draw the smallest circle minEnclosingCircle(contours[i], centers[i], radius[i]); circle(src, centers[i], radius[i], scalar(0,0,255), 2); }
  • Fit ellipse :fitEllipse()
RotatedRect fitEllipse(InputArray points);
// The only parameter is the input two-dimensional point set , It can be vector or Mat type .
for example :
// Find and draw the smallest ellipse rota_rect[i]
= fitEllipse(contours[i]); ellipse(dst, rota_rect[i], scalar(0,0,255), 2);
  • The convex hull of the contour :convexHull()

convexHull ( InputArray points, / Input two-dimensional point set ,Mat Type data 
OutputArray hull, // Output parameters , Used to output the convex hull found 
bool clockwise = false, // Operation direction , When the identifier is true , The output convex hull is clockwise , Otherwise it's counter clockwise .
bool returnPoints = true // Operation identifier , The default value is true, At this point, return to each point of each convex hull , Otherwise, it returns the exponent of each point of the convex hull 
  • Polygonal approximation - Close to the real shape :approxPolyDP()

void approxPolyDP( InputArray curve, // Input curve , Generally, it is a set of points composed of contour points of an image 
OutputArray approxCurve, // Represents the output polygon point set 
double epsilon, // Mainly refers to the accuracy of the output , Is the maximum distance between the other contour points 
bool closed // Indicates whether the output polygon is closed 


Please bring the original link to reprint ,thank
Similar articles