opencv 学习之 轮廓操作笔记(一)

1、轮廓之外的区域像素置0

根据最小外接矩形,仿射变换至无偏转矩形。外接矩形结构体导出顶点是按顺时针结构排列的,但是起点不定。

int SetExcludeRectZero(Mat & gray, RotatedRect rect)
{
	Point2f vertex1[4], vertex2[4];      //定义外接矩形的4个顶点  
	//定点的排序为逆时针
	rect.points(vertex1);
	rect.points(vertex2);
	int width = rect.size.width;
	int height = rect.size.height;
	Point2f certer = rect.center;
	//修正vertex2,使其无倾斜
	for (int k = 0; k < 4; k++)
	{
		int index1 = k;
		int index2 = (k + 1) % 4;
		if (vertex2[index1].x < rect.center.x && vertex2[index2].x < rect.center.x)
		{		
			//坐标逆时针排序
			vertex2[index1].x = certer.x - width / 2;
			vertex2[index1].y = certer.y + height / 2;
			vertex2[index2].x = certer.x - width / 2;
			vertex2[index2].y = certer.y - height / 2;
			index1 = (k + 2) % 4;
			index2 = (k + 3) % 4;
			vertex2[index1].x = certer.x + width / 2;
			vertex2[index1].y = certer.y - height / 2;
			vertex2[index2].x = certer.x + width / 2;
			vertex2[index2].y = certer.y + height / 2;
			break;
		}
	}
	/// 求得仿射变换
	Mat warp_dst = gray.clone();
	Mat warp_mat = getAffineTransform(vertex1, vertex2);
	/// 对源图像应用上面求得的仿射变换
	warpAffine(gray, warp_dst, warp_mat, warp_dst.size());
	Rect lcdrect(certer.x - width / 2, certer.y - height / 2 - 10, width, height + 30);
	Mat lcd = warp_dst(lcdrect).clone();
	warp_dst = 0;
	lcd.copyTo(warp_dst(lcdrect));
	warp_mat = getAffineTransform(vertex2, vertex1);
	warpAffine(warp_dst, gray, warp_mat, warp_dst.size());
	return 0;
}

2、轮廓匹配

无法跟普通模板匹配一样定位最佳点,轮廓列表逐个匹配找到最匹配的轮廓索引

//CURZR 轮廓匹配找到最佳值
int FindSimilarContours(Mat & img, vector<Point> srccontours, vector<vector<Point>> contourslist, vector<Point>& dstcontours)
{
	int index = -1;
	double ratio = 100;
	Point2f vertex1[4], vertex2[4];
	RotatedRect rect1 = minAreaRect(srccontours);
	double area1 = rect1.size.width * rect1.size.height;
	int width1 = rect1.size.width > rect1.size.height ? rect1.size.width : rect1.size.height;
	int height1 = rect1.size.width <= rect1.size.height ? rect1.size.width : rect1.size.height;
	rect1.points(vertex1);
	int lengthsrc1 = sqrt(pow(vertex1[0].x-vertex1[2].x, 2)+pow(vertex1[0].y-vertex1[2].y, 2));
	int lengthsrc2 = sqrt(pow(vertex1[1].x-vertex1[3].x, 2)+pow(vertex1[1].y-vertex1[3].y, 2));
	for (int k = 0; k<contourslist.size(); k++)
	{
		Rect rect = boundingRect(contourslist[k]);
		//rectangle(img, rect, Scalar(255,255,255),3);
		RotatedRect rect2 = minAreaRect(contourslist[k]);		
		double area2 = rect2.size.width * rect2.size.height;
		int width2 = rect2.size.width>rect2.size.height ? rect2.size.width : rect2.size.height;
		int height2 = rect2.size.width<rect2.size.height ? rect2.size.width : rect2.size.height;
		rect2.points(vertex2);
		for (int i = 0; i < 4; i++)
		{
			//putText(img, format("%d", i), Point(vertex2[i].x, vertex2[i].y), FONT_HERSHEY_COMPLEX, 2, Scalar(0, 0, 0));
			//line(img, vertex2[i], vertex2[(i + 1) % 4], Scalar(0, 255, 0));
		}			
		int lengthdst1 = sqrt(pow(vertex2[0].x - vertex2[2].x, 2) + pow(vertex2[0].y - vertex2[2].y, 2));
		int lengthdst2 = sqrt(pow(vertex2[1].x - vertex2[3].x, 2) + pow(vertex2[1].y - vertex2[3].y, 2));
		if (lengthsrc1<lengthdst1*1.5 && lengthsrc1>lengthdst1*0.5 && lengthsrc2<lengthdst2*1.5 && lengthsrc2>lengthdst2*0.5)
		{
			//drawContours(img, contourslist, k, Scalar(255, 0, 255));
			double ret = matchShapes(srccontours, contourslist[k], CV_CONTOURS_MATCH_I1, 0);
			if (ret<ratio)
			{
				ratio = ret;
				index = k;
			}
		}
	}
	if (index<0)
	{
		return index;
	}
	dstcontours = contourslist[index];	
	//imshow("img", img);
	//waitKey();
	return 0;
}


猜你喜欢

转载自blog.csdn.net/u010477528/article/details/79779439
今日推荐