函数解释:
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);
}
*结果显示图:
参考文章:参考