使用minAreaRect函数获取轮廓尺寸和形心坐标并打印

函数解释:
minAreaRect(InputArray points)

points:输入信息,可以为包含点的容器(vector)或是Mat。 返回包覆输入信息的最小斜矩形,是一个Box2D结构rect:(最小外接矩形的中心(x,y),(宽度,高度),旋转角度),绘制这个矩形有两种方法:
1.获取矩形的4个顶点坐标box, 通过函数 cv2.cv.BoxPoints() 获得,返回形式[ [x0,y0], [x1,y1], [x2,y2], [x3,y3] ]。得到的最小外接矩形的4个顶点顺序、中心坐标、宽度、高度、旋转角度(是度数形式,不是弧度数)参考:绘制矩形法1描述:
2.
1)minRects = minAreaRect(contours);
2)minRects .points(rect_point); //将最小矩形四个点赋给一组数组;
3)line()函数绘制矩形
源程序

#include “stdafx.h”
//本节讲述 图像处理之 直方图比较;
#include
#include
#include

using namespace std;
using namespace cv;

void contours_Callback(int, void*);
Mat src, test1, test2, dst, gray_src, temp;
char input_title[] = “原图”;
char output_title[] = “结果图”;
int match_method = CV_TM_SQDIFF;
int max_track = 5;
int threshold_value = 83;
int max_threshold = 255;

int main(int argc, char**argv)
{
src = imread(“C:\Users\Rubison.DELL\Desktop\杂物(3)\chess1.jpg”); //待检测图
//src = imread(“C:/Users/Rubison.DELL/Desktop\杂物/壁纸/小白2.jpg”);
if (src.empty())
{
printf(“could not load image…\r\n”);
return -1;
}

namedWindow(input_title, CV_WINDOW_NORMAL);
namedWindow(output_title, CV_WINDOW_NORMAL);

cvtColor(src, gray_src, CV_BGR2GRAY);
createTrackbar("Threshold Value", output_title, &threshold_value, max_threshold, contours_Callback);
contours_Callback(0, 0);
waitKey(0);
destroyAllWindows();
return 0;

}

void contours_Callback(int, void*)
{

//对图像进行二值化,控制阈值
Mat binary_output;
vector > contours;//用于存放检测到的轮廓,数据类型为vector,每个轮廓中存放着属于该轮廓的像素坐标
vector hierarchy;     //用于存放各个轮廓之间的结构信息,数据类型为vector
threshold(gray_src, binary_output, threshold_value, max_threshold, THRESH_BINARY);
namedWindow("轮廓图", CV_WINDOW_NORMAL);
imshow("轮廓图", binary_output);

//形态学操作:膨胀+腐蚀-------------------
Mat zj, dst1;
Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
Mat structureElement = getStructuringElement(MORPH_RECT, Size(31 * 2 + 1, 40 * 2 + 1), Point(-1, -1));//19
Mat structureElement2 = getStructuringElement(MORPH_RECT, Size(39 * 2 + 1, 39 * 2 + 1), Point(-1, -1));
dilate(binary_output, zj, structureElement, Point(-1, -1), 1); //膨胀操作
erode(zj, dst1, structureElement2, Point(-1, -1), 1); //腐蚀操作
namedWindow("形态学处理", CV_WINDOW_NORMAL);
imshow("形态学处理", dst1);

//-----------------------------------------
findContours(dst1, contours, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(-1, 1));
/*轮廓中的元素除了设置一个数组储存外,还可以使用迭代器
vector>::iterator itc = contours.begin();*/

vector> contours_poly(contours.size());   //括号内的为定义初始化 
vectorminRects(contours.size());

for (size_t i = 1; i < contours.size(); i++)
{
	approxPolyDP(Mat(contours[i]), contours_poly[i], 9, true);  // //减少每个轮廓的点数
	if (contours_poly[i].size() > 5)          //!!注意 该类型API要求点数必须大于5
	{
		minRects[i] = minAreaRect(contours_poly[i]);
		char width[20], height[20],core[40];
		sprintf_s(width,"width=%0.2f", minRects[i].size.width);
		sprintf_s(height, "height=%0.2f", minRects[i].size.height);
		sprintf_s(core, "Core(%0.2f,%0.2f)", minRects[i].size.width, minRects[i].size.height);
		//width = "宽度=" + minRects[i].size.width;
			cout << "angle " << i << " :" << minRects[i].angle << endl;
			cout << "width " << i << " :" << minRects[i].size.width << endl;
			cout << "height " << i << " :" << minRects[i].size.height << endl << endl;
		circle(src, Point(minRects[i].center.x, minRects[i].center.y), 5, Scalar(0, 0, 255), -1, 8);  //绘制最小外接矩形的中心点
		//putText(src, width, minRects[i].center, 0, 1, Scalar(0, 255, 0),3,8);
		putText(src, core, minRects[i].center + Point2f(0,30), 0, 1, Scalar(0, 255, 0), 3, 8);
		//putText(src, "6666", Point(3072/2,2048/2), 0, 5, Scalar(0, 255, 0),5,8);
	}
}
Point2f rect_point[4];
for (size_t j = 0; j < contours.size(); j++)
{
	Scalar color = Scalar(0, 0, 255);
	minRects[j].points(rect_point); //把最小外接矩形四个端点复制给pts数组
									//绘制矩形
	for (int k = 0; k < 4; k++)
	{
		line(src, rect_point[k], rect_point[(k + 1) % 4], color, 2, 8);
	}
}

imshow(output_title, src);

}

*结果显示图:

使用minAreaRect函数获取轮廓尺寸和形心坐标并打印_第1张图片

参考文章:参考

补充:关于minAreaRect函数中外形尺寸的问题:
参考文章:minAteaRect函数
使用minAreaRect函数获取轮廓尺寸和形心坐标并打印_第2张图片

你可能感兴趣的:(opencv,计算机视觉,c++)