经典博文:https://www.jianshu.com/p/ef5ca683c005
https://www.cnblogs.com/mikewolf2002/p/3427079.html
https://blog.csdn.net/qq_18343569/article/details/48000179
http://blog.sina.com.cn/s/blog_8fc98fe501017ypb.html
https://blog.csdn.net/yansmile1/article/details/50261527
终极参考链接:https://blog.csdn.net/dcrmg/article/details/51987348#comments 与
-
//rectPoint变量中得到了矩形的四个顶点坐标
-
RotatedRect rectPoint = minAreaRect(points);
-
//定义一个存储以上四个点的坐标的变量
-
Point2f fourPoint2f[4];
-
//将rectPoint变量中存储的坐标值放到 fourPoint的数组中
-
rectPoint.points(fourPoint2f);
-
https://blog.csdn.net/qq_23880193/article/details/49257529?utm_source=copy(个人认是迄今见到最为深入浅出全面的一个帖子-必看)
在OpenCV中,能够很方便的求轮廓包围盒。包括矩形,圆形,椭圆形以及倾斜的矩形(包围面积最小)集中包围盒。用到的四个函数是:
1. Rect boundingRect(InputArray points)
2. void minEnclosingCircle(InputArray points, Point2f& center, float& radius)
3. RotatedRect minAreaRect(InputArray points)
4. RotatedRect fitEllipse(InputArray points)
这四个函数比较容易混淆,这里对其进行总结:
OpenCV求包覆矩形
Rect boundingRect(InputArray points)
- points:輸入資訊,可以為包含點的容器(vector)或是Mat。
- 返回包覆輸入資訊的最小正矩形。
OpenCV求包覆矩形
RotatedRect minAreaRect(InputArray points)
- points:輸入資訊,可以為包含點的容器(vector)或是Mat。
- 返回包覆輸入資訊的最小斜矩形。
OpenCV求包覆圓形
void minEnclosingCircle(InputArray points, Point2f& center, float& radius)
- points:輸入資訊,可以為包含點的容器(vector)或是Mat。
- center:包覆圓形的圓心。
- radius:包覆圓形的半徑。
boundingRect()函数的使用方法
Calculates the up-right bounding rectangle of a point set.
C++: Rect boundingRect(InputArray points)
Parameters: points – Input 2D point set, stored in std::vector or Mat.
注意:(boundingRect读入的参数必须是vector或者Mat点集)
使用例程:
for( size_t k = 0; k < contours.size(); k++ )
{
Rect ret1=boundingRect(Mat(contours[k]));//计算右上点集的边界矩形
avgX = (ret1.x + ret1.x + ret1.width)/2; //运动物体的矩形的中点X位置
avgY = (ret1.y + ret1.y + ret1.height)/2;//运动物体的矩形的中点Y位置
cout<<"x:"<<avgX<<"y:"<<avgY<<endl;
}
RotatedRect
class RotatedRect
class CV_EXPORTS RotatedRect
{
public:
//! various constructors
RotatedRect();
RotatedRect(const Point2f& center, const Size2f& size, float angle);
RotatedRect(const CvBox2D& box);
//! returns 4 vertices of the rectangle
void points(Point2f pts[]) const;
//! returns the minimal up-right rectangle containing the rotated rectangle
Rect boundingRect() const;
//! conversion to the old-style CvBox2D structure
operator CvBox2D() const;
Point2f center; //< the rectangle mass center
Size2f size; //< width and height of the rectangle
float angle; //< the rotation angle. When the angle is 0, 90, 180, 270 etc., the rectangle becomes an up-right rectangle.
};
The class represents rotated (i.e. not up-right) rectangles on a plane. Each rectangle is specified by the center point (mass center), length of each side (represented by cv::Size2f structure) and the rotation angle in degrees.
C++: RotatedRect::RotatedRect()
C++: RotatedRect::RotatedRect(const Point2f& center, const Size2f& size, float angle)
C++: RotatedRect::RotatedRect(const CvBox2D& box)
Parameters:
- center – The rectangle mass center.
- size – Width and height of the rectangle.
- angle – The rotation angle in a clockwise direction. When the angle is 0, 90, 180, 270 etc., the rectangle becomes an up-right rectangle.
- box – The rotated rectangle parameters as the obsolete CvBox2D structure.
C++: void RotatedRect::points(Point2f pts[]) const //! returns 4 vertices of the rectangle
C++: Rect RotatedRect::boundingRect() const
C++: RotatedRect::operator CvBox2D() const
Parameters:
- pts – The points array for storing rectangle vertices.
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace cv;
using namespace std;
Mat src; Mat src_gray;
int thresh = 221;
int max_thresh = 255;
RNG rng(12345);
/// Function header
void thresh_callback(int, void*);
/** @function main */
int main(int argc, char** argv)
{
/// 加载源图像
src = imread("123.jpg", 1);
resize(src, src, Size(512, 512));
/// 转为灰度图并模糊化
cvtColor(src, src_gray, CV_BGR2GRAY);
blur(src_gray, src_gray, Size(3, 3));
/// 创建窗体
char* source_window = "Source";
namedWindow(source_window, CV_WINDOW_AUTOSIZE);
imshow(source_window, src);
createTrackbar(" Threshold:", "Source", &thresh, max_thresh, thresh_callback);
thresh_callback(0, 0);
waitKey(0);
return(0);
}
/** @function thresh_callback */
void thresh_callback(int, void*)
{
Mat threshold_output;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
/// 阈值化检测边界
threshold(src_gray, threshold_output, thresh, 255, THRESH_BINARY);
/// 寻找轮廓
findContours(threshold_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
/// 对每个找到的轮廓创建可倾斜的边界框和椭圆
vector<RotatedRect> minRect(contours.size());
//vector<RotatedRect> minEllipse(contours.size());
for (int i = 0; i < contours.size(); i++)
{
minRect[i] = minAreaRect(Mat(contours[i]));
/*if (contours[i].size() > 5)
{
minEllipse[i] = fitEllipse(Mat(contours[i]));
}*/
}
/// 绘出轮廓及其可倾斜的边界框和边界椭圆
Mat drawing = Mat::zeros(threshold_output.size(), CV_8UC3);
for (int i = 0; i< contours.size(); i++)
{
//rectPoint变量中得到了矩形的四个顶点坐标
//RotatedRect rectPoint = minAreaRect(points);//定义一个存储以上四个点的坐标的变量
// Point2f fourPoint2f[4];
//将rectPoint变量中存储的坐标值放到 fourPoint的数组中
// rectPoint.points(fourPoint2f);
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
// contour
drawContours(drawing, contours, i, color, 1, 8, vector<Vec4i>(), 0, Point());
// rotated rectangle
Point2f rect_points[4]; minRect[i].points(rect_points);
for (int j = 0; j < 4; j++) {
line(drawing, rect_points[j], rect_points[(j + 1) % 4], color, 1, 8);
cout << rect_points[j].x <<" "<< rect_points[j].y << endl;
}
}
/// 结果在窗体中显示
namedWindow("Contours", CV_WINDOW_AUTOSIZE);
imshow("Contours", drawing);
}
最终结果: