opencv ellipse
opencv ellipse
/** @brief Draws a simple or thick elliptic arc or fills an ellipse sector. The function cv::ellipse with more parameters draws an ellipse outline, a filled ellipse, an elliptic arc, or a filled ellipse sector. The drawing code uses general parametric form. A piecewise-linear curve is used to approximate the elliptic arc boundary. If you need more control of the ellipse rendering, you can retrieve the curve using cv::ellipse2Poly and then render it with polylines or fill it with cv::fillPoly. If you use the first variant of the function and want to draw the whole ellipse, not an arc, pass `startAngle=0` and `endAngle=360`. If `startAngle` is greater than `endAngle`, they are swapped. The figure below explains the meaning of the parameters to draw the blue arc. ![Parameters of Elliptic Arc](pics/ellipse.svg) @param img Image. @param center Center of the ellipse. @param axes Half of the size of the ellipse main axes. @param angle Ellipse rotation angle in degrees. @param startAngle Starting angle of the elliptic arc in degrees. @param endAngle Ending angle of the elliptic arc in degrees. @param color Ellipse color. @param thickness Thickness of the ellipse arc outline, if positive. Otherwise, this indicates that a filled ellipse sector is to be drawn. @param lineType Type of the ellipse boundary. See the line description. @param shift Number of fractional bits in the coordinates of the center and values of axes. */ CV_EXPORTS_W void 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);
void ellipse( InputOutputArray _img, Point center, Size axes, double angle, double start_angle, double end_angle, const Scalar& color, int thickness, int line_type, int shift ) { CV_INSTRUMENT_REGION(); Mat img = _img.getMat(); if( line_type == CV_AA && img.depth() != CV_8U ) line_type = 8; CV_Assert( axes.width >= 0 && axes.height >= 0 && thickness <= MAX_THICKNESS && 0 <= shift && shift <= XY_SHIFT ); double buf[4]; scalarToRawData(color, buf, img.type(), 0); int _angle = cvRound(angle); int _start_angle = cvRound(start_angle); int _end_angle = cvRound(end_angle); Point2l _center(center); Size2l _axes(axes); _center.x <<= XY_SHIFT - shift; _center.y <<= XY_SHIFT - shift; _axes.width <<= XY_SHIFT - shift; _axes.height <<= XY_SHIFT - shift; EllipseEx( img, _center, _axes, _angle, _start_angle, _end_angle, buf, thickness, line_type ); }
void ellipse(InputOutputArray _img, const RotatedRect& box, const Scalar& color, int thickness, int lineType) { CV_INSTRUMENT_REGION(); Mat img = _img.getMat(); if( lineType == CV_AA && img.depth() != CV_8U ) lineType = 8; CV_Assert( box.size.width >= 0 && box.size.height >= 0 && thickness <= MAX_THICKNESS ); double buf[4]; scalarToRawData(color, buf, img.type(), 0); int _angle = cvRound(box.angle); Point2l center(cvRound(box.center.x), cvRound(box.center.y)); center.x = (center.x << XY_SHIFT) + cvRound((box.center.x - center.x)*XY_ONE); center.y = (center.y << XY_SHIFT) + cvRound((box.center.y - center.y)*XY_ONE); Size2l axes(cvRound(box.size.width), cvRound(box.size.height)); axes.width = (axes.width << (XY_SHIFT - 1)) + cvRound((box.size.width - axes.width)*(XY_ONE>>1)); axes.height = (axes.height << (XY_SHIFT - 1)) + cvRound((box.size.height - axes.height)*(XY_ONE>>1)); EllipseEx( img, center, axes, _angle, 0, 360, buf, thickness, lineType ); }
static void EllipseEx( Mat& img, Point2l center, Size2l axes, int angle, int arc_start, int arc_end, const void* color, int thickness, int line_type ) { axes.width = std::abs(axes.width), axes.height = std::abs(axes.height); int delta = (int)((std::max(axes.width,axes.height)+(XY_ONE>>1))>>XY_SHIFT); delta = delta < 3 ? 90 : delta < 10 ? 30 : delta < 15 ? 18 : 5; std::vector<Point2d> _v; ellipse2Poly( Point2d((double)center.x, (double)center.y), Size2d((double)axes.width, (double)axes.height), angle, arc_start, arc_end, delta, _v ); std::vector<Point2l> v; Point2l prevPt(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF); v.resize(0); for (unsigned int i = 0; i < _v.size(); ++i) { Point2l pt; pt.x = (int64)cvRound(_v[i].x / XY_ONE) << XY_SHIFT; pt.y = (int64)cvRound(_v[i].y / XY_ONE) << XY_SHIFT; pt.x += cvRound(_v[i].x - pt.x); pt.y += cvRound(_v[i].y - pt.y); if (pt != prevPt) { v.push_back(pt); prevPt = pt; } } // If there are no points, it's a zero-size polygon if (v.size() == 1) { v.assign(2, center); } if( thickness >= 0 ) PolyLine( img, &v[0], (int)v.size(), false, color, thickness, line_type, XY_SHIFT ); else if( arc_end - arc_start >= 360 ) FillConvexPoly( img, &v[0], (int)v.size(), color, line_type, XY_SHIFT ); else { v.push_back(center); std::vector<PolyEdge> edges; CollectPolyEdges( img, &v[0], (int)v.size(), edges, color, line_type, XY_SHIFT ); FillEdgeCollection( img, edges, color ); } }
#############################################
QQ 3087438119