当前位置:网站首页>47_ Contour lookup in opencv cv:: findcontours()

47_ Contour lookup in opencv cv:: findcontours()

2022-07-07 16:15:00 sinat_ forty-one million seven hundred and fifty-two thousand t

A contour corresponds to a series of points , These points represent a curve in the image in some way .OpenCV in , Contour with standard template library vector vector<> Express , The most common is to use a series of two-dimensional vertices (vector<cv::Point> or vector<cv::Point2f> Express .

function cv::findContours() Calculate the contour from the two-dimensional image , It can process images from cv::Canny() Function to get the image with edge pixels , Or from cv::threshold() And cv::adaptiveThreshold() Image obtained by function .

1. Find the outline cv::findContours

cv::findContours() The function prototype :

void cv::findContours(
	cv::InputOutputArray image,  // input binary 8-bit single channel
	cv::InputOutputArrayOfArrays contours,  // vector of vectors or points
	cv::OutputArray hierarchy,  // (optional) topology information
	int mode,  // contour retrieval mode
	int method,  // approximation method
	cv::Point offset = cv::Point()  // (optional) offset every point
);

void cv::findContours(
	cv::InputOutputArray image,  // input binary 8-bit single channel
	cv::OutputArrayOfArrays contours,  // vector of vectors or pointd
	int mode,  // contour retrieval mode
	int method,  // approximation method
	cv::Point offset = cv::Point()  // (optional) offset every point;
);

Parameters image It's the input image , Must be 8 Bit single channel image , Should be transformed into binary Of .cv::findContours() Function will change the parameter , So if the image will be useful in the future , It should be copied and then transmitted to cv::findContours().

Parameters contours It's a set of arrays , In most cases, it is one or more standard template libraries vector. This parameter is the contour found . For example, in an outline vector in ,contours[i] It's an outline , and contours[i][j] It's the outline contours[i] A point on .

Parameters hierarchy Optional. , If this parameter is given ,hierarchy The tree structure of all contours will be output . This parameter is an array , Each contour corresponds to a value in the array . Each value in the array is a quaternion array , Each element represents a node with a specific link to the current node , The meaning of each element is as follows :

Indexes meaning
0 The next contour of the same level
1 The previous contour of the same level
2 The first child node of the lower level
3 Parent node of the parent

Parameters mode Represents the desired contour extraction method , Yes 4 Kind of :

  • cv::RETR_EXTERNAL: Retrieve only the outermost contour , And the contour is not connected with other contours .
  • cv::RETR_LIST: Retrieve all contours and save them to the table .
  • cv::RETR_CCOMP: Retrieve all the contours , And organize them into a double-layer structure .
  • cv::RETR_TREE: Retrieve all contours and rebuild the mesh contour structure .

Parameters method Indicates how the outline is expressed , The options are :

  • cv::CHAIN_APPROX_NONE: Convert all points in contour coding into points , This operation will produce a large number of points , Each point will become the 8 One of the adjacent points , Will not reduce the number of points returned .
  • cv::CHAIN_APPROX_SIMPLE: Compression level 、 vertical 、 The oblique part , Keep only the last point , In many special cases , This operation will greatly reduce the number of returned points . An extreme example is , For one along x-y Rectangle in direction , Only return 4 A little bit .
  • cv::CHAIN_SPPROX_TC89_L1 or cv::CHAIN_APPROX_TC89_KCOS: Use Teh-chin One of the chain approximation algorithms .Teh-Chin Algorithm is a more complex and computationally intensive Algorithm , Used to reduce the number of points returned . function T-C No additional parameters are required .

Parameters offset Optional. , If this parameter is given , All points in the returned contour will be offset according to the parameter value . Usually used in two cases : When the contour extracted from the region of interest is expressed in the original coordinate system , Second, when the contour extracted from the original image is expressed in the image sub region coordinate system .

2. Draw the outline cv::drawContours

After finding the contour, the most common function is to draw the detected contour on the screen , You can use functions cv::drawContours() Function completion . The function prototype :

void cv::drawContours(
	cv::InputOutputArray image,  // will draw on input image
	cv::InputArrayOfArrays contours,  // vector of vectors or pointd
	int contourIdx,  // contour to draw (-1 is all)
	const cv::Scalar &color,  // color for contours
	int thickness = 1,  // thickness for contour lines
	int lineType = 8,  // connectedness ('4' or '8')
	cv::InputArray hierarchy = cv::noArray(),  // optional from find contours
	int maxLevel = INT_MAX,  // max descent in hierarchy
	cv::Point offset = cv::Point()  // (optional) offset all points
);

Parameters image, The image to be outlined .

Parameters contour Is the outline to be drawn , The type of this parameter is the same as cv::findContours() Output contour identical , Is the point stored in the list .

Parameters contourIdx Used to tell cv::drawContours() What needs to be drawn is contours Whether a certain contour or all contours in the parameter , If it's a positive number , Then the corresponding contour will be drawn , If it's negative , All outlines will be drawn .

Parameters color、thickness、lineType The function of is the same as that of the corresponding parameters in other functions used for drawing , Respectively represent the color of painting , The thickness of the drawn line , Type of sketch line ( Four Unicom / Eight connections /AA Line ).

Parameters hierarchy Corresponding cv::findContours() Level of function output . Parameters hierarchy And parameters maxLevel Work together .maxLevel Limit the depth of the contour hierarchy that will be drawn on the graph ,maxLevel=0 It means to draw only the second 0 The outline of the layer , Set to other non 0 Positive numbers , It means drawing the contour of the same number of levels below the highest level . If you want to display only the outermost outline when connecting components , Very helpful .

Parameters offset Optional , When the contour coordinate system is converted into the execution coordinate system or other local coordinate system , This feature is very useful .

Use VS2010+opencv2.4.9 when ,32 Bit tests always crash , Prompt that the heap is broken , And there is also a problem with the contour obtained by the function , use 64 Bit won't crash , The contour obtained is also correct .

3. Using examples : Find the outline and draw it one by one

#include <opencv.hpp>
#include <algorithm>
#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;

struct AreaCmp{
	AreaCmp(const vector<float>& _areas):areas(&_areas){}
	bool operator()(int a,int b) const {return (*areas)[a] > (*areas)[b];}
	const vector<float>* areas;
};

int main(int argc, char *argv[])
{
	Mat img,img_edge,img_color;
	img = cv::imread(argv[1],cv::IMREAD_GRAYSCALE);
	if(img.empty())
	{
		std::cout << "Load image fail," << argv[1] << std::endl;
		getc(stdin);
		return -1;
	}
	cv::threshold(img,img_edge,128,255,cv::THRESH_BINARY);
	cv::namedWindow("Image after threshold",cv::WINDOW_NORMAL);
	cv::imshow("Image after threshold",img_edge);
	cv::vector< cv::vector<cv::Point> > contours;
	vector<cv::Vec4i> hierarchy;

    //  Find the outline 
	cv::findContours(img_edge,contours,hierarchy,cv::RETR_LIST,cv::CHAIN_APPROX_SIMPLE);
	cout << "\nTotal contours detected:" << contours.size() << endl;

	vector<int> sortIdx(contours.size());
	vector<float> areas(contours.size());
	for(int n=0;n<(int)contours.size();n++)
	{
		sortIdx[n] = n;
		areas[n] = contourArea(contours[n],false);  //  Calculate the contour area 
	}

	// sort contours so that largest contours go first
	std::sort(sortIdx.begin(),sortIdx.end(),AreaCmp(areas));

	for(int n=0;n<(int)sortIdx.size();n++)
	{
		int idx = sortIdx[n];
		cv::cvtColor(img,img_color,cv::COLOR_GRAY2BGR);
        //  Draw the outline 
		cv::drawContours(img_color,contours,idx,cv::Scalar(0,0,255),2,8,hierarchy,0);  //  Draw the outline one by one 
		cout << "Contour #" << idx << ": area=" << areas[idx] << ", nvertices=" << contours[idx].size() << endl;
		cv::namedWindow(argv[0],cv::WINDOW_NORMAL);
		cv::imshow(argv[0],img_color);
		int k;
		if((k = cv::waitKey()&255) == 27)
			break;
	}

	std::cout << "Finished all contours\n" ;
	getc(stdin);
	return 0;
}

原网站

版权声明
本文为[sinat_ forty-one million seven hundred and fifty-two thousand t]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/188/202207071351354552.html