判断识别方案设计

判断识别方案设计

  1. 功能介绍
  • 读入摄像头及预处理得到的装有Point类型的容器;
  • 通过计算转折点数目来判断形状,根据要求分为水平线/垂直线/三角形/矩形/圆(转折点数目依次为2,2,3,4,4+);
  • 通过转折点和容器中坐标拟合出最理想的形状,并描出其外框(线);
  • 返回string来输出其形状名称.
  1. 思路分析
  • 读入Point2i类型的容器;
  • 调用arcLength()求封闭图形的周长,为后续操作中的阈值设定最准备;
  • 调用approxPolyDP()函数,得到装有转折点坐标的容器;
  • 采用switch-case分支结构对进行下一步的判断(以本实验为例,采用(int)angle.size()作为条件);
  • 分支中具体函数如下:
    1. 直线判断:
      • 读入装有转折点的容器;
      • 采用tan的方式判断直线的水平和垂直状态;
      • 得到直线的状态后,根据不同的状态对直线进行归中处理;
      • 调用line()函数进行描边.
    2. 三角形判断:
      • 读入装有转折点的容器;
      • 调用polylines()函数,利用求得的转折点坐标信息进行描边.
    3. 矩形判断:
      • 读入装有转折点的容器;
      • 调用minAreaRect()函数进行矩形的拟合(可返回得到矩形中心和倾斜角度等信息,注:无转折点信息);
      • 调用box.points()获取角点位置;
      • 调用line()函数进行描边(该处采用polylines()函数效果不理想).
    4. 圆判断:
      • 读入装有转折点的容器;
      • 调用minEnclosingCircle()函数,获取拟合程度最好的圆的半径和圆心信息;
      • 调用circle()函数进行描边.
  1. 代码介绍

判断函数

void Detect_Shape(std::vector<cv::Point2i> pt)
{
	using namespace std;
	using namespace cv;

	string Shape_Name;
	int flag_line; 
	double epsilon = 0.06 * arcLength(pt , true);

	vector<Point2i> angle;
	approxPolyDP(pt,angle,epsilon,true);

	switch((int)angle.size())
	{
		case 2:{
			flag_line = D_Line(angle);
			if(flag_line == 1)
				Shape_Name = "vertical line";
			else
				Shape_Name = "horizonal line";
			break;
		}
		case 3:{
			D_Triangle(angle);
			Shape_Name = "triangle";
			break;
		}
		case 4:{
			D_Rectangle(angle);
			Shape_Name = "rectangle";
			break;
		}		
		default:{
			D_Round(angle);
			Shape_Name = "round";
			break;
		}
	}

	cout<<"It is a "<< Shape_Name <<endl;
	return;
}

直线

int D_Line(std::vector<cv::Point2i> angle)
{
	using namespace std;
	using namespace cv;

	int flag_line;
	
	int dy = abs(angle[0].y - angle[1].y);
	int dx = abs(angle[0].x - angle[1].x);
	double tan = dy/dx;
	
	if(tan > 1)
	{
		flag_line = 1;
		int x = (angle[0].x + angle[1].x)/2;
		line(Mask,Point(x,angle[0].y),Point(x,angle[1].y),Scalar(0,255,0),3);		
	}
	else
	{
		flag_line = 2;
		int y = (angle[0].y + angle[1].y)/2;
		line(Mask,Point(angle[0].x,y),Point(angle[1].x,y),Scalar(0,255,0),3);		
	}
	
	imshow("Line",Mask);
	
	return flag_line;
}

三角形

void D_Triangle(std::vector<cv::Point2i> angle)
{
	using namespace std;
	using namespace cv;
	
	polylines(Mask, angle, true, Scalar(0,255,0), 3, LINE_AA);

	imshow("Triangle",Mask);

	return;
}

矩形

void D_Rectangle(std::vector<cv::Point2i> angle)
{
	using namespace std;
	using namespace cv;

	Point2f vertices[4];
	RotatedRect box = minAreaRect(angle);
	box.points(vertices);
	
	for(int i = 0;i<4;i++)
	{
		line(Mask, vertices[i], vertices[(i+1)%4], Scalar(0,255,0), 3);
	}

	imshow("Rectangle",Mask);

	return;
}

void D_Round(std::vector<cv::Point2i> angle)
{
	using namespace std;
	using namespace cv;

	Point2f circle_centers;
	float circle_radius;

	minEnclosingCircle(angle, circle_centers, circle_radius);
	circle(Mask,circle_centers,circle_radius,Scalar(0,255,0),3,LINE_AA,0);

	imshow("Round",Mask);

	return;
}
  1. 待改进问题
  • 暂基本满足设想,后需要优化程序设计
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值