mirror of
https://github.com/opencv/opencv.git
synced 2024-11-25 11:40:44 +08:00
Fix for incorrect line drawing beyond 32768 row or column
This commit is contained in:
parent
de85680a6a
commit
26c9889c6b
@ -177,6 +177,7 @@ public:
|
||||
};
|
||||
|
||||
typedef Point_<int> Point2i;
|
||||
typedef Point_<int64> Point2l;
|
||||
typedef Point_<float> Point2f;
|
||||
typedef Point_<double> Point2d;
|
||||
typedef Point2i Point;
|
||||
@ -308,6 +309,7 @@ public:
|
||||
};
|
||||
|
||||
typedef Size_<int> Size2i;
|
||||
typedef Size_<int64> Size2l;
|
||||
typedef Size_<float> Size2f;
|
||||
typedef Size_<double> Size2d;
|
||||
typedef Size2i Size;
|
||||
|
@ -4408,6 +4408,13 @@ it returns true .
|
||||
*/
|
||||
CV_EXPORTS bool clipLine(Size imgSize, CV_IN_OUT Point& pt1, CV_IN_OUT Point& pt2);
|
||||
|
||||
/** @overload
|
||||
@param imgSize Image size. The image rectangle is Rect(0, 0, imgSize.width, imgSize.height) .
|
||||
@param pt1 First line point.
|
||||
@param pt2 Second line point.
|
||||
*/
|
||||
CV_EXPORTS bool clipLine(Size2l imgSize, CV_IN_OUT Point2l& pt1, CV_IN_OUT Point2l& pt2);
|
||||
|
||||
/** @overload
|
||||
@param imgRect Image rectangle.
|
||||
@param pt1 First line point.
|
||||
@ -4433,6 +4440,20 @@ CV_EXPORTS_W void ellipse2Poly( Point center, Size axes, int angle,
|
||||
int arcStart, int arcEnd, int delta,
|
||||
CV_OUT std::vector<Point>& pts );
|
||||
|
||||
/** @overload
|
||||
@param center Center of the arc.
|
||||
@param axes Half of the size of the ellipse main axes. See the ellipse for details.
|
||||
@param angle Rotation angle of the ellipse in degrees. See the ellipse for details.
|
||||
@param arcStart Starting angle of the elliptic arc in degrees.
|
||||
@param arcEnd Ending angle of the elliptic arc in degrees.
|
||||
@param delta Angle between the subsequent polyline vertices. It defines the approximation
|
||||
accuracy.
|
||||
@param pts Output vector of polyline vertices.
|
||||
*/
|
||||
CV_EXPORTS void ellipse2Poly(Point2d center, Size2d axes, int angle,
|
||||
int arcStart, int arcEnd, int delta,
|
||||
CV_OUT std::vector<Point2d>& pts);
|
||||
|
||||
/** @brief Draws a text string.
|
||||
|
||||
The function putText renders the specified text string in the image. Symbols that cannot be rendered
|
||||
|
@ -53,12 +53,12 @@ struct PolyEdge
|
||||
//PolyEdge(int _y0, int _y1, int _x, int _dx) : y0(_y0), y1(_y1), x(_x), dx(_dx) {}
|
||||
|
||||
int y0, y1;
|
||||
int x, dx;
|
||||
int64 x, dx;
|
||||
PolyEdge *next;
|
||||
};
|
||||
|
||||
static void
|
||||
CollectPolyEdges( Mat& img, const Point* v, int npts,
|
||||
CollectPolyEdges( Mat& img, const Point2l* v, int npts,
|
||||
std::vector<PolyEdge>& edges, const void* color, int line_type,
|
||||
int shift, Point offset=Point() );
|
||||
|
||||
@ -66,11 +66,11 @@ static void
|
||||
FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color );
|
||||
|
||||
static void
|
||||
PolyLine( Mat& img, const Point* v, int npts, bool closed,
|
||||
PolyLine( Mat& img, const Point2l* v, int npts, bool closed,
|
||||
const void* color, int thickness, int line_type, int shift );
|
||||
|
||||
static void
|
||||
FillConvexPoly( Mat& img, const Point* v, int npts,
|
||||
FillConvexPoly( Mat& img, const Point2l* v, int npts,
|
||||
const void* color, int line_type, int shift );
|
||||
|
||||
/****************************************************************************************\
|
||||
@ -78,17 +78,28 @@ FillConvexPoly( Mat& img, const Point* v, int npts,
|
||||
\****************************************************************************************/
|
||||
|
||||
bool clipLine( Size img_size, Point& pt1, Point& pt2 )
|
||||
{
|
||||
Point2l p1(pt1);
|
||||
Point2l p2(pt2);
|
||||
bool inside = clipLine(Size2l(img_size.width, img_size.height), p1, p2);
|
||||
pt1.x = (int)p1.x;
|
||||
pt1.y = (int)p1.y;
|
||||
pt2.x = (int)p2.x;
|
||||
pt2.y = (int)p2.y;
|
||||
return inside;
|
||||
}
|
||||
|
||||
bool clipLine( Size2l img_size, Point2l& pt1, Point2l& pt2 )
|
||||
{
|
||||
CV_INSTRUMENT_REGION()
|
||||
|
||||
int64 x1, y1, x2, y2;
|
||||
int c1, c2;
|
||||
int64 right = img_size.width-1, bottom = img_size.height-1;
|
||||
|
||||
if( img_size.width <= 0 || img_size.height <= 0 )
|
||||
return false;
|
||||
|
||||
x1 = pt1.x; y1 = pt1.y; x2 = pt2.x; y2 = pt2.y;
|
||||
int64 &x1 = pt1.x, &y1 = pt1.y, &x2 = pt2.x, &y2 = pt2.y;
|
||||
c1 = (x1 < 0) + (x1 > right) * 2 + (y1 < 0) * 4 + (y1 > bottom) * 8;
|
||||
c2 = (x2 < 0) + (x2 > right) * 2 + (y2 < 0) * 4 + (y2 > bottom) * 8;
|
||||
|
||||
@ -128,11 +139,6 @@ bool clipLine( Size img_size, Point& pt1, Point& pt2 )
|
||||
}
|
||||
|
||||
assert( (c1 & c2) != 0 || (x1 | y1 | x2 | y2) >= 0 );
|
||||
|
||||
pt1.x = (int)x1;
|
||||
pt1.y = (int)y1;
|
||||
pt2.x = (int)x2;
|
||||
pt2.y = (int)y2;
|
||||
}
|
||||
|
||||
return (c1 | c2) == 0;
|
||||
@ -285,25 +291,25 @@ static const int FilterTable[] = {
|
||||
};
|
||||
|
||||
static void
|
||||
LineAA( Mat& img, Point pt1, Point pt2, const void* color )
|
||||
LineAA( Mat& img, Point2l pt1, Point2l pt2, const void* color )
|
||||
{
|
||||
int dx, dy;
|
||||
int64 dx, dy;
|
||||
int ecount, scount = 0;
|
||||
int slope;
|
||||
int ax, ay;
|
||||
int x_step, y_step;
|
||||
int i, j;
|
||||
int64 ax, ay;
|
||||
int64 x_step, y_step;
|
||||
int64 i, j;
|
||||
int ep_table[9];
|
||||
int cb = ((uchar*)color)[0], cg = ((uchar*)color)[1], cr = ((uchar*)color)[2], ca = ((uchar*)color)[3];
|
||||
int _cb, _cg, _cr, _ca;
|
||||
int nch = img.channels();
|
||||
uchar* ptr = img.ptr();
|
||||
size_t step = img.step;
|
||||
Size size = img.size();
|
||||
Size2l size(img.size());
|
||||
|
||||
if( !((nch == 1 || nch == 3 || nch == 4) && img.depth() == CV_8U) )
|
||||
{
|
||||
Line(img, pt1, pt2, color);
|
||||
Line(img, Point((int)(pt1.x<<XY_SHIFT), (int)(pt1.y<<XY_SHIFT)), Point((int)(pt2.x<<XY_SHIFT), (int)(pt2.y<<XY_SHIFT)), color);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -339,11 +345,11 @@ LineAA( Mat& img, Point pt1, Point pt2, const void* color )
|
||||
pt1.y ^= pt2.y & j;
|
||||
|
||||
x_step = XY_ONE;
|
||||
y_step = (int) (((int64) dy << XY_SHIFT) / (ax | 1));
|
||||
y_step = (dy << XY_SHIFT) / (ax | 1);
|
||||
pt2.x += XY_ONE;
|
||||
ecount = (pt2.x >> XY_SHIFT) - (pt1.x >> XY_SHIFT);
|
||||
ecount = (int)((pt2.x >> XY_SHIFT) - (pt1.x >> XY_SHIFT));
|
||||
j = -(pt1.x & (XY_ONE - 1));
|
||||
pt1.y += (int) ((((int64) y_step) * j) >> XY_SHIFT) + (XY_ONE >> 1);
|
||||
pt1.y += ((y_step * j) >> XY_SHIFT) + (XY_ONE >> 1);
|
||||
slope = (y_step >> (XY_SHIFT - 5)) & 0x3f;
|
||||
slope ^= (y_step < 0 ? 0x3f : 0);
|
||||
|
||||
@ -362,12 +368,12 @@ LineAA( Mat& img, Point pt1, Point pt2, const void* color )
|
||||
pt2.y ^= pt1.y & i;
|
||||
pt1.y ^= pt2.y & i;
|
||||
|
||||
x_step = (int) (((int64) dx << XY_SHIFT) / (ay | 1));
|
||||
x_step = (dx << XY_SHIFT) / (ay | 1);
|
||||
y_step = XY_ONE;
|
||||
pt2.y += XY_ONE;
|
||||
ecount = (pt2.y >> XY_SHIFT) - (pt1.y >> XY_SHIFT);
|
||||
ecount = (int)((pt2.y >> XY_SHIFT) - (pt1.y >> XY_SHIFT));
|
||||
j = -(pt1.y & (XY_ONE - 1));
|
||||
pt1.x += (int) ((((int64) x_step) * j) >> XY_SHIFT) + (XY_ONE >> 1);
|
||||
pt1.x += ((x_step * j) >> XY_SHIFT) + (XY_ONE >> 1);
|
||||
slope = (x_step >> (XY_SHIFT - 5)) & 0x3f;
|
||||
slope ^= (x_step < 0 ? 0x3f : 0);
|
||||
|
||||
@ -381,8 +387,8 @@ LineAA( Mat& img, Point pt1, Point pt2, const void* color )
|
||||
/* Calc end point correction table */
|
||||
{
|
||||
int t0 = slope << 7;
|
||||
int t1 = ((0x78 - i) | 4) * slope;
|
||||
int t2 = (j | 4) * slope;
|
||||
int t1 = ((0x78 - (int)i) | 4) * slope;
|
||||
int t2 = ((int)j | 4) * slope;
|
||||
|
||||
ep_table[0] = 0;
|
||||
ep_table[8] = slope;
|
||||
@ -636,23 +642,25 @@ LineAA( Mat& img, Point pt1, Point pt2, const void* color )
|
||||
|
||||
|
||||
static void
|
||||
Line2( Mat& img, Point pt1, Point pt2, const void* color )
|
||||
Line2( Mat& img, Point2l pt1, Point2l pt2, const void* color)
|
||||
{
|
||||
int dx, dy;
|
||||
int64 dx, dy;
|
||||
int ecount;
|
||||
int ax, ay;
|
||||
int i, j, x, y;
|
||||
int x_step, y_step;
|
||||
int64 ax, ay;
|
||||
int64 i, j;
|
||||
int x, y;
|
||||
int64 x_step, y_step;
|
||||
int cb = ((uchar*)color)[0];
|
||||
int cg = ((uchar*)color)[1];
|
||||
int cr = ((uchar*)color)[2];
|
||||
int pix_size = (int)img.elemSize();
|
||||
uchar *ptr = img.ptr(), *tptr;
|
||||
size_t step = img.step;
|
||||
Size size = img.size(), sizeScaled(size.width*XY_ONE, size.height*XY_ONE);
|
||||
Size size = img.size();
|
||||
|
||||
//assert( img && (nch == 1 || nch == 3) && img.depth() == CV_8U );
|
||||
|
||||
Size2l sizeScaled(((int64)size.width) << XY_SHIFT, ((int64)size.height) << XY_SHIFT);
|
||||
if( !clipLine( sizeScaled, pt1, pt2 ))
|
||||
return;
|
||||
|
||||
@ -676,8 +684,8 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color )
|
||||
pt1.y ^= pt2.y & j;
|
||||
|
||||
x_step = XY_ONE;
|
||||
y_step = (int) (((int64) dy << XY_SHIFT) / (ax | 1));
|
||||
ecount = (pt2.x - pt1.x) >> XY_SHIFT;
|
||||
y_step = (dy << XY_SHIFT) / (ax | 1);
|
||||
ecount = (int)((pt2.x - pt1.x) >> XY_SHIFT);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -690,9 +698,9 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color )
|
||||
pt2.y ^= pt1.y & i;
|
||||
pt1.y ^= pt2.y & i;
|
||||
|
||||
x_step = (int) (((int64) dx << XY_SHIFT) / (ay | 1));
|
||||
x_step = (dx << XY_SHIFT) / (ay | 1);
|
||||
y_step = XY_ONE;
|
||||
ecount = (pt2.y - pt1.y) >> XY_SHIFT;
|
||||
ecount = (int)((pt2.y - pt1.y) >> XY_SHIFT);
|
||||
}
|
||||
|
||||
pt1.x += (XY_ONE >> 1);
|
||||
@ -711,8 +719,8 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color )
|
||||
tptr[2] = (uchar)cr; \
|
||||
}
|
||||
|
||||
ICV_PUT_POINT((pt2.x + (XY_ONE >> 1)) >> XY_SHIFT,
|
||||
(pt2.y + (XY_ONE >> 1)) >> XY_SHIFT);
|
||||
ICV_PUT_POINT((int)((pt2.x + (XY_ONE >> 1)) >> XY_SHIFT),
|
||||
(int)((pt2.y + (XY_ONE >> 1)) >> XY_SHIFT));
|
||||
|
||||
if( ax > ay )
|
||||
{
|
||||
@ -720,7 +728,7 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color )
|
||||
|
||||
while( ecount >= 0 )
|
||||
{
|
||||
ICV_PUT_POINT(pt1.x, pt1.y >> XY_SHIFT);
|
||||
ICV_PUT_POINT((int)(pt1.x), (int)(pt1.y >> XY_SHIFT));
|
||||
pt1.x++;
|
||||
pt1.y += y_step;
|
||||
ecount--;
|
||||
@ -732,7 +740,7 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color )
|
||||
|
||||
while( ecount >= 0 )
|
||||
{
|
||||
ICV_PUT_POINT(pt1.x >> XY_SHIFT, pt1.y);
|
||||
ICV_PUT_POINT((int)(pt1.x >> XY_SHIFT), (int)(pt1.y));
|
||||
pt1.x += x_step;
|
||||
pt1.y++;
|
||||
ecount--;
|
||||
@ -752,8 +760,8 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color )
|
||||
tptr[0] = (uchar)cb; \
|
||||
}
|
||||
|
||||
ICV_PUT_POINT((pt2.x + (XY_ONE >> 1)) >> XY_SHIFT,
|
||||
(pt2.y + (XY_ONE >> 1)) >> XY_SHIFT);
|
||||
ICV_PUT_POINT((int)((pt2.x + (XY_ONE >> 1)) >> XY_SHIFT),
|
||||
(int)((pt2.y + (XY_ONE >> 1)) >> XY_SHIFT));
|
||||
|
||||
if( ax > ay )
|
||||
{
|
||||
@ -761,7 +769,7 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color )
|
||||
|
||||
while( ecount >= 0 )
|
||||
{
|
||||
ICV_PUT_POINT(pt1.x, pt1.y >> XY_SHIFT);
|
||||
ICV_PUT_POINT((int)(pt1.x), (int)(pt1.y >> XY_SHIFT));
|
||||
pt1.x++;
|
||||
pt1.y += y_step;
|
||||
ecount--;
|
||||
@ -773,7 +781,7 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color )
|
||||
|
||||
while( ecount >= 0 )
|
||||
{
|
||||
ICV_PUT_POINT(pt1.x >> XY_SHIFT, pt1.y);
|
||||
ICV_PUT_POINT((int)(pt1.x >> XY_SHIFT), (int)(pt1.y));
|
||||
pt1.x += x_step;
|
||||
pt1.y++;
|
||||
ecount--;
|
||||
@ -794,8 +802,8 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color )
|
||||
tptr[j] = ((uchar*)color)[j]; \
|
||||
}
|
||||
|
||||
ICV_PUT_POINT((pt2.x + (XY_ONE >> 1)) >> XY_SHIFT,
|
||||
(pt2.y + (XY_ONE >> 1)) >> XY_SHIFT);
|
||||
ICV_PUT_POINT((int)((pt2.x + (XY_ONE >> 1)) >> XY_SHIFT),
|
||||
(int)((pt2.y + (XY_ONE >> 1)) >> XY_SHIFT));
|
||||
|
||||
if( ax > ay )
|
||||
{
|
||||
@ -803,7 +811,7 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color )
|
||||
|
||||
while( ecount >= 0 )
|
||||
{
|
||||
ICV_PUT_POINT(pt1.x, pt1.y >> XY_SHIFT);
|
||||
ICV_PUT_POINT((int)(pt1.x), (int)(pt1.y >> XY_SHIFT));
|
||||
pt1.x++;
|
||||
pt1.y += y_step;
|
||||
ecount--;
|
||||
@ -815,7 +823,7 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color )
|
||||
|
||||
while( ecount >= 0 )
|
||||
{
|
||||
ICV_PUT_POINT(pt1.x >> XY_SHIFT, pt1.y);
|
||||
ICV_PUT_POINT((int)(pt1.x >> XY_SHIFT), (int)(pt1.y));
|
||||
pt1.x += x_step;
|
||||
pt1.y++;
|
||||
ecount--;
|
||||
@ -923,15 +931,38 @@ sincos( int angle, float& cosval, float& sinval )
|
||||
constructs polygon that represents elliptic arc.
|
||||
*/
|
||||
void ellipse2Poly( Point center, Size axes, int angle,
|
||||
int arcStart, int arcEnd,
|
||||
int delta, CV_OUT std::vector<Point>& pts )
|
||||
{
|
||||
std::vector<Point2d> _pts;
|
||||
ellipse2Poly(Point2d(center.x, center.y), Size2d(axes.width, axes.height), angle,
|
||||
arcStart, arcEnd, delta, _pts);
|
||||
Point prevPt(INT_MIN, INT_MIN);
|
||||
pts.resize(0);
|
||||
for (unsigned int i = 0; i < _pts.size(); ++i)
|
||||
{
|
||||
Point pt;
|
||||
pt.x = cvRound(_pts[i].x);
|
||||
pt.y = cvRound(_pts[i].y);
|
||||
if (pt != prevPt) {
|
||||
pts.push_back(pt);
|
||||
prevPt = pt;
|
||||
}
|
||||
}
|
||||
|
||||
// If there are no points, it's a zero-size polygon
|
||||
if (pts.size() == 1) {
|
||||
pts.assign(2, center);
|
||||
}
|
||||
}
|
||||
|
||||
void ellipse2Poly( Point2d center, Size2d axes, int angle,
|
||||
int arc_start, int arc_end,
|
||||
int delta, std::vector<Point>& pts )
|
||||
int delta, std::vector<Point2d>& pts )
|
||||
{
|
||||
CV_INSTRUMENT_REGION()
|
||||
|
||||
float alpha, beta;
|
||||
double size_a = axes.width, size_b = axes.height;
|
||||
double cx = center.x, cy = center.y;
|
||||
Point prevPt(INT_MIN,INT_MIN);
|
||||
int i;
|
||||
|
||||
while( angle < 0 )
|
||||
@ -972,15 +1003,12 @@ void ellipse2Poly( Point center, Size axes, int angle,
|
||||
if( angle < 0 )
|
||||
angle += 360;
|
||||
|
||||
x = size_a * SinTable[450-angle];
|
||||
y = size_b * SinTable[angle];
|
||||
Point pt;
|
||||
pt.x = cvRound( cx + x * alpha - y * beta );
|
||||
pt.y = cvRound( cy + x * beta + y * alpha );
|
||||
if( pt != prevPt ){
|
||||
pts.push_back(pt);
|
||||
prevPt = pt;
|
||||
}
|
||||
x = axes.width * SinTable[450-angle];
|
||||
y = axes.height * SinTable[angle];
|
||||
Point2d pt;
|
||||
pt.x = center.x + x * alpha - y * beta;
|
||||
pt.y = center.y + x * beta + y * alpha;
|
||||
pts.push_back(pt);
|
||||
}
|
||||
|
||||
// If there are no points, it's a zero-size polygon
|
||||
@ -991,16 +1019,37 @@ void ellipse2Poly( Point center, Size axes, int angle,
|
||||
|
||||
|
||||
static void
|
||||
EllipseEx( Mat& img, Point center, Size axes,
|
||||
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 = (std::max(axes.width,axes.height)+(XY_ONE>>1))>>XY_SHIFT;
|
||||
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<Point> v;
|
||||
ellipse2Poly( center, axes, angle, arc_start, arc_end, delta, v );
|
||||
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 );
|
||||
@ -1039,23 +1088,24 @@ EllipseEx( Mat& img, Point center, Size axes,
|
||||
|
||||
/* filling convex polygon. v - array of vertices, ntps - number of points */
|
||||
static void
|
||||
FillConvexPoly( Mat& img, const Point* v, int npts, const void* color, int line_type, int shift )
|
||||
FillConvexPoly( Mat& img, const Point2l* v, int npts, const void* color, int line_type, int shift )
|
||||
{
|
||||
struct
|
||||
{
|
||||
int idx, di;
|
||||
int x, dx, ye;
|
||||
int64 x, dx;
|
||||
int ye;
|
||||
}
|
||||
edge[2];
|
||||
|
||||
int delta = shift ? 1 << (shift - 1) : 0;
|
||||
int i, y, imin = 0, left = 0, right = 1, x1, x2;
|
||||
int delta = 1 << shift >> 1;
|
||||
int i, y, imin = 0, left = 0, right = 1;
|
||||
int edges = npts;
|
||||
int xmin, xmax, ymin, ymax;
|
||||
int64 xmin, xmax, ymin, ymax;
|
||||
uchar* ptr = img.ptr();
|
||||
Size size = img.size();
|
||||
int pix_size = (int)img.elemSize();
|
||||
Point p0;
|
||||
Point2l p0;
|
||||
int delta1, delta2;
|
||||
|
||||
if( line_type < CV_AA )
|
||||
@ -1073,7 +1123,7 @@ FillConvexPoly( Mat& img, const Point* v, int npts, const void* color, int line_
|
||||
|
||||
for( i = 0; i < npts; i++ )
|
||||
{
|
||||
Point p = v[i];
|
||||
Point2l p = v[i];
|
||||
if( p.y < ymin )
|
||||
{
|
||||
ymin = p.y;
|
||||
@ -1092,10 +1142,10 @@ FillConvexPoly( Mat& img, const Point* v, int npts, const void* color, int line_
|
||||
if( shift == 0 )
|
||||
{
|
||||
Point pt0, pt1;
|
||||
pt0.x = p0.x >> XY_SHIFT;
|
||||
pt0.y = p0.y >> XY_SHIFT;
|
||||
pt1.x = p.x >> XY_SHIFT;
|
||||
pt1.y = p.y >> XY_SHIFT;
|
||||
pt0.x = (int)(p0.x >> XY_SHIFT);
|
||||
pt0.y = (int)(p0.y >> XY_SHIFT);
|
||||
pt1.x = (int)(p.x >> XY_SHIFT);
|
||||
pt1.y = (int)(p.y >> XY_SHIFT);
|
||||
Line( img, pt0, pt1, color, line_type );
|
||||
}
|
||||
else
|
||||
@ -1111,13 +1161,13 @@ FillConvexPoly( Mat& img, const Point* v, int npts, const void* color, int line_
|
||||
ymin = (ymin + delta) >> shift;
|
||||
ymax = (ymax + delta) >> shift;
|
||||
|
||||
if( npts < 3 || xmax < 0 || ymax < 0 || xmin >= size.width || ymin >= size.height )
|
||||
if( npts < 3 || (int)xmax < 0 || (int)ymax < 0 || (int)xmin >= size.width || (int)ymin >= size.height )
|
||||
return;
|
||||
|
||||
ymax = MIN( ymax, size.height - 1 );
|
||||
edge[0].idx = edge[1].idx = imin;
|
||||
|
||||
edge[0].ye = edge[1].ye = y = ymin;
|
||||
edge[0].ye = edge[1].ye = y = (int)ymin;
|
||||
edge[0].di = 1;
|
||||
edge[1].di = npts - 1;
|
||||
|
||||
@ -1125,18 +1175,19 @@ FillConvexPoly( Mat& img, const Point* v, int npts, const void* color, int line_
|
||||
|
||||
do
|
||||
{
|
||||
if( line_type < CV_AA || y < ymax || y == ymin )
|
||||
if( line_type < CV_AA || y < (int)ymax || y == (int)ymin )
|
||||
{
|
||||
for( i = 0; i < 2; i++ )
|
||||
{
|
||||
if( y >= edge[i].ye )
|
||||
{
|
||||
int idx = edge[i].idx, di = edge[i].di;
|
||||
int xs = 0, xe, ye, ty = 0;
|
||||
int64 xs = 0, xe;
|
||||
int ty = 0;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
ty = (v[idx].y + delta) >> shift;
|
||||
ty = (int)((v[idx].y + delta) >> shift);
|
||||
if( ty > y || edges == 0 )
|
||||
break;
|
||||
xs = v[idx].x;
|
||||
@ -1145,16 +1196,15 @@ FillConvexPoly( Mat& img, const Point* v, int npts, const void* color, int line_
|
||||
edges--;
|
||||
}
|
||||
|
||||
ye = ty;
|
||||
xs <<= XY_SHIFT - shift;
|
||||
xe = v[idx].x << (XY_SHIFT - shift);
|
||||
|
||||
/* no more edges */
|
||||
if( y >= ye )
|
||||
if( y >= ty)
|
||||
return;
|
||||
|
||||
edge[i].ye = ye;
|
||||
edge[i].dx = ((xe - xs)*2 + (ye - y)) / (2 * (ye - y));
|
||||
edge[i].ye = ty;
|
||||
edge[i].dx = ((xe - xs)*2 + (ty - y)) / (2 * (ty - y));
|
||||
edge[i].x = xs;
|
||||
edge[i].idx = idx;
|
||||
}
|
||||
@ -1167,13 +1217,10 @@ FillConvexPoly( Mat& img, const Point* v, int npts, const void* color, int line_
|
||||
right ^= 1;
|
||||
}
|
||||
|
||||
x1 = edge[left].x;
|
||||
x2 = edge[right].x;
|
||||
|
||||
if( y >= 0 )
|
||||
{
|
||||
int xx1 = (x1 + delta1) >> XY_SHIFT;
|
||||
int xx2 = (x2 + delta2) >> XY_SHIFT;
|
||||
int xx1 = (int)((edge[left].x + delta1) >> XY_SHIFT);
|
||||
int xx2 = (int)((edge[right].x + delta2) >> XY_SHIFT);
|
||||
|
||||
if( xx2 >= 0 && xx1 < size.width )
|
||||
{
|
||||
@ -1185,25 +1232,22 @@ FillConvexPoly( Mat& img, const Point* v, int npts, const void* color, int line_
|
||||
}
|
||||
}
|
||||
|
||||
x1 += edge[left].dx;
|
||||
x2 += edge[right].dx;
|
||||
|
||||
edge[left].x = x1;
|
||||
edge[right].x = x2;
|
||||
edge[left].x += edge[left].dx;
|
||||
edge[right].x += edge[right].dx;
|
||||
ptr += img.step;
|
||||
}
|
||||
while( ++y <= ymax );
|
||||
while( ++y <= (int)ymax );
|
||||
}
|
||||
|
||||
|
||||
/******** Arbitrary polygon **********/
|
||||
|
||||
static void
|
||||
CollectPolyEdges( Mat& img, const Point* v, int count, std::vector<PolyEdge>& edges,
|
||||
CollectPolyEdges( Mat& img, const Point2l* v, int count, std::vector<PolyEdge>& edges,
|
||||
const void* color, int line_type, int shift, Point offset )
|
||||
{
|
||||
int i, delta = offset.y + (shift ? 1 << (shift - 1) : 0);
|
||||
Point pt0 = v[count-1], pt1;
|
||||
int i, delta = offset.y + ((1 << shift) >> 1);
|
||||
Point2l pt0 = v[count-1], pt1;
|
||||
pt0.x = (pt0.x + offset.x) << (XY_SHIFT - shift);
|
||||
pt0.y = (pt0.y + delta) >> shift;
|
||||
|
||||
@ -1211,7 +1255,7 @@ CollectPolyEdges( Mat& img, const Point* v, int count, std::vector<PolyEdge>& ed
|
||||
|
||||
for( i = 0; i < count; i++, pt0 = pt1 )
|
||||
{
|
||||
Point t0, t1;
|
||||
Point2l t0, t1;
|
||||
PolyEdge edge;
|
||||
|
||||
pt1 = v[i];
|
||||
@ -1238,14 +1282,14 @@ CollectPolyEdges( Mat& img, const Point* v, int count, std::vector<PolyEdge>& ed
|
||||
|
||||
if( pt0.y < pt1.y )
|
||||
{
|
||||
edge.y0 = pt0.y;
|
||||
edge.y1 = pt1.y;
|
||||
edge.y0 = (int)(pt0.y);
|
||||
edge.y1 = (int)(pt1.y);
|
||||
edge.x = pt0.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
edge.y0 = pt1.y;
|
||||
edge.y1 = pt0.y;
|
||||
edge.y0 = (int)(pt1.y);
|
||||
edge.y1 = (int)(pt0.y);
|
||||
edge.x = pt1.x;
|
||||
}
|
||||
edge.dx = (pt1.x - pt0.x) / (pt1.y - pt0.y);
|
||||
@ -1271,7 +1315,8 @@ FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color )
|
||||
int i, y, total = (int)edges.size();
|
||||
Size size = img.size();
|
||||
PolyEdge* e;
|
||||
int y_max = INT_MIN, x_max = INT_MIN, y_min = INT_MAX, x_min = INT_MAX;
|
||||
int y_max = INT_MIN, y_min = INT_MAX;
|
||||
int64 x_max = 0xFFFFFFFFFFFFFFFF, x_min = 0x7FFFFFFFFFFFFFFF;
|
||||
int pix_size = (int)img.elemSize();
|
||||
|
||||
if( total < 2 )
|
||||
@ -1283,7 +1328,7 @@ FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color )
|
||||
assert( e1.y0 < e1.y1 );
|
||||
// Determine x-coordinate of the end of the edge.
|
||||
// (This is not necessary x-coordinate of any vertex in the array.)
|
||||
int x1 = e1.x + (e1.y1 - e1.y0) * e1.dx;
|
||||
int64 x1 = e1.x + (e1.y1 - e1.y0) * e1.dx;
|
||||
y_min = std::min( y_min, e1.y0 );
|
||||
y_max = std::max( y_max, e1.y1 );
|
||||
x_min = std::min( x_min, e1.x );
|
||||
@ -1292,7 +1337,7 @@ FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color )
|
||||
x_max = std::max( x_max, x1 );
|
||||
}
|
||||
|
||||
if( y_max < 0 || y_min >= size.height || x_max < 0 || x_min >= (size.width<<XY_SHIFT) )
|
||||
if( y_max < 0 || y_min >= size.height || x_max < 0 || x_min >= ((int64)size.width<<XY_SHIFT) )
|
||||
return;
|
||||
|
||||
std::sort( edges.begin(), edges.end(), CmpEdges() );
|
||||
@ -1348,19 +1393,18 @@ FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color )
|
||||
{
|
||||
// convert x's from fixed-point to image coordinates
|
||||
uchar *timg = img.ptr(y);
|
||||
int x1 = keep_prelast->x;
|
||||
int x2 = prelast->x;
|
||||
int x1, x2;
|
||||
|
||||
if( x1 > x2 )
|
||||
if (keep_prelast->x > prelast->x)
|
||||
{
|
||||
int t = x1;
|
||||
|
||||
x1 = x2;
|
||||
x2 = t;
|
||||
x1 = (int)((prelast->x + XY_ONE - 1) >> XY_SHIFT);
|
||||
x2 = (int)(keep_prelast->x >> XY_SHIFT);
|
||||
}
|
||||
else
|
||||
{
|
||||
x1 = (int)((keep_prelast->x + XY_ONE - 1) >> XY_SHIFT);
|
||||
x2 = (int)(prelast->x >> XY_SHIFT);
|
||||
}
|
||||
|
||||
x1 = (x1 + XY_ONE - 1) >> XY_SHIFT;
|
||||
x2 = x2 >> XY_SHIFT;
|
||||
|
||||
// clip and draw the line
|
||||
if( x1 < size.width && x2 >= 0 )
|
||||
@ -1560,7 +1604,7 @@ Circle( Mat& img, Point center, int radius, const void* color, int fill )
|
||||
|
||||
|
||||
static void
|
||||
ThickLine( Mat& img, Point p0, Point p1, const void* color,
|
||||
ThickLine( Mat& img, Point2l p0, Point2l p1, const void* color,
|
||||
int thickness, int line_type, int flags, int shift )
|
||||
{
|
||||
static const double INV_XY_ONE = 1./XY_ONE;
|
||||
@ -1590,7 +1634,7 @@ ThickLine( Mat& img, Point p0, Point p1, const void* color,
|
||||
}
|
||||
else
|
||||
{
|
||||
Point pt[4], dp = Point(0,0);
|
||||
Point2l pt[4], dp = Point2l(0,0);
|
||||
double dx = (p0.x - p1.x)*INV_XY_ONE, dy = (p1.y - p0.y)*INV_XY_ONE;
|
||||
double r = dx * dx + dy * dy;
|
||||
int i, oddThickness = thickness & 1;
|
||||
@ -1621,13 +1665,13 @@ ThickLine( Mat& img, Point p0, Point p1, const void* color,
|
||||
if( line_type < CV_AA )
|
||||
{
|
||||
Point center;
|
||||
center.x = (p0.x + (XY_ONE>>1)) >> XY_SHIFT;
|
||||
center.y = (p0.y + (XY_ONE>>1)) >> XY_SHIFT;
|
||||
center.x = (int)((p0.x + (XY_ONE>>1)) >> XY_SHIFT);
|
||||
center.y = (int)((p0.y + (XY_ONE>>1)) >> XY_SHIFT);
|
||||
Circle( img, center, (thickness + (XY_ONE>>1)) >> XY_SHIFT, color, 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
EllipseEx( img, p0, cvSize(thickness, thickness),
|
||||
EllipseEx( img, p0, Size2l(thickness, thickness),
|
||||
0, 0, 360, color, -1, line_type );
|
||||
}
|
||||
}
|
||||
@ -1638,7 +1682,7 @@ ThickLine( Mat& img, Point p0, Point p1, const void* color,
|
||||
|
||||
|
||||
static void
|
||||
PolyLine( Mat& img, const Point* v, int count, bool is_closed,
|
||||
PolyLine( Mat& img, const Point2l* v, int count, bool is_closed,
|
||||
const void* color, int thickness,
|
||||
int line_type, int shift )
|
||||
{
|
||||
@ -1647,13 +1691,13 @@ PolyLine( Mat& img, const Point* v, int count, bool is_closed,
|
||||
|
||||
int i = is_closed ? count - 1 : 0;
|
||||
int flags = 2 + !is_closed;
|
||||
Point p0;
|
||||
Point2l p0;
|
||||
CV_Assert( 0 <= shift && shift <= XY_SHIFT && thickness >= 0 );
|
||||
|
||||
p0 = v[i];
|
||||
for( i = !is_closed; i < count; i++ )
|
||||
{
|
||||
Point p = v[i];
|
||||
Point2l p = v[i];
|
||||
ThickLine( img, p0, p, color, thickness, line_type, flags, shift );
|
||||
p0 = p;
|
||||
flags = 2;
|
||||
@ -1784,7 +1828,7 @@ void rectangle( InputOutputArray _img, Point pt1, Point pt2,
|
||||
double buf[4];
|
||||
scalarToRawData(color, buf, img.type(), 0);
|
||||
|
||||
Point pt[4];
|
||||
Point2l pt[4];
|
||||
|
||||
pt[0] = pt1;
|
||||
pt[1].x = pt2.x;
|
||||
@ -1831,10 +1875,12 @@ void circle( InputOutputArray _img, Point center, int radius,
|
||||
|
||||
if( thickness > 1 || line_type != LINE_8 || shift > 0 )
|
||||
{
|
||||
center.x <<= XY_SHIFT - shift;
|
||||
center.y <<= XY_SHIFT - shift;
|
||||
radius <<= XY_SHIFT - shift;
|
||||
EllipseEx( img, center, Size(radius, radius),
|
||||
Point2l _center(center);
|
||||
int64 _radius(radius);
|
||||
_center.x <<= XY_SHIFT - shift;
|
||||
_center.y <<= XY_SHIFT - shift;
|
||||
_radius <<= XY_SHIFT - shift;
|
||||
EllipseEx( img, _center, Size2l(_radius, _radius),
|
||||
0, 0, 360, buf, thickness, line_type );
|
||||
}
|
||||
else
|
||||
@ -1862,12 +1908,14 @@ void ellipse( InputOutputArray _img, Point center, Size axes,
|
||||
int _angle = cvRound(angle);
|
||||
int _start_angle = cvRound(start_angle);
|
||||
int _end_angle = cvRound(end_angle);
|
||||
center.x <<= XY_SHIFT - shift;
|
||||
center.y <<= XY_SHIFT - shift;
|
||||
axes.width <<= XY_SHIFT - shift;
|
||||
axes.height <<= XY_SHIFT - shift;
|
||||
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,
|
||||
EllipseEx( img, _center, _axes, _angle, _start_angle,
|
||||
_end_angle, buf, thickness, line_type );
|
||||
}
|
||||
|
||||
@ -1888,10 +1936,14 @@ void ellipse(InputOutputArray _img, const RotatedRect& box, const Scalar& color,
|
||||
scalarToRawData(color, buf, img.type(), 0);
|
||||
|
||||
int _angle = cvRound(box.angle);
|
||||
Point center(cvRound(box.center.x*(1 << XY_SHIFT)),
|
||||
cvRound(box.center.y*(1 << XY_SHIFT)));
|
||||
Size axes(cvRound(box.size.width*(1 << (XY_SHIFT - 1))),
|
||||
cvRound(box.size.height*(1 << (XY_SHIFT - 1))));
|
||||
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 );
|
||||
}
|
||||
|
||||
@ -1909,7 +1961,8 @@ void fillConvexPoly( Mat& img, const Point* pts, int npts,
|
||||
double buf[4];
|
||||
CV_Assert( 0 <= shift && shift <= XY_SHIFT );
|
||||
scalarToRawData(color, buf, img.type(), 0);
|
||||
FillConvexPoly( img, pts, npts, buf, line_type, shift );
|
||||
std::vector<Point2l> _pts(pts, pts + npts);
|
||||
FillConvexPoly( img, _pts.data(), npts, buf, line_type, shift );
|
||||
}
|
||||
|
||||
|
||||
@ -1934,8 +1987,11 @@ void fillPoly( Mat& img, const Point** pts, const int* npts, int ncontours,
|
||||
total += npts[i];
|
||||
|
||||
edges.reserve( total + 1 );
|
||||
for( i = 0; i < ncontours; i++ )
|
||||
CollectPolyEdges( img, pts[i], npts[i], edges, buf, line_type, shift, offset );
|
||||
for (i = 0; i < ncontours; i++)
|
||||
{
|
||||
std::vector<Point2l> _pts(pts[i], pts[i] + npts[i]);
|
||||
CollectPolyEdges(img, _pts.data(), npts[i], edges, buf, line_type, shift, offset);
|
||||
}
|
||||
|
||||
FillEdgeCollection(img, edges, buf);
|
||||
}
|
||||
@ -1957,7 +2013,10 @@ void polylines( Mat& img, const Point* const* pts, const int* npts, int ncontour
|
||||
scalarToRawData( color, buf, img.type(), 0 );
|
||||
|
||||
for( int i = 0; i < ncontours; i++ )
|
||||
PolyLine( img, pts[i], npts[i], isClosed, buf, thickness, line_type, shift );
|
||||
{
|
||||
std::vector<Point2l> _pts(pts[i], pts[i]+npts[i]);
|
||||
PolyLine( img, _pts.data(), npts[i], isClosed, buf, thickness, line_type, shift );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2202,23 +2261,23 @@ void putText( InputOutputArray _img, const String& text, Point org,
|
||||
if( bottomLeftOrigin )
|
||||
vscale = -vscale;
|
||||
|
||||
int view_x = org.x << XY_SHIFT;
|
||||
int view_y = (org.y << XY_SHIFT) + base_line*vscale;
|
||||
std::vector<Point> pts;
|
||||
int64 view_x = (int64)org.x << XY_SHIFT;
|
||||
int64 view_y = ((int64)org.y << XY_SHIFT) + base_line*vscale;
|
||||
std::vector<Point2l> pts;
|
||||
pts.reserve(1 << 10);
|
||||
const char **faces = cv::g_HersheyGlyphs;
|
||||
|
||||
for( int i = 0; i < (int)text.size(); i++ )
|
||||
{
|
||||
int c = (uchar)text[i];
|
||||
Point p;
|
||||
Point2l p;
|
||||
|
||||
readCheck(c, i, text, fontFace);
|
||||
|
||||
const char* ptr = faces[ascii[(c-' ')+1]];
|
||||
p.x = (uchar)ptr[0] - 'R';
|
||||
p.y = (uchar)ptr[1] - 'R';
|
||||
int dx = p.y*hscale;
|
||||
int64 dx = p.y*hscale;
|
||||
view_x -= p.x*hscale;
|
||||
pts.resize(0);
|
||||
|
||||
@ -2237,7 +2296,7 @@ void putText( InputOutputArray _img, const String& text, Point org,
|
||||
p.x = (uchar)ptr[0] - 'R';
|
||||
p.y = (uchar)ptr[1] - 'R';
|
||||
ptr += 2;
|
||||
pts.push_back(Point(p.x*hscale + view_x, p.y*vscale + view_y));
|
||||
pts.push_back(Point2l(p.x*hscale + view_x, p.y*vscale + view_y));
|
||||
}
|
||||
}
|
||||
view_x += dx;
|
||||
@ -2474,7 +2533,7 @@ cvDrawContours( void* _img, CvSeq* contour,
|
||||
CvSeq *contour0 = contour, *h_next = 0;
|
||||
CvTreeNodeIterator iterator;
|
||||
std::vector<cv::PolyEdge> edges;
|
||||
std::vector<cv::Point> pts;
|
||||
std::vector<cv::Point2l> pts;
|
||||
cv::Scalar externalColor = _externalColor, holeColor = _holeColor;
|
||||
cv::Mat img = cv::cvarrToMat(_img);
|
||||
cv::Point offset = _offset;
|
||||
@ -2598,7 +2657,7 @@ cvEllipse2Poly( CvPoint center, CvSize axes, int angle,
|
||||
int arc_start, int arc_end, CvPoint* _pts, int delta )
|
||||
{
|
||||
std::vector<cv::Point> pts;
|
||||
cv::ellipse2Poly( center, axes, angle, arc_start, arc_end, delta, pts );
|
||||
cv::ellipse2Poly( Point(center), Size(axes), angle, arc_start, arc_end, delta, pts );
|
||||
memcpy( _pts, &pts[0], pts.size()*sizeof(_pts[0]) );
|
||||
return (int)pts.size();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user