opencv 之 外接多边形(矩形、圆、三角形、椭圆、多边形)使用详解

本文主要讲述opencv中的外接多边形的使用:

多边形近似外接矩形、最小外接矩形最小外接圆外接三角形椭圆拟合凸包 将重点讲述最小外接矩形的使用

1. API介绍

#多边形近似

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. 例程

给一个opencv官方的例程:

#include "opencv2/highgui.hpp"

#include "opencv2/imgproc.hpp"

#include

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 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 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;

}

过程图像如下: 椭圆拟合一般用于轮廓提取之后:

//获取拟合椭圆的外包围矩形

cv::RotatedRect rotate_rect = cv::fitEllipse(points);

//绘制拟合椭圆

cv::ellipse(image, rotate_rect, cv::Scalar(0, 255, 255), 2, 8);

凸包绘制

vector 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);

计算两个旋转矩形交集:

vector intersectingRegion;

rotatedRectangleIntersection(rect1, rect2, intersectingRegion);

3. 关于最小外接矩形

C++版的最小外接矩形使用:

RotatedRect rect = minAreaRect(points);

float angle = rect.

box.points(vtx);

其接口返回值可读取如下:其中,其角度指的是width与物理坐标系y轴正方向逆时针所成的夹角 赋值时也可以读出如下数据:中心、角度、尺寸大小、外接矩形

画图详解一下吧: 想要看真实的效果图的话,可以参考:biubiubiu~ 它也可以用于: python版本的最小外接矩形:

_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)

还有一些想法,后边再补充吧

文章来源

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。