计算机系统应用教程网站

网站首页 > 技术文章 正文

基于opencv图像识别的AI五子棋系列3—查找棋盘四个顶点

btikc 2024-09-30 13:13:28 技术文章 11 ℃ 0 评论

基于opencv图像识别的AI五子棋系列3—查找棋盘四个顶点

该篇文章是基于opencv图像识别的AI五子棋系列的第三篇文章。通过该系列文章,你可以进阶opencv图像识别,熟悉图像识别与处理的大致流程,熟悉AI智能......


上一篇文章对五子棋棋盘进行了棋盘轮廓的查找,该篇文章,则在上一篇文章的基础上进行棋盘四个顶点的查找,查找到四个顶点后方便我们进行后续处理。

首先看一下处理的效果图

程序具体实现过程

在上篇文章基础上,我们查找到了棋盘的轮廓,如下图:

这里的轮廓是保存在

vector<vector<Point>> RectContours_fainal ;

里的。我们要在一个不规则的四边形中找到四个顶点还是需要一些技巧的。

这里我写了一个FindConnor() 函数来实现寻找到四个角点。函数实现如下:

/***** 2、输入单个轮廓,返回逆时针排序的4个角点*****/
vector<Index_Point> FindConnor(vector<Point> RectContours)
{
	///**(1).根据距离条件找出三个角点
	float distance = 0, distanceMax = 0;
	vector<Index_Point> connorPoint(4), connor_order(4);
	int i = 0;
	distance = 0;
	distanceMax = 0;
	for (i = 0; i < RectContours.size(); i++)
	{//找第一个角点
		distance = getDistance(RectContours[i], RectContours[0]);
		if (distance>distanceMax)
		{
			distanceMax = distance;
			connorPoint[0].point = RectContours[i];
			connorPoint[0].index = i;
		}
	}
	distance = 0;
	distanceMax = 0;
	for (i = 0; i < RectContours.size(); i++)
	{//找第二个角点
		distance = getDistance(RectContours[i], connorPoint[0].point);
		if (distance>distanceMax)
		{
			distanceMax = distance;
			connorPoint[1].point = RectContours[i];
			connorPoint[1].index = i;
		}
	}
	distance = 0;
	distanceMax = 0;
	for (i = 0; i < RectContours.size(); i++)
	{//找第三个角点
		distance = getDistance(RectContours[i], connorPoint[0].point) + getDistance(RectContours[i], connorPoint[1].point);
		if (distance>distanceMax)
		{
			distanceMax = distance;
			connorPoint[2].point = RectContours[i];
			connorPoint[2].index = i;
		}
	}

	///**(2).对已经找到的角点排列
	connor_order = ListConnor_0(connorPoint);//
	connorPoint = connor_order;

	///**(3).找出3个怀疑是第四角点的点
	vector<Index_Point> connor4_Doubt(3);
	distance = 0;
	distanceMax = 0;
	for (i = connorPoint[1].index; i < connorPoint[0].index; i++)
	{//1,0号角点之间找到怀疑是4角点的点
		distance = getDistance(RectContours[i], connorPoint[0].point) + getDistance(RectContours[i], connorPoint[1].point);
		if (distance>distanceMax)
		{
			distanceMax = distance;
			connor4_Doubt[0].point = RectContours[i];
			connor4_Doubt[0].index = i;
		}
	}
	distance = 0;
	distanceMax = 0;
	for (i = connorPoint[2].index; i < connorPoint[1].index; i++)
	{//2,1号角点之间找到怀疑是4角点的点
		distance = getDistance(RectContours[i], connorPoint[2].point) + getDistance(RectContours[i], connorPoint[1].point);
		if (distance>distanceMax)
		{
			distanceMax = distance;
			connor4_Doubt[1].point = RectContours[i];
			connor4_Doubt[1].index = i;
		}
	}
	distance = 0;
	distanceMax = 0;
	for (i = connorPoint[0].index; i < RectContours.size() + connorPoint[2].index; i++)
	{//0,2号角点之间找到怀疑是4角点的点
		if (i< RectContours.size())
		{
			distance = getDistance(RectContours[i], connorPoint[0].point) + getDistance(RectContours[i], connorPoint[2].point);
			if (distance>distanceMax)
			{
				distanceMax = distance;
				connor4_Doubt[2].point = RectContours[i];
				connor4_Doubt[2].index = i;
			}
		}
		else
		{
			distance = getDistance(RectContours[i - RectContours.size()], connorPoint[0].point) + getDistance(RectContours[i - RectContours.size()], connorPoint[2].point);
			if (distance>distanceMax)
			{
				distanceMax = distance;
				connor4_Doubt[2].point = RectContours[i - RectContours.size()];
				connor4_Doubt[2].index = i;
			}
		}
	}

	///**(4).通过点到直线的距离找到第四个角点
	if (getDist_P2L(connor4_Doubt[0].point, connorPoint[0].point, connorPoint[1].point)>10)
	{
		connorPoint[3] = connor4_Doubt[0];
	}
	else if (getDist_P2L(connor4_Doubt[1].point, connorPoint[1].point, connorPoint[2].point)>10)
	{
		connorPoint[3] = connor4_Doubt[1];
	}
	else if (getDist_P2L(connor4_Doubt[2].point, connorPoint[0].point, connorPoint[2].point)>10)
	{
		connorPoint[3] = connor4_Doubt[2];
	}

	///**(5).对四个角点按顺时针排序
	connor_order = ListConnor(connorPoint);
	return connor_order;
}

