mirror of
https://github.com/opencv/opencv.git
synced 2026-07-29 23:33:05 +04:00
Fix occuring artifacts in fillPoly
This commit is contained in:
@@ -63,7 +63,7 @@ CollectPolyEdges( Mat& img, const Point2l* v, int npts,
|
||||
int shift, Point offset=Point() );
|
||||
|
||||
static void
|
||||
FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color );
|
||||
FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color, int line_type);
|
||||
|
||||
static void
|
||||
PolyLine( Mat& img, const Point2l* v, int npts, bool closed,
|
||||
@@ -1031,7 +1031,7 @@ EllipseEx( Mat& img, Point2l center, Size2l axes,
|
||||
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 );
|
||||
FillEdgeCollection( img, edges, color, line_type );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1259,37 +1259,60 @@ CollectPolyEdges( Mat& img, const Point2l* v, int count, std::vector<PolyEdge>&
|
||||
pt1.x = (pt1.x + offset.x) << (XY_SHIFT - shift);
|
||||
pt1.y = (pt1.y + delta) >> shift;
|
||||
|
||||
if( line_type < CV_AA )
|
||||
Point2l pt0c(pt0), pt1c(pt1);
|
||||
|
||||
if (line_type < CV_AA)
|
||||
{
|
||||
t0.y = pt0.y; t1.y = pt1.y;
|
||||
t0.x = (pt0.x + (XY_ONE >> 1)) >> XY_SHIFT;
|
||||
t1.x = (pt1.x + (XY_ONE >> 1)) >> XY_SHIFT;
|
||||
Line( img, t0, t1, color, line_type );
|
||||
Line(img, t0, t1, color, line_type);
|
||||
|
||||
// use clipped endpoints to create a more accurate PolyEdge
|
||||
if ((unsigned)t0.x >= (unsigned)(img.cols) ||
|
||||
(unsigned)t1.x >= (unsigned)(img.cols) ||
|
||||
(unsigned)t0.y >= (unsigned)(img.rows) ||
|
||||
(unsigned)t1.y >= (unsigned)(img.rows))
|
||||
{
|
||||
clipLine(img.size(), t0, t1);
|
||||
|
||||
if (t0.y != t1.y)
|
||||
{
|
||||
pt0c.y = t0.y; pt1c.y = t1.y;
|
||||
pt0c.x = (int64)(t0.x) << XY_SHIFT;
|
||||
pt1c.x = (int64)(t1.x) << XY_SHIFT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pt0c.x += XY_ONE >> 1;
|
||||
pt1c.x += XY_ONE >> 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
t0.x = pt0.x; t1.x = pt1.x;
|
||||
t0.y = pt0.y << XY_SHIFT;
|
||||
t1.y = pt1.y << XY_SHIFT;
|
||||
LineAA( img, t0, t1, color );
|
||||
LineAA(img, t0, t1, color);
|
||||
}
|
||||
|
||||
if( pt0.y == pt1.y )
|
||||
if (pt0.y == pt1.y)
|
||||
continue;
|
||||
|
||||
if( pt0.y < pt1.y )
|
||||
edge.dx = (pt1c.x - pt0c.x) / (pt1c.y - pt0c.y);
|
||||
if (pt0.y < pt1.y)
|
||||
{
|
||||
edge.y0 = (int)(pt0.y);
|
||||
edge.y1 = (int)(pt1.y);
|
||||
edge.x = pt0.x;
|
||||
edge.x = pt0c.x + (pt0.y - pt0c.y) * edge.dx; // correct starting point for clipped lines
|
||||
}
|
||||
else
|
||||
{
|
||||
edge.y0 = (int)(pt1.y);
|
||||
edge.y1 = (int)(pt0.y);
|
||||
edge.x = pt1.x;
|
||||
edge.x = pt1c.x + (pt1.y - pt1c.y) * edge.dx; // correct starting point for clipped lines
|
||||
}
|
||||
edge.dx = (pt1.x - pt0.x) / (pt1.y - pt0.y);
|
||||
edges.push_back(edge);
|
||||
}
|
||||
}
|
||||
@@ -1306,7 +1329,7 @@ struct CmpEdges
|
||||
/**************** helper macros and functions for sequence/contour processing ***********/
|
||||
|
||||
static void
|
||||
FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color )
|
||||
FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color, int line_type)
|
||||
{
|
||||
PolyEdge tmp;
|
||||
int i, y, total = (int)edges.size();
|
||||
@@ -1315,6 +1338,12 @@ FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color )
|
||||
int y_max = INT_MIN, y_min = INT_MAX;
|
||||
int64 x_max = 0xFFFFFFFFFFFFFFFF, x_min = 0x7FFFFFFFFFFFFFFF;
|
||||
int pix_size = (int)img.elemSize();
|
||||
int delta;
|
||||
|
||||
if (line_type < CV_AA)
|
||||
delta = 0;
|
||||
else
|
||||
delta = XY_ONE - 1;
|
||||
|
||||
if( total < 2 )
|
||||
return;
|
||||
@@ -1394,12 +1423,12 @@ FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color )
|
||||
|
||||
if (keep_prelast->x > prelast->x)
|
||||
{
|
||||
x1 = (int)((prelast->x + XY_ONE - 1) >> XY_SHIFT);
|
||||
x1 = (int)((prelast->x + delta) >> XY_SHIFT);
|
||||
x2 = (int)(keep_prelast->x >> XY_SHIFT);
|
||||
}
|
||||
else
|
||||
{
|
||||
x1 = (int)((keep_prelast->x + XY_ONE - 1) >> XY_SHIFT);
|
||||
x1 = (int)((keep_prelast->x + delta) >> XY_SHIFT);
|
||||
x2 = (int)(prelast->x >> XY_SHIFT);
|
||||
}
|
||||
|
||||
@@ -1995,7 +2024,7 @@ void fillPoly( Mat& img, const Point** pts, const int* npts, int ncontours,
|
||||
CollectPolyEdges(img, _pts.data(), npts[i], edges, buf, line_type, shift, offset);
|
||||
}
|
||||
|
||||
FillEdgeCollection(img, edges, buf);
|
||||
FillEdgeCollection(img, edges, buf, line_type);
|
||||
}
|
||||
|
||||
|
||||
@@ -2654,7 +2683,7 @@ cvDrawContours( void* _img, CvSeq* contour,
|
||||
}
|
||||
|
||||
if( thickness < 0 )
|
||||
cv::FillEdgeCollection( img, edges, ext_buf );
|
||||
cv::FillEdgeCollection( img, edges, ext_buf, line_type);
|
||||
|
||||
if( h_next && contour0 )
|
||||
contour0->h_next = h_next;
|
||||
|
||||
Reference in New Issue
Block a user