opencv(一)形状识别

##opencv 识别三角形、圆形及矩形
常用函数:
(1)approxPolyDP 多边形逼近
(2)boundingRect 最小外接矩形
(3) minEnclosingCircle 最小外接圆形
(4)arcLength 计算周长
(5)contourArea 计算面积
(6)FitEllipse 最小外接椭圆
(7)cvFindDominantPoints 寻找关键点
(8)轮廓匹配
有10个图案,包括三角形,方形和圆。你把这三种图案识别出来,每一种图形画上不同颜色的轮廓,并提取出每个轮廓的重心坐标。
opencv(一)形状识别_第1张图片

#include
#include
using namespace cv;
using namespace std;

int main()
{
	Mat srcImg, tempImg;
	srcImg = imread("90.bmp");
	if (!srcImg.data)
	{
		cout << "no Img" << endl;
		return -1;
	}
	Mat gray;
	resize(srcImg, tempImg, Size(srcImg.cols / 2, srcImg.rows / 2), 0, 0);
	cvtColor(tempImg, gray, CV_RGB2GRAY);
	medianBlur(gray, gray, 3);

	vectorcircles;//圆
	HoughCircles(gray, circles, CV_HOUGH_GRADIENT, 1, srcImg.rows / 20, 100, 60, 0, 0);

	Mat thresh;
	threshold(gray, thresh, 0, 255, THRESH_OTSU);
	
	vectorsanjiao;

	vectorapprox;
	vectorsquares;

	Mat srcImg1;
	srcImg1 = thresh.clone();
	vector>contours;
	findContours(srcImg1, contours, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
	Mat dstImg(srcImg1.rows, srcImg1.cols, CV_8UC3, Scalar(255, 255, 255));
	for (size_t i = 0; i < circles.size(); i++)//画圆
	{
		Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
		int radius = cvRound(circles[i][2]);
		circle(dstImg, center, radius, Scalar(0, 255, 0), 5, 8, 0);
		circle(dstImg, center, 3, Scalar(0, 255, 0), -1);
		cout << "圆心" << i + 1 << center << endl;
	}
	for (size_t i = 0; i < contours.size(); i++)
	{
		approxPolyDP(contours[i], approx, arcLength(Mat(contours[i]), true)*0.02, true);
		if (approx.size() == 4 && fabs(contourArea(Mat(approx))) > 1000 && isContourConvex(Mat(approx)))
		{
			double minDist = 1e10;

			for (int i = 0; i < 4; i++)
			{
				Point side = approx[i] - approx[(i + 1) % 4];
				double squaredSideLength = side.dot(side);
				minDist = min(minDist, squaredSideLength);
			}
			if (minDist<50)
				break;
			for (int i = 0; i<4; i++)
				squares.push_back(Point(approx[i].x, approx[i].y));
		}
		approxPolyDP(contours[i], approx, arcLength(Mat(contours[i]), true)*0.1, true);
		if (approx.size() == 3 && fabs(contourArea(Mat(approx))) > 1000 && isContourConvex(Mat(approx)))
		{
			double minDist = 1e10;

			for (int i = 0; i <3; i++)
			{
				Point side = approx[i] - approx[(i + 1) % 3];
				double squaredSideLength = side.dot(side);
				minDist = min(minDist, squaredSideLength);
			}
			if (minDist<50)
				break;
			for (int i = 0; i<3; i++)
				sanjiao.push_back(Point(approx[i].x, approx[i].y));
		}
		drawContours(dstImg, contours, i, Scalar(0,0,255), 3);
	}
	for (size_t i = 0; i < squares.size(); i += 4)
	{
		Point center;
		center.x = (squares[i].x + squares[i + 2].x) / 2;
		center.y = (squares[i].y + squares[i + 2].y) / 2;
		line(dstImg, squares[i], squares[i + 1], Scalar(0, 0, 255), 4);
		line(dstImg, squares[i + 1], squares[i + 2], Scalar(0, 0, 255), 4);
		line(dstImg, squares[i + 2], squares[i + 3], Scalar(0, 0, 255), 4);
		line(dstImg, squares[i + 3], squares[i], Scalar(0, 0, 255), 4);
		cout << "矩形中心" << (i + 1) % 4 << center << endl;
		circle(dstImg, center, 3, Scalar(0, 0, 255), -1);
	}
	for (size_t i = 0; i < sanjiao.size(); i += 3)
	{
		Point center;
		center.x = (sanjiao[i].x + sanjiao[i + 1].x + sanjiao[i + 2].x) / 3;
		center.y = (sanjiao[i].y + sanjiao[i + 1].y + sanjiao[i + 2].y) / 3;
		line(dstImg, sanjiao[i], sanjiao[i + 1], Scalar(255, 0, 0), 4);
		line(dstImg, sanjiao[i + 1], sanjiao[i + 2], Scalar(255, 0, 0), 4);
		line(dstImg, sanjiao[i], sanjiao[i + 2], Scalar(255, 0, 0), 4);
		cout << "三角形中心" << (i + 1) % 3 << center << endl;
		circle(dstImg, center, 3, Scalar(255, 0, 0), -1);
	}
	imshow("123", dstImg);
	waitKey(0);
	return 0;
}

你可能感兴趣的:(opencv)