Detailed explanation of the use of opencv external polygons (rectangle, circle, triangle, ellipse, polygon)

Detailed explanation of the use of opencv external polygons (rectangle, circle, triangle, ellipse, polygon)

  • This article mainly describes the use of circumscribed polygons in opencv:

    • polygon approximation
    • Circumscribed Rectangle, Minimum Circumscribed Rectangle
    • Minimum circumscribed circle
    • circumscribed triangle
    • Ellipse fitting
    • convex hull
  • will focus on the use of the minimum bounding rectangle

1. API introduction

#多边形近似
void cv::approxPolyDP(InputArray 	curve,
          OutputArray 	approxCurve,
          double 	epsilon,
          bool 	closed )		
Python:
cv.approxPolyDP(curve, epsilon, closed[, approxCurve]	) ->	approxCurve

#计算点到多边形的距离或者判断是否在多边形内部
double cv::pointPolygonTest	(InputArray 	contour,
           Point2f 	pt,
           bool 	measureDist )		
Python:
cv.pointPolygonTest(contour, pt, measureDist) ->	retval


#外接矩形
Rect cv::boundingRect(InputArray 	array)	

Python:
cv.boundingRect(array) ->	retval

#最小外接矩形
RotatedRect cv::minAreaRect	(InputArray 	points)	
Python:
cv.minAreaRect(	points) ->	retval

#求矩形交集
int cv::rotatedRectangleIntersection(const RotatedRect & 	rect1,
        const RotatedRect & 	rect2,
        OutputArray 	intersectingRegion )		
Python:
cv.rotatedRectangleIntersection(rect1, rect2[, intersectingRegion]	) ->	retval, intersectingRegion


#最小外接圆
void cv::minEnclosingCircle	(InputArray 	points,
        Point2f & 	center,
        float & 	radius )		
Python:
cv.minEnclosingCircle(points) ->	center, radius

#最小外接三角形
double cv::minEnclosingTriangle	(InputArray 	points,
        OutputArray 	triangle)		
Python:
cv.minEnclosingTriangle(points[, triangle]	) ->	retval, triangle

#椭圆拟合
void cv::ellipse(InputOutputArray 	img,
        Point 	center,
        Size 	axes,
        double 	angle,
        double 	startAngle,
        double 	endAngle,
        const Scalar & 	color,
        int 	thickness = 1,
        int 	lineType = LINE_8,
        int 	shift = 0 )		
Python:
cv.ellipse(	img, center, axes, angle, startAngle, endAngle, color[, thickness[, lineType[, shift]]]	) ->	img
cv.ellipse(	img, box, color[, thickness[, lineType]]	) ->	img

2. Routine

  • Give an opencv official routine:
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std;
static void help()
{
    
    
	cout << "This program demonstrates finding the minimum enclosing box, triangle or circle of a set\n"
		<< "of points using functions: minAreaRect() minEnclosingTriangle() minEnclosingCircle().\n"
		<< "Random points are generated and then enclosed.\n\n"
		<< "Press ESC, 'q' or 'Q' to exit and any other key to regenerate the set of points.\n\n";
}
int main(int /*argc*/, char** /*argv*/)
{
    
    
	help();
	Mat img(500, 500, CV_8UC3, Scalar::all(0));
	RNG& rng = theRNG();
	for (;;)
	{
    
    
		int i, count = rng.uniform(1, 101);
		vector<Point> points;
		// Generate a random set of points
		for (i = 0; i < count; i++)
		{
    
    
			Point pt;
			pt.x = rng.uniform(img.cols / 4, img.cols * 3 / 4);
			pt.y = rng.uniform(img.rows / 4, img.rows * 3 / 4);
			points.push_back(pt);
		}
		// Find the minimum area enclosing bounding box
		Point2f vtx[4];
		RotatedRect box = minAreaRect(points);
		box.points(vtx);
		// Find the minimum area enclosing triangle
		vector<Point2f> triangle;
		minEnclosingTriangle(points, triangle);
		// Find the minimum area enclosing circle
		Point2f center;
		float radius = 0;
		minEnclosingCircle(points, center, radius);

		img = Scalar::all(0);
		// Draw the points
		for (i = 0; i < count; i++)
			circle(img, points[i], 3, Scalar(0, 0, 255), FILLED, LINE_AA);
		// Draw the bounding box
		for (i = 0; i < 4; i++)
			line(img, vtx[i], vtx[(i + 1) % 4], Scalar(0, 255, 0), 1, LINE_AA);

		//绘制外接矩形
		rectangle(img, box.boundingRect(), cv::Scalar(10, 100, 20), 2);
        
		//也可以:
		/*cv::Rect _rect = boundingRect(points);
		rectangle(img, _rect, cv::Scalar(10, 100, 20), 2);*/

		// Draw the triangle
		for (i = 0; i < 3; i++)
			line(img, triangle[i], triangle[(i + 1) % 3], Scalar(255, 255, 0), 1, LINE_AA);
		// Draw the circle
		circle(img, center, cvRound(radius), Scalar(0, 255, 255), 1, LINE_AA);
		imshow("Rectangle, triangle & circle", img);
		char key = (char)waitKey();
		if (key == 27 || key == 'q' || key == 'Q') // 'ESC'
			break;
	}
	return 0;
}
  • The process image is as follows:
    insert image description here
  • Ellipse fitting is generally used after contour extraction:

//获取拟合椭圆的外包围矩形  
cv::RotatedRect rotate_rect = cv::fitEllipse(points);  
//绘制拟合椭圆  
cv::ellipse(image, rotate_rect, cv::Scalar(0, 255, 255), 2, 8);  

insert image description here

  • Convex Hull Drawing
 vector<Point> hull;
 convexHull(points, hull, true);
 img = Scalar::all(0);
 for( i = 0; i < count; i++ )
 circle(img, points[i], 3, Scalar(0, 0, 255), FILLED, LINE_AA);
 polylines(img, hull, true, Scalar(0, 255, 0), 1, LINE_AA);
 imshow("hull", img);
 #多边形填充绘制:
 polylines(img, hull, true, Scalar(0, 255, 0), -1, LINE_AA);
  • Compute the intersection of two rotated rectangles:
vector<Point2f> intersectingRegion;
rotatedRectangleIntersection(rect1, rect2, intersectingRegion);

insert image description here

3. About the minimum enclosing rectangle

  • The C++ version of the minimum bounding rectangle uses:
RotatedRect rect = minAreaRect(points);
float angle = rect.
box.points(vtx);

The return value of its interface can be read as follows: Among them, the angle refers to the angle between the width and the positive direction of the y-axis of the physical coordinate system counterclockwise. When assigning values, the following data can also be read: center, angle
insert image description here
, size, circumscribed rectangle
insert image description here

  • Let’s draw a picture and explain it in detail:
    insert image description here
  • If you want to see the real effect picture, you can refer to: biubiubiu~
    insert image description here
  • It can also be used for:
    insert image description here
  • The minimum bounding rectangle of the python version:
 _rect = cv2.minAreaRect(conts_new[i])
 (x, y), (w, h), ang = _rect
 box = cv2.boxPoints(_rect)
 # 标准化坐标到整数
 box = np.int32(box)
 cv2.drawContours(mask_c3, [box], 0, (int(bgr[0]), int(bgr[1]), int(bgr[2])),2)
  • I have some more ideas, I'll add them later

Guess you like

Origin blog.csdn.net/yohnyang/article/details/131871093