具体思路如下:

首先我们观察四边形,哪些点会是角点呢?显然是对角线这一特征,根据这一个特性,我们遍历所有的点,并一 一求出两点之间距离,在两个点距离最远的时候,肯定是四个角点中的两个。

找第一个顶点——第一个顶点怎么求,首先随意找轮廓中一个点,然后求任意两点距离,距离最大的那个肯定是个顶点,然后同理,以第一个点为基准,找第二个顶点。第三个顶点就是,距离第一个顶点和第二个顶点距离最远的那个点,然后对前三个点进行排序,最后再找第四个顶点,第四个顶点肯定在三个已知任意两个顶点的中间,求出来,然后再根据距离,就可以找到了。

然后我们利用ListConnor函数对找到的四个顶点进行排序,使它顺时针排序。方便后续我们透视变换用——透视变换需要指定顺序才能进行透视变换。

下面语句是将得到的四个角点画出来。

	if (ConnorPoint_Output[0].size()>0)
	{

		vector<vector<Point>> RectContours;
		vector<Point> pts;
		for (int i = 0; i < ConnorPoint_Output[0].size(); i++)
		{
			Point one_ConnorGroup[4];
			for (int j = 0; j < 4; j++)
			{//为单独一组角点赋值
				one_ConnorGroup[j] = ConnorPoint_Output[j][i];
				circle(srcImage0, one_ConnorGroup[j], 10, Scalar(0, 255, 0), -1); //第五个参数我设为-1,表明这是个实点。
			}

			namedWindow("四个角点", 0);
			imshow("四个角点", srcImage0);
			waitKey(2);
		}

	}
	else
	{
		//没找到,返回下帧继续找
		printf("[ALG ERROR][函数:%s][行号:%d],当前帧未找到方形仪表四边形四个角点,返回,下帧继续找 \n", __FUNCTION__, __LINE__);
		return ERROR;
	}

完整源码如下:


/*****************************************************************************************
五子棋棋盘棋子识别检测
1、灰度化,二值化
2、查找棋盘最外边轮廓
3、找到棋盘四个顶点
*****************************************************************************************/
#include<opencv2/opencv.hpp>
#include <iostream> 
#include <fstream>  
#include <stdlib.h> //srand()和rand()函数 
#include <time.h> //time()函数 
#include <opencv2/core/core.hpp> 
#include <opencv2/highgui/highgui.hpp> 
#include <opencv2/imgproc/imgproc.hpp>  
#include <opencv2/objdetect/objdetect.hpp> 
#include <opencv2/ml/ml.hpp>  
#include<opencv2\opencv.hpp>
#include <opencv2\imgproc\types_c.h>
#include<windows.h>


