Skip to content

Commit 93a882d

Browse files
committed
Fix fillPoly drawing over boundaries
1 parent f503890 commit 93a882d

File tree

2 files changed

+78
-18
lines changed

2 files changed

+78
-18
lines changed

modules/imgproc/src/drawing.cpp

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ CollectPolyEdges( Mat& img, const Point2l* v, int npts,
6464
int shift, Point offset=Point() );
6565

6666
static void
67-
FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color, int line_type);
67+
FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color );
6868

6969
static void
7070
PolyLine( Mat& img, const Point2l* v, int npts, bool closed,
@@ -1051,7 +1051,7 @@ EllipseEx( Mat& img, Point2l center, Size2l axes,
10511051
v.push_back(center);
10521052
std::vector<PolyEdge> edges;
10531053
CollectPolyEdges( img, &v[0], (int)v.size(), edges, color, line_type, XY_SHIFT );
1054-
FillEdgeCollection( img, edges, color, line_type );
1054+
FillEdgeCollection( img, edges, color );
10551055
}
10561056
}
10571057

@@ -1299,15 +1299,11 @@ CollectPolyEdges( Mat& img, const Point2l* v, int count, std::vector<PolyEdge>&
12991299
if (t0.y != t1.y)
13001300
{
13011301
pt0c.y = t0.y; pt1c.y = t1.y;
1302-
pt0c.x = (int64)(t0.x) << XY_SHIFT;
1303-
pt1c.x = (int64)(t1.x) << XY_SHIFT;
13041302
}
13051303
}
1306-
else
1307-
{
1308-
pt0c.x += XY_ONE >> 1;
1309-
pt1c.x += XY_ONE >> 1;
1310-
}
1304+
1305+
pt0c.x = (int64)(t0.x) << XY_SHIFT;
1306+
pt1c.x = (int64)(t1.x) << XY_SHIFT;
13111307
}
13121308
else
13131309
{
@@ -1349,7 +1345,7 @@ struct CmpEdges
13491345
/**************** helper macros and functions for sequence/contour processing ***********/
13501346

13511347
static void
1352-
FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color, int line_type)
1348+
FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color )
13531349
{
13541350
PolyEdge tmp;
13551351
int i, y, total = (int)edges.size();
@@ -1358,12 +1354,7 @@ FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color, i
13581354
int y_max = INT_MIN, y_min = INT_MAX;
13591355
int64 x_max = 0xFFFFFFFFFFFFFFFF, x_min = 0x7FFFFFFFFFFFFFFF;
13601356
int pix_size = (int)img.elemSize();
1361-
int delta;
1362-
1363-
if (line_type < cv::LINE_AA)
1364-
delta = 0;
1365-
else
1366-
delta = XY_ONE - 1;
1357+
int delta = XY_ONE - 1;
13671358

13681359
if( total < 2 )
13691360
return;
@@ -2051,7 +2042,7 @@ void fillPoly( InputOutputArray _img, const Point** pts, const int* npts, int nc
20512042
}
20522043
}
20532044

2054-
FillEdgeCollection(img, edges, buf, line_type);
2045+
FillEdgeCollection(img, edges, buf);
20552046
}
20562047

20572048
void polylines( InputOutputArray _img, const Point* const* pts, const int* npts, int ncontours, bool isClosed,
@@ -2690,7 +2681,7 @@ cvDrawContours( void* _img, CvSeq* contour,
26902681
}
26912682

26922683
if( thickness < 0 )
2693-
cv::FillEdgeCollection( img, edges, ext_buf, line_type);
2684+
cv::FillEdgeCollection( img, edges, ext_buf );
26942685

26952686
if( h_next && contour0 )
26962687
contour0->h_next = h_next;

modules/imgproc/test/test_drawing.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,75 @@ TEST(Drawing, fillpoly_circle)
680680
EXPECT_LT(diff_fp3, 1.);
681681
}
682682

683+
TEST(Drawing, fillpoly_contours)
684+
{
685+
const int imgSize = 50;
686+
const int type = CV_8UC1;
687+
const int shift = 0;
688+
const Scalar cl = Scalar::all(255);
689+
const cv::LineTypes lineType = LINE_8;
690+
691+
// check that contours of fillPoly and polylines match
692+
{
693+
cv::Mat img(imgSize, imgSize, type);
694+
img = 0;
695+
std::vector<std::vector<cv::Point>> polygonPoints{
696+
{ {44, 27}, {7, 37}, {7, 19}, {38, 19} }
697+
};
698+
cv::fillPoly(img, polygonPoints, cl, lineType, shift);
699+
cv::polylines(img, polygonPoints, true, 0, 1, lineType, shift);
700+
701+
{
702+
cv::Mat labelImage(img.size(), CV_32S);
703+
int labels = cv::connectedComponents(img, labelImage, 4);
704+
EXPECT_EQ(2, labels) << "filling went over the border";
705+
}
706+
}
707+
708+
// check that line generated with fillPoly and polylines match
709+
{
710+
cv::Mat img1(imgSize, imgSize, type), img2(imgSize, imgSize, type);
711+
img1 = 0;
712+
img2 = 0;
713+
std::vector<std::vector<cv::Point>> polygonPoints{
714+
{ {44, 27}, {38, 19} }
715+
};
716+
cv::fillPoly(img1, polygonPoints, cl, lineType, shift);
717+
cv::polylines(img2, polygonPoints, true, cl, 1, lineType, shift);
718+
EXPECT_MAT_N_DIFF(img1, img2, 0);
719+
}
720+
}
721+
722+
TEST(Drawing, fillpoly_match_lines)
723+
{
724+
const int imgSize = 49;
725+
const int type = CV_8UC1;
726+
const int shift = 0;
727+
const Scalar cl = Scalar::all(255);
728+
const cv::LineTypes lineType = LINE_8;
729+
cv::Mat img1(imgSize, imgSize, type), img2(imgSize, imgSize, type);
730+
for (int x1 = 0; x1 < imgSize; x1 += imgSize / 2)
731+
{
732+
for (int y1 = 0; y1 < imgSize; y1 += imgSize / 2)
733+
{
734+
for (int x2 = 0; x2 < imgSize; x2++)
735+
{
736+
for (int y2 = 0; y2 < imgSize; y2++)
737+
{
738+
img1 = 0;
739+
img2 = 0;
740+
std::vector<std::vector<cv::Point>> polygonPoints{
741+
{ {x1, y1}, {x2, y2} }
742+
};
743+
cv::fillPoly(img1, polygonPoints, cl, lineType, shift);
744+
cv::polylines(img2, polygonPoints, true, cl, 1, lineType, shift);
745+
EXPECT_MAT_N_DIFF(img1, img2, 0);
746+
}
747+
}
748+
}
749+
}
750+
}
751+
683752
TEST(Drawing, fillpoly_fully)
684753
{
685754
unsigned imageWidth = 256;

0 commit comments

Comments
 (0)