mirror of
https://github.com/opencv/opencv.git
synced 2024-12-04 00:39:11 +08:00
Fix fillPoly drawing over boundaries
This commit is contained in:
parent
f503890c2b
commit
93a882d2e2
@ -64,7 +64,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, int line_type);
|
||||
FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color );
|
||||
|
||||
static void
|
||||
PolyLine( Mat& img, const Point2l* v, int npts, bool closed,
|
||||
@ -1051,7 +1051,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, line_type );
|
||||
FillEdgeCollection( img, edges, color );
|
||||
}
|
||||
}
|
||||
|
||||
@ -1299,15 +1299,11 @@ CollectPolyEdges( Mat& img, const Point2l* v, int count, std::vector<PolyEdge>&
|
||||
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;
|
||||
}
|
||||
|
||||
pt0c.x = (int64)(t0.x) << XY_SHIFT;
|
||||
pt1c.x = (int64)(t1.x) << XY_SHIFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1349,7 +1345,7 @@ struct CmpEdges
|
||||
/**************** helper macros and functions for sequence/contour processing ***********/
|
||||
|
||||
static void
|
||||
FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color, int line_type)
|
||||
FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color )
|
||||
{
|
||||
PolyEdge tmp;
|
||||
int i, y, total = (int)edges.size();
|
||||
@ -1358,12 +1354,7 @@ FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color, i
|
||||
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::LINE_AA)
|
||||
delta = 0;
|
||||
else
|
||||
delta = XY_ONE - 1;
|
||||
int delta = XY_ONE - 1;
|
||||
|
||||
if( total < 2 )
|
||||
return;
|
||||
@ -2051,7 +2042,7 @@ void fillPoly( InputOutputArray _img, const Point** pts, const int* npts, int nc
|
||||
}
|
||||
}
|
||||
|
||||
FillEdgeCollection(img, edges, buf, line_type);
|
||||
FillEdgeCollection(img, edges, buf);
|
||||
}
|
||||
|
||||
void polylines( InputOutputArray _img, const Point* const* pts, const int* npts, int ncontours, bool isClosed,
|
||||
@ -2690,7 +2681,7 @@ cvDrawContours( void* _img, CvSeq* contour,
|
||||
}
|
||||
|
||||
if( thickness < 0 )
|
||||
cv::FillEdgeCollection( img, edges, ext_buf, line_type);
|
||||
cv::FillEdgeCollection( img, edges, ext_buf );
|
||||
|
||||
if( h_next && contour0 )
|
||||
contour0->h_next = h_next;
|
||||
|
@ -680,6 +680,75 @@ TEST(Drawing, fillpoly_circle)
|
||||
EXPECT_LT(diff_fp3, 1.);
|
||||
}
|
||||
|
||||
TEST(Drawing, fillpoly_contours)
|
||||
{
|
||||
const int imgSize = 50;
|
||||
const int type = CV_8UC1;
|
||||
const int shift = 0;
|
||||
const Scalar cl = Scalar::all(255);
|
||||
const cv::LineTypes lineType = LINE_8;
|
||||
|
||||
// check that contours of fillPoly and polylines match
|
||||
{
|
||||
cv::Mat img(imgSize, imgSize, type);
|
||||
img = 0;
|
||||
std::vector<std::vector<cv::Point>> polygonPoints{
|
||||
{ {44, 27}, {7, 37}, {7, 19}, {38, 19} }
|
||||
};
|
||||
cv::fillPoly(img, polygonPoints, cl, lineType, shift);
|
||||
cv::polylines(img, polygonPoints, true, 0, 1, lineType, shift);
|
||||
|
||||
{
|
||||
cv::Mat labelImage(img.size(), CV_32S);
|
||||
int labels = cv::connectedComponents(img, labelImage, 4);
|
||||
EXPECT_EQ(2, labels) << "filling went over the border";
|
||||
}
|
||||
}
|
||||
|
||||
// check that line generated with fillPoly and polylines match
|
||||
{
|
||||
cv::Mat img1(imgSize, imgSize, type), img2(imgSize, imgSize, type);
|
||||
img1 = 0;
|
||||
img2 = 0;
|
||||
std::vector<std::vector<cv::Point>> polygonPoints{
|
||||
{ {44, 27}, {38, 19} }
|
||||
};
|
||||
cv::fillPoly(img1, polygonPoints, cl, lineType, shift);
|
||||
cv::polylines(img2, polygonPoints, true, cl, 1, lineType, shift);
|
||||
EXPECT_MAT_N_DIFF(img1, img2, 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Drawing, fillpoly_match_lines)
|
||||
{
|
||||
const int imgSize = 49;
|
||||
const int type = CV_8UC1;
|
||||
const int shift = 0;
|
||||
const Scalar cl = Scalar::all(255);
|
||||
const cv::LineTypes lineType = LINE_8;
|
||||
cv::Mat img1(imgSize, imgSize, type), img2(imgSize, imgSize, type);
|
||||
for (int x1 = 0; x1 < imgSize; x1 += imgSize / 2)
|
||||
{
|
||||
for (int y1 = 0; y1 < imgSize; y1 += imgSize / 2)
|
||||
{
|
||||
for (int x2 = 0; x2 < imgSize; x2++)
|
||||
{
|
||||
for (int y2 = 0; y2 < imgSize; y2++)
|
||||
{
|
||||
img1 = 0;
|
||||
img2 = 0;
|
||||
std::vector<std::vector<cv::Point>> polygonPoints{
|
||||
{ {x1, y1}, {x2, y2} }
|
||||
};
|
||||
cv::fillPoly(img1, polygonPoints, cl, lineType, shift);
|
||||
cv::polylines(img2, polygonPoints, true, cl, 1, lineType, shift);
|
||||
EXPECT_MAT_N_DIFF(img1, img2, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Drawing, fillpoly_fully)
|
||||
{
|
||||
unsigned imageWidth = 256;
|
||||
|
Loading…
Reference in New Issue
Block a user