using namespace std;
using namespace cv;
using namespace ml;

struct Index_Point
{//带引索的点
	Point point;
	int index;
};

/*******************************************************************************************
*函数功能 : 找每个轮廓的中心坐标
*输入参数 :轮廓或者凸包
*返 回 值 : 点向量
*编写时间 : 2018.8.9
*作    者 : diyun
********************************************************************************************/
vector< Point2f> find_lunkuo_zhongxin(vector<vector<Point>> dangban_RectContours)
{

	vector<Point2f> zhongxin_zuobiao;
	/// 计算矩
	vector<Moments> mu(dangban_RectContours.size());
	for (int i = 0; i < dangban_RectContours.size(); i++)
	{
		mu[i] = moments(dangban_RectContours[i], false);
	}
	///  计算中心矩:
	vector<Point2f> mc(dangban_RectContours.size());
	for (int i = 0; i < dangban_RectContours.size(); i++)
	{
		mc[i] = Point2f(mu[i].m10 / mu[i].m00, mu[i].m01 / mu[i].m00);
		zhongxin_zuobiao.push_back(mc[i]);
	}

	return	zhongxin_zuobiao;

}
/***** 求两点间距离*****/
float getDistance(Point pointO, Point pointA)
{
	float distance;
	distance = powf((pointO.x - pointA.x), 2) + powf((pointO.y - pointA.y), 2);
	distance = sqrtf(distance);
	return distance;
}

//两点之间距离
float getDistance_1(Point pointO, Point pointA)
{
	float distance;
	distance = powf((pointO.x - pointA.x), 2) + powf((pointO.y - pointA.y), 2);
	distance = sqrtf(distance);
	return distance;
}
/***** 点到直线的距离:P到AB的距离*****/
float getDist_P2L(Point pointP, Point pointA, Point pointB)
{
	//求直线方程
	int A = 0, B = 0, C = 0;
	A = pointA.y - pointB.y;
	B = pointB.x - pointA.x;
	C = pointA.x*pointB.y - pointA.y*pointB.x;
	//代入点到直线距离公式
	float distance = 0;
	distance = ((float)abs(A*pointP.x + B*pointP.y + C)) / ((float)sqrtf(A*A + B*B));
	return distance;
}


