Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Antialiased polygon fill doesn't respect area borders

I want to draw a quadrilateral which vertices doesn't coincide with pixel boundaries. The simplest case is a square with all 4 vertices located exactly in the middle of pixels. Here is my code doing it:

cv::Point2f A(5.5,2.5), B(6.5, 2.5), C(6.5,3.5), D(5.5, 3.5);
cv::Point points[4] = {A, B, C, D};
const cv::Point *contours[1] = {points};
int lengths[1] = {4};

cv::Mat p(10, 10, CV_8U, cv::Scalar(0));
cv::fillPoly(p, contours, lengths, 1, cv::Scalar(100), CV_AA, 0);
std::cout << p << std::endl;

In the output image I expected 4 pixels with the value of 25%, i.e. total value of 100 (because the area of the square is exactly 1). But the real output looks like this:

[  0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,  19, 100,  22,   0,   0;
   0,   0,   0,   0,   0,  36, 100,  40,   0,   0;
   0,   0,   0,   0,   0,  20,  83,  22,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0,   0]

Is this a bug in the library or do I use it in a wrong way? And how to draw a simple 1x1 antialiased square?

Antialiased polygon fill doesn't respect area borders

I want to draw a quadrilateral which vertices doesn't coincide with pixel boundaries. The simplest case is a square with all 4 vertices located exactly in the middle of pixels. Here is my code doing it:

cv::Point2f A(5.5,2.5), B(6.5, 2.5), C(6.5,3.5), D(5.5, 3.5);
cv::Point points[4] = {A, B, C, D};
const cv::Point *contours[1] = {points};
int lengths[1] = {4};

cv::Mat p(10, 10, CV_8U, cv::Scalar(0));
cv::fillPoly(p, contours, lengths, 1, cv::Scalar(100), CV_AA, 0);
std::cout << p << std::endl;

In the output image I expected 4 pixels with the value of 25%, i.e. total value of 100 (because the area of the square is exactly 1). But the real output looks like this:

[  0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,  19, 100,  22,   0,   0;
   0,   0,   0,   0,   0,  36, 100,  40,   0,   0;
   0,   0,   0,   0,   0,  20,  83,  22,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0,   0]

Is this a bug in the library or do I use it in a wrong way? And how to draw a simple 1x1 antialiased square?

UPDATE: After removing CV_AA flag the output of

 cv::fillPoly(p, contours, lengths, 1, cv::Scalar(100));

looks like this:

[  0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0, 100,   0,   0,   0;
   0,   0,   0,   0,   0,   0, 100,   0,   0,   0;
   0,   0,   0,   0,   0,   0, 100,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0,   0]