OpenCV寻找物体最小包围矩形 minAreaRect()和最小包围圆minEnclosingCircle()
运用到的知识点:
1.寻找最小包围矩形
2.寻找最小包围圆
3.定义和输出vector容器点坐标
代码示例:
//寻找最小包围矩形
//寻找最小包围圆
//定义和输出vector容器点坐标
#include <opencv2/opencv.hpp>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <vector>
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
Mat testImage(600, 600, CV_8UC3);//画布大小600x600
RNG& rng = theRNG();
//按回车键一直更新
while (1)
{
testImage = Scalar::all(0);//将画布设置为黑色,每次按键后可更新
//int count = (unsigned)rng % 100 + 8;//随机生成点的数量
int count = rng.uniform(5, 20);//随机产生点的个数
cout << "凸包包含 " << count << " 个点" << endl;
cout << "各点坐标如下:" << endl;//输出产生随机点个数
vector<Point>points;//vector容器存放点坐标
for (int i = 0; i < count; i++)
{
Point point;
//点坐标随机产生
point.x = rng.uniform(testImage.cols / 5, testImage.cols * 4 / 5); //横坐标x在范围(600/1,600*4/5)随机产生
point.y = rng.uniform(testImage.rows / 4, testImage.rows * 3 / 4);//纵坐标y在范围(600/4,600*3/4)随机产生
points.push_back(point);
cout << "Point" << i + 1 << ": " << point << endl;//依次输出随机产生每个点的坐标
}
//输出并标记各点坐标
cout << "基于Mat的vector:\n" << Mat(points) << endl;//基于Mat类的vector将以矩阵形式输出坐标
for (int i = 0; i < count; i++)
circle(testImage, points[i], 5, Scalar(255, 0, 255), -1, 4);//以随机点为圆心,画出半径为5的实心圆
//=============【1】寻找最小包围矩形================
RotatedRect minRect = minAreaRect(Mat(points));
Point2f vertex[4];//用于存放最小矩形的四个顶点
minRect.points(vertex);//返回矩形的四个顶点给vertex
//绘制最小面积包围矩形
for (int i = 0; i < 4; i++)
line(testImage, vertex[i], vertex[(i + 1) % 4], Scalar(0, 0, 255), 1, 8);//非常巧妙的表达式
//=============【2】寻找最小包围圆================
Point2f center;//变量圆心坐标
float radius = 0;//初始化圆半径
minEnclosingCircle(Mat(points), center, radius);//寻找最小包围圆
circle(testImage, center, cvRound(radius), Scalar(0, 255, 0), 1, 8);//绘制最小包围圆,cvRound对半径进行四舍五入
//输出
imshow("凸包绘制检测", testImage);
char key;
key = (char)waitKey();
if (key == 27 || key == 'q' || key == 'Q')//按下ESC 或q 或 Q 退出
break;
}
return 0;
}
运行结果:
结果1
结果2