//辅助函数:
/***** 输入角点组的前3个值,返回按Index由大到小排好的角点组*****/
vector<Index_Point> ListConnor_0(vector<Index_Point> Point_list)
{
	int i, j;
	vector<Index_Point> Point_Ordered(Point_list.size());
	for (j = 0; j < Point_Ordered.size() - 1; j++)
	{
		if (j == 0)
		{
			for (i = 0; i < Point_list.size(); i++)
			{
				if (Point_list[i].index>Point_Ordered[j].index)
				{
					Point_Ordered[j].index = Point_list[i].index;
					Point_Ordered[j].point = Point_list[i].point;
				}
			}
		}
		else
		{
			for (i = 0; i < Point_list.size(); i++)
			{
				if (Point_list[i].index<Point_Ordered[j - 1].index&&Point_list[i].index>Point_Ordered[j].index)
				{
					Point_Ordered[j].index = Point_list[i].index;
					Point_Ordered[j].point = Point_list[i].point;
				}
			}
		}
		if (Point_list[j].index == 0)
		{
			Point_Ordered[2].index = Point_list[j].index;
			Point_Ordered[2].point = Point_list[j].point;

		}
	}

	return Point_Ordered;
}
//辅助函数:
/***** 输入角点组,返回按Index由大到小排好的角点组*****/
vector<Index_Point> ListConnor(vector<Index_Point> Point_list)
{
	int i, j;
	vector<Index_Point> Point_Ordered(Point_list.size());
	for (j = 0; j < Point_Ordered.size(); j++)
	{
		if (j == 0)
		{
			for (i = 0; i < Point_list.size(); i++)
			{
				if (Point_list[i].index>Point_Ordered[j].index)
				{
					Point_Ordered[j].index = Point_list[i].index;
					Point_Ordered[j].point = Point_list[i].point;
				}
			}
		}
		else
		{
			for (i = 0; i < Point_list.size(); i++)
			{
				if (Point_list[i].index<Point_Ordered[j - 1].index&&Point_list[i].index>Point_Ordered[j].index)
				{
					Point_Ordered[j].index = Point_list[i].index;
					Point_Ordered[j].point = Point_list[i].point;
				}
			}
		}
		if (Point_list[j].index == 0)
		{
			Point_Ordered[3].index = Point_list[j].index;
			Point_Ordered[3].point = Point_list[j].point;

		}
	}
	return Point_Ordered;
}
/***** 2、输入单个轮廓,返回逆时针排序的4个角点*****/
vector<Index_Point> FindConnor(vector<Point> RectContours)
{
	///**(1).根据距离条件找出三个角点
	float distance = 0, distanceMax = 0;
	vector<Index_Point> connorPoint(4), connor_order(4);
	int i = 0;
	distance = 0;
	distanceMax = 0;
	for (i = 0; i < RectContours.size(); i++)
	{//找第一个角点
		distance = getDistance(RectContours[i], RectContours[0]);
		if (distance>distanceMax)
		{
			distanceMax = distance;
			connorPoint[0].point = RectContours[i];
			connorPoint[0].index = i;
		}
	}
	distance = 0;
	distanceMax = 0;
	for (i = 0; i < RectContours.size(); i++)
	{//找第二个角点
		distance = getDistance(RectContours[i], connorPoint[0].point);
		if (distance>distanceMax)
		{
			distanceMax = distance;
			connorPoint[1].point = RectContours[i];
			connorPoint[1].index = i;
		}
	}
	distance = 0;
	distanceMax = 0;
	for (i = 0; i < RectContours.size(); i++)
	{//找第三个角点
		distance = getDistance(RectContours[i], connorPoint[0].point) + getDistance(RectContours[i], connorPoint[1].point);
		if (distance>distanceMax)
		{
			distanceMax = distance;
			connorPoint[2].point = RectContours[i];
			connorPoint[2].index = i;
		}
	}

	///**(2).对已经找到的角点排列
	connor_order = ListConnor_0(connorPoint);//
	connorPoint = connor_order;

	///**(3).找出3个怀疑是第四角点的点
	vector<Index_Point> connor4_Doubt(3);
	distance = 0;
	distanceMax = 0;
	for (i = connorPoint[1].index; i < connorPoint[0].index; i++)
	{//1,0号角点之间找到怀疑是4角点的点
		distance = getDistance(RectContours[i], connorPoint[0].point) + getDistance(RectContours[i], connorPoint[1].point);
		if (distance>distanceMax)
		{
			distanceMax = distance;
			connor4_Doubt[0].point = RectContours[i];
			connor4_Doubt[0].index = i;
		}
	}
	distance = 0;
	distanceMax = 0;
	for (i = connorPoint[2].index; i < connorPoint[1].index; i++)
	{//2,1号角点之间找到怀疑是4角点的点
		distance = getDistance(RectContours[i], connorPoint[2].point) + getDistance(RectContours[i], connorPoint[1].point);
		if (distance>distanceMax)
		{
			distanceMax = distance;
			connor4_Doubt[1].point = RectContours[i];
			connor4_Doubt[1].index = i;
		}
	}
	distance = 0;
	distanceMax = 0;
	for (i = connorPoint[0].index; i < RectContours.size() + connorPoint[2].index; i++)
	{//0,2号角点之间找到怀疑是4角点的点
		if (i< RectContours.size())
		{
			distance = getDistance(RectContours[i], connorPoint[0].point) + getDistance(RectContours[i], connorPoint[2].point);
			if (distance>distanceMax)
			{
				distanceMax = distance;
				connor4_Doubt[2].point = RectContours[i];
				connor4_Doubt[2].index = i;
			}
		}
		else
		{
			distance = getDistance(RectContours[i - RectContours.size()], connorPoint[0].point) + getDistance(RectContours[i - RectContours.size()], connorPoint[2].point);
			if (distance>distanceMax)
			{
				distanceMax = distance;
				connor4_Doubt[2].point = RectContours[i - RectContours.size()];
				connor4_Doubt[2].index = i;
			}
		}
	}

	///**(4).通过点到直线的距离找到第四个角点
	if (getDist_P2L(connor4_Doubt[0].point, connorPoint[0].point, connorPoint[1].point)>10)
	{
		connorPoint[3] = connor4_Doubt[0];
	}
	else if (getDist_P2L(connor4_Doubt[1].point, connorPoint[1].point, connorPoint[2].point)>10)
	{
		connorPoint[3] = connor4_Doubt[1];
	}
	else if (getDist_P2L(connor4_Doubt[2].point, connorPoint[0].point, connorPoint[2].point)>10)
	{
		connorPoint[3] = connor4_Doubt[2];
	}

	///**(5).对四个角点按顺时针排序
	connor_order = ListConnor(connorPoint);
	return connor_order;
}

/***** 3、输入逆时针排序的4个角点,把0号点赋给右下角那个,最后逆时针输出*****/
vector<Point> FindFirstPoint(vector<Index_Point> Point_list)
{
	int i, Ymax, Y;
	float Kl, Kr;
	vector<Index_Point> Connor_Point_Ready;
	for (i = 0; i < Point_list.size(); i++)
	{
		Point_list[i].index = i;
	}
	for (i = 0; i < Point_list.size(); i++)
	{//找到所有上一级斜比下一级小的角点
		if (i>0 && i<Point_list.size() - 1)
		{
			Kl = abs(((float)(Point_list[i].point.y - Point_list[i - 1].point.y)) / ((float)(Point_list[i].point.x - Point_list[i - 1].point.x)));
			Kr = abs(((float)(Point_list[i].point.y - Point_list[i + 1].point.y)) / ((float)(Point_list[i].point.x - Point_list[i + 1].point.x)));
			if (Kl<Kr)
			{
				Connor_Point_Ready.push_back(Point_list[i]);
			}
		}
		else if (i == 0)
		{
			Kl = abs(((float)(Point_list[i].point.y - Point_list[Point_list.size() - 1].point.y)) / ((float)(Point_list[i].point.x - Point_list[Point_list.size() - 1].point.x)));
			Kr = abs(((float)(Point_list[i].point.y - Point_list[i + 1].point.y)) / ((float)(Point_list[i].point.x - Point_list[i + 1].point.x)));
			if (Kl<Kr)
			{
				Connor_Point_Ready.push_back(Point_list[i]);
			}
		}
		else if (i == Point_list.size() - 1)
		{
			Kl = abs(((float)(Point_list[i].point.y - Point_list[i - 1].point.y)) / ((float)(Point_list[i].point.x - Point_list[i - 1].point.x)));
			Kr = abs(((float)(Point_list[i].point.y - Point_list[0].point.y)) / ((float)(Point_list[i].point.x - Point_list[0].point.x)));
			if (Kl<Kr)
			{
				Connor_Point_Ready.push_back(Point_list[i]);
			}
		}

	}
	Y = 0; Ymax = 0;
	Index_Point Point_First;
	Point_First.point = Point(0, 0);
	Point_First.index = 0;

	for (i = 0; i < Connor_Point_Ready.size(); i++)
	{//以y最大的那个点作为first点
		if (Connor_Point_Ready[i].point.y >= Ymax)
		{
			Point_First.point = Connor_Point_Ready[i].point;
			Point_First.index = Connor_Point_Ready[i].index;
			Ymax = Connor_Point_Ready[i].point.y;
		}
	}
	vector<Point> PointOrder(Point_list.size());
	if (Point_list.size()>0)
	{
		for (i = 0; i < Point_list.size(); i++)
		{
			if (Point_First.index + i< Point_list.size())
			{
				PointOrder[i] = Point_list[Point_First.index + i].point;
			}
			else
			{
				PointOrder[i] = Point_list[Point_First.index + i - Point_list.size()].point;
			}

		}
	}

	return PointOrder;
}

int main()
{
	float ret = 0;

	Mat srcImage0 = imread("1.jpg");//读取图片 
									//Mat srcImage0 = imread("app/1.jpg");//读取图片 
	if (srcImage0.empty())
	{
		cout << " 待预测图像不存在: " << endl;
		printf("[ALG ERROR][函数:%s][行号:%d],图片未正常读取,请检查输入路径十分正确 \n", __FUNCTION__, __LINE__, 1);
		cout << " 待预测图像不存在: " << endl;
	}
	Mat srcImage, srcImage1;
	resize(srcImage0, srcImage0, Size(1920, 1080));
	cvtColor(srcImage0, srcImage1, CV_BGR2GRAY);

	namedWindow("灰度化", 0);
	imshow("灰度化", srcImage1);
	waitKey(2);
	srcImage = srcImage1 > 150; // 二值化
	namedWindow("二值化", 0);
	imshow("二值化", srcImage);
	waitKey(2);

	/*****1、输入二值化图像返回有用的轮廓*****/
	/*一般通过长度滤除剩下两个,选择内部那个*/

	vector<vector<Point>> contours, RectContours, RectContours_fainal;
	int height = srcImage.rows;
	findContours(srcImage, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);//找轮廓 CV_RETR_EXTERNAL,表示最外层轮廓
	vector<vector<Point>> hull(contours.size());//用于存放凸包
	vector<float> length(contours.size());
	vector<float> Area_contours(contours.size()), Area_hull(contours.size()), Rectangularity(contours.size()), circularity(contours.size());
	Mat drawing(srcImage.size(), CV_8UC3, cv::Scalar(255, 255, 255));
	for (int i = 0; i < contours.size(); i++)
	{//历遍所有的轮廓

		length[i] = arcLength(contours[i], true);

		if (length[i] >2000 && length[i] <12000)
		{//通过长度匹配滤除小轮廓
			convexHull(Mat(contours[i]), hull[i], false);//把凸包找出来
			Area_contours[i] = contourArea(contours[i]);
			Area_hull[i] = contourArea(hull[i]);
			Rectangularity[i] = Area_contours[i] / Area_hull[i];
			printf("过滤后轮廓长度为 length=%5f\n", length[i]);
			circularity[i] = (4 * 3.1415*Area_contours[i]) / (length[i] * length[i]);
			//drawContours(drawing, contours, i, (255, 0, 0), 2);//得到方框
			//if (Rectangularity[i]>0.9&&circularity[i]<0.8&&Area_hull[i]>8000 && Area_hull[i]<50000)
			{//通过凸包面积滤除不对的凸包,找到最终的四边形
				RectContours.push_back(hull[i]);//把提取出来的方框导入到新的轮廓组
				drawContours(drawing, hull, i, Scalar(0, 0, 0), 1);//得到方框
			}
		}
	}
	if (0 == RectContours.size())
	{
		printf("[ALG ERROR][函数:%s][行号:%d],RectContours.size=0,当前帧未找到轮廓,检查仪表二值化是否正常\n", __FUNCTION__, __LINE__);
	}
	/*识别结果显示,调试用*/
	//namedWindow("找轮廓结果", 0);
	//imshow("找轮廓结果", drawing);
	//waitKey(2);

	/*将多个轮廓,弄成一个*/
	cvtColor(drawing, drawing, CV_BGR2GRAY);
	drawing = drawing<150; // 二值化
						   //imshow("二值化", drawing);
						   //将线连接起来
	vector<Point2f> zhongxin_zuobiao;
	zhongxin_zuobiao = find_lunkuo_zhongxin(RectContours);
	if (zhongxin_zuobiao.size() >= 2)
	{
		for (int i = 0; i < zhongxin_zuobiao.size() - 1; i++)
		{
			for (int j = i + 1; j < zhongxin_zuobiao.size(); j++)
			{
				float dis_juxin = getDistance_1(zhongxin_zuobiao[i], zhongxin_zuobiao[j]);
				//if (dis_juxin <65)
				{
					line(drawing, zhongxin_zuobiao[i], zhongxin_zuobiao[j], Scalar(0), 40, LINE_AA);
				}

			}
		}

	}
	vector<vector<Point>> contours1;
	findContours(drawing, contours1, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);//找轮廓 CV_RETR_EXTERNAL,表示最外层轮廓
	Mat drawing1(drawing.size(), CV_8UC3, cv::Scalar(255, 255, 255));
	vector<vector<Point>> hull1(contours1.size());//用于存放凸包
	for (int i = 0; i < contours1.size(); i++)
	{//历遍所有的轮廓
	 //drawContours(drawing1, contours1, i, Scalar(0, 255, 0), 1);//得到方框
		convexHull(Mat(contours1[i]), hull1[i], false);//把凸包找出来
		RectContours_fainal.push_back(hull1[i]);//把提取出来的方框导入到新的轮廓组
		drawContours(drawing1, hull1, i, Scalar(0, 0, 0), 4);//得到方框
	}

	namedWindow("最终轮廓", 0);
	imshow("最终轮廓", drawing1);



	vector<Index_Point> ConnorPoint(4);
	vector<Point> ConnorPoint_ordered(4);
	vector<vector<Point>> ConnorPoint_Output(4);
	int i;

	for (i = 0; i < RectContours_fainal.size(); i++)
	{
		ConnorPoint = FindConnor(RectContours_fainal[i]);
		ConnorPoint_ordered = FindFirstPoint(ConnorPoint);
		ConnorPoint_Output[0].push_back(ConnorPoint_ordered[2]);
		ConnorPoint_Output[1].push_back(ConnorPoint_ordered[1]);
		ConnorPoint_Output[2].push_back(ConnorPoint_ordered[0]);
		ConnorPoint_Output[3].push_back(ConnorPoint_ordered[3]);
	}
	//ConnorPoint_Output[0][i]代表第i个轮廓的0号角点,顺时针输出
	//return ConnorPoint_Output;


	if (ConnorPoint_Output[0].size()>0)
	{

		vector<vector<Point>> RectContours;
		vector<Point> pts;
		for (int i = 0; i < ConnorPoint_Output[0].size(); i++)
		{
			Point one_ConnorGroup[4];
			for (int j = 0; j < 4; j++)
			{//为单独一组角点赋值
				one_ConnorGroup[j] = ConnorPoint_Output[j][i];
				circle(srcImage0, one_ConnorGroup[j], 10, Scalar(0, 255, 0), -1); //第五个参数我设为-1,表明这是个实点。
			}

			namedWindow("四个角点", 0);
			imshow("四个角点", srcImage0);
			waitKey(2);
		}

	}
	else
	{
		//没找到,返回下帧继续找
		printf("[ALG ERROR][函数:%s][行号:%d],当前帧未找到方形仪表四边形四个角点,返回,下帧继续找 \n", __FUNCTION__, __LINE__);
		return ERROR;
	}
	waitKey(0);
	return 0;
}

下一篇文章,我们根据寻找到的四个角点,进行透视变换,将侧视图投影成俯视图。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表