Opencv uses matchshape operator to achieve simple shape matching

Opencv uses matchshape operator to achieve simple shape matching

Arithmetic:

matchShapes( InputArray contour1, InputArray contour2, int method, double parameter )

(1) Parameter 1 is the contour or gray image to be matched

(2) Parameter 2 is the same as parameter 1

(3) To compare the similarity of parameters 1 and 2, opencv provides three methods as follows:

                CV_CONTOURS_MATCH_I1
                CV_CONTOURS_MATCH_I2
                CV_CONTOURS_MATCH_I3

(4) Parameter 4 is not currently supported, and it is ok if it is assigned 0 when using it.

Comparing the three matching methods, the results are as follows:

Shape matching process:

1. Split the image to be recognized -> grayscale processing -> automatic threshold segmentation

2. Find all the contours of the image to be recognized through the contour retrieval function cv.findContours

3. Template image -> grayscale image -> automatic threshold segmentation

4. Find the outer contour of the target in the template image through the contour retrieval function cv.findContours

5. Use the cv.matchShapes function to match the contours obtained in step 2 with the contours obtained in step 4 one by one. Find the minimum value, and the contour in the image to be recognized corresponding to the minimum value is the matched template image

6. Mark the template image found in the image to be recognized

Note : The smaller the matching score obtained by mathshape, the more similar the two contours, and the larger the more dissimilar. During the matching process, the matching score will be compared with the set score. In the case of ensuring the perfect matching effect, the lower the set score, the better. If the set matching score is slightly higher, it may cause Two completely dissimilar shapes are successfully matched (in-person experiment, the score is set high, using a triangle will match a circle).

In addition, the matchShapes function actually compares the Hu invariant moments of two contours. Hu moment characteristics: rotation, scaling and translation invariance . The feature quantity composed of Hu moments recognizes the picture. The advantage is that the speed is very fast, but the disadvantage is that the recognition rate is relatively low. Therefore, Hu invariant moments are generally used to identify large objects in an image. The shape of the object is described well, and the texture characteristics of the image cannot be too complicated .

Example:

Use the matchshape method to find the circle in the figure below.

Code:

(1) Create a shape outline template

vector<Point> ImageTemplateContours(Mat img_template)
{
	//灰度化
	Mat gray_img_template;
	cvtColor(img_template, gray_img_template, COLOR_BGR2GRAY);

	//阈值分割
	Mat thresh_img_template;
	threshold(gray_img_template, thresh_img_template, 0, 255, THRESH_OTSU);
	//膨胀处理
	Mat ellipse = getStructuringElement(MORPH_ELLIPSE, Size(15, 15));
	Mat erode_img_template;
	//erode(thresh_img_template, erode_img_template, ellipse);
	morphologyEx(thresh_img_template, thresh_img_template, MORPH_OPEN, ellipse, Point(-1, -1), 1);

	//寻找边界
	vector<vector<Point>> contours_template;
	vector<Vec4i> hierarchy;
	findContours(thresh_img_template, contours_template, hierarchy, RETR_LIST, CHAIN_APPROX_NONE, Point());

	//绘制边界
	drawContours(img_template, contours_template, 0, Scalar(0, 0, 255), 1, 8, hierarchy);


	return contours_template[0];
}

Note: The reason for returning the 0th of all contours found by the findContours operator is because the 0th is the circular template I want

(2) Perform shape template matching

vector<Point2d> ShapeTemplateMatch(Mat image, vector<Point> imgTemplatecontours, double minMatchValue)
{
	vector<Point2d> image_coordinates;
	//灰度化
	Mat gray_img;
	cvtColor(image, gray_img, COLOR_BGR2GRAY);

	//阈值分割
	Mat thresh_img;
	threshold(gray_img, thresh_img, 0, 255, THRESH_OTSU);
	
	//寻找边界
	vector<vector<Point>> contours_img;
	vector<Vec4i> hierarchy;
	findContours(thresh_img, contours_img, hierarchy, RETR_LIST, CHAIN_APPROX_NONE, Point());
	//根据形状模板进行匹配
	int min_pos = -1;
	double	min_value = minMatchValue;//匹配分值,小于该值则匹配成功
	for (int i = 0; i < contours_img.size(); i++)
	{
	        //计算轮廓面积,筛选掉一些没必要的小轮廓
		if (contourArea(contours_img[i])>12000)
		{
	                //得到匹配分值 
			double value = matchShapes(contours_img[i], imgTemplatecontours, CONTOURS_MATCH_I3, 0.0);
	                //将匹配分值与设定分值进行比较 
			if (value < min_value)
			{
				min_pos = i;
				//绘制目标边界
				drawContours(image, contours_img, min_pos, Scalar(0, 0, 255), 1, 8, hierarchy, 0);

				//获取重心点
				Moments M;
				M = moments(contours_img[min_pos]);
				double cX = double(M.m10 / M.m00);
				double cY = double(M.m01 / M.m00);
				//显示目标中心并提取坐标点
				circle(image, Point2d(cX, cY), 1, Scalar(0, 255, 0), 2, 8);
				//putText(image, "center", Point2d(cX - 20, cY - 20), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0), 1, 8);
	                        //将目标的重心坐标都存在数组中 
				image_coordinates.push_back(Point2d(cX, cY));//向数组中存放点的坐标
			}
		}
	}
	return image_coordinates;
}

Reference article: opencv uses cv.matchShapes() function to realize image recognition technology

                   OpenCV learning (33) Moment of contour feature

                 [OpenCV study notes] image contour features and image moments

Guess you like

Origin blog.csdn.net/Kevin_Sun777/article/details/111395898