Using findcontour to find only the inner contour

The first time you try to write a blog, just write an essay!

Recently, I was working on a small project. I need to detect the target contour, and only the inner contour is needed. The contour detection function findContours provided by OpenCV is particularly convenient to use. The hierarchical relationship between contours can be used to find the inner contour.

Please refer to the relevant tutorials and manuals for the specific use of findContours function. The following only highlights and supplements the key points related to this algorithm. If there are errors, please criticize and correct them.

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

There are data structure parameters in the parameter list: hierarchy (translation hierarchy). Hierarchy is a vector with the same number of elements as the total number of found contours. Each element contains four int type data hierarchy[i][0]~hierarchy[i][3].
Respectively means:
(1) Represents the number of the next contour of the same level contour. If there is no next contour of this level contour, it is - 1.
(2) Represents the number of the previous contour of the same level contour. If there is no previous contour of this level contour, it is - 1.
(3) Indicates the number of the first of the next level contour contained in the contour. If not, it is - 1.
(4) Represents the number of the previous level of the profile. If there is no previous level, it is - 1.

For details, please refer to the blog: Detailed explanation of findContour function

Parameter: int mode: defines the retrieval mode of contours. Different modes lead to different topologies between contours. Refer to other blogs for specific parameter definitions.

This article uses mode: CV when detecting only the inner contour_ RETR_ Ccomp detects all contours, but all contours only establish two hierarchical relationships, namely, outer contour and inner contour. If there are other contours in the inner contour, all contours in the inner contour belong to the outer contour, and so on.

The test images used in the program are as follows:
(find_color() function in the code segment corresponding to binary image obtained by red threshold segmentation in hsv color space)

The code is as follows, which is very simple:

int main()
{
	Mat dstImage, SrcImage, drawImage;
	string path = "F:\\Image_design\\circle4.png";
	SrcImage = imread(path);							//source image

	if (!SrcImage.data) {
		std::cout << "Could not open or find the image" << std::endl;
		return -1;
	}

	find_color(SrcImage, dstImage);					  //Extracting the red part from hsv color space
	Mat markers = dstImage.clone();
	drawImage = cv::Mat::zeros(SrcImage.size(), SrcImage.type());

	std::vector< std::vector<cv::Point> > contours;
	std::vector<cv::Vec4i> hierarchy;

	contours.clear();
	cv::findContours(markers, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE);  //Only two levels are selected for hierarchical relationship
	for (int i = 0; i < contours.size(); i++)
	{
		if (hierarchy[i][3] != -1 && contourArea(contours[i]) > 50)
		{
			drawContours(SrcImage, contours, i, Scalar(0, 255, 0), 2);
			drawContours(drawImage, contours, i, Scalar(0, 255, 0), 1);

			cout << "vector hierarchy The first" << to_string(i) << " The contents of the elements are:" << endl << hierarchy[i] << endl << endl;
		}
	}

	imshow("contours", SrcImage);
	waitKey(0);
	return 0;
}

The code execution effect is as follows:
(green is the detected inner contour)

Conclusion: in fact, as long as you understand mode: CV_ RETR_ The practical significance of ccomp and hierarchy, the key point of the algorithm is one sentence:
If (hierarchy [i] [3]! = - 1) saves the contour;
(when CV_RETR_CCOMP is selected, the hierarchical data of the above test chart)
Because there are two levels of hierarchical relationship, when the last data in the vector hierarchy element is not - 1, it indicates that there is an outer contour of the contour, then the contour is an inner contour.

(learn OpenCV, write a blog for the first time, if there are errors, please understand!)

Keywords: OpenCV

Added by MorganM on Fri, 24 Dec 2021 05:18:18 +0200