mirror of
https://github.com/opencv/opencv.git
synced 2025-01-18 22:44:02 +08:00
Merge pull request #16495 from vpisarev:drawing_aa_border_fix
* fixed antialiased line rendering to process image border correctly * fixed warning on Windows * imgproc(test): circle drawing regression
This commit is contained in:
parent
4e4dfffe06
commit
e50acb923e
@ -308,7 +308,7 @@ LineAA( Mat& img, Point2l pt1, Point2l pt2, const void* color )
|
||||
int nch = img.channels();
|
||||
uchar* ptr = img.ptr();
|
||||
size_t step = img.step;
|
||||
Size2l size(img.size());
|
||||
Size2l size0(img.size()), size = size0;
|
||||
|
||||
if( !((nch == 1 || nch == 3 || nch == 4) && img.depth() == CV_8U) )
|
||||
{
|
||||
@ -316,15 +316,8 @@ LineAA( Mat& img, Point2l pt1, Point2l pt2, const void* color )
|
||||
return;
|
||||
}
|
||||
|
||||
pt1.x -= XY_ONE*2;
|
||||
pt1.y -= XY_ONE*2;
|
||||
pt2.x -= XY_ONE*2;
|
||||
pt2.y -= XY_ONE*2;
|
||||
ptr += img.step*2 + 2*nch;
|
||||
|
||||
size.width = ((size.width - 5) << XY_SHIFT) + 1;
|
||||
size.height = ((size.height - 5) << XY_SHIFT) + 1;
|
||||
|
||||
size.width <<= XY_SHIFT;
|
||||
size.height <<= XY_SHIFT;
|
||||
if( !clipLine( size, pt1, pt2 ))
|
||||
return;
|
||||
|
||||
@ -403,171 +396,160 @@ LineAA( Mat& img, Point2l pt1, Point2l pt2, const void* color )
|
||||
|
||||
if( nch == 3 )
|
||||
{
|
||||
#define ICV_PUT_POINT() \
|
||||
#define ICV_PUT_POINT(x, y) \
|
||||
{ \
|
||||
uchar* tptr = ptr + (x)*3 + (y)*step; \
|
||||
_cb = tptr[0]; \
|
||||
_cb += ((cb - _cb)*a + 127)>> 8;\
|
||||
_cb += ((cb - _cb)*a + 127)>> 8;\
|
||||
_cg = tptr[1]; \
|
||||
_cg += ((cg - _cg)*a + 127)>> 8;\
|
||||
_cg += ((cg - _cg)*a + 127)>> 8;\
|
||||
_cr = tptr[2]; \
|
||||
_cr += ((cr - _cr)*a + 127)>> 8;\
|
||||
_cr += ((cr - _cr)*a + 127)>> 8;\
|
||||
tptr[0] = (uchar)_cb; \
|
||||
tptr[1] = (uchar)_cg; \
|
||||
tptr[2] = (uchar)_cr; \
|
||||
}
|
||||
if( ax > ay )
|
||||
{
|
||||
ptr += (pt1.x >> XY_SHIFT) * 3;
|
||||
int x = (int)(pt1.x >> XY_SHIFT);
|
||||
|
||||
while( ecount >= 0 )
|
||||
for( ; ecount >= 0; x++, pt1.y += y_step, scount++, ecount-- )
|
||||
{
|
||||
uchar *tptr = ptr + ((pt1.y >> XY_SHIFT) - 1) * step;
|
||||
if( (unsigned)x >= (unsigned)size0.width )
|
||||
continue;
|
||||
int y = (int)((pt1.y >> XY_SHIFT) - 1);
|
||||
|
||||
int ep_corr = ep_table[(((scount >= 2) + 1) & (scount | 2)) * 3 +
|
||||
(((ecount >= 2) + 1) & (ecount | 2))];
|
||||
int a, dist = (pt1.y >> (XY_SHIFT - 5)) & 31;
|
||||
|
||||
a = (ep_corr * FilterTable[dist + 32] >> 8) & 0xff;
|
||||
ICV_PUT_POINT();
|
||||
ICV_PUT_POINT();
|
||||
if( (unsigned)y < (unsigned)size0.height )
|
||||
ICV_PUT_POINT(x, y)
|
||||
|
||||
tptr += step;
|
||||
a = (ep_corr * FilterTable[dist] >> 8) & 0xff;
|
||||
ICV_PUT_POINT();
|
||||
ICV_PUT_POINT();
|
||||
if( (unsigned)(y+1) < (unsigned)size0.height )
|
||||
ICV_PUT_POINT(x, y+1)
|
||||
|
||||
tptr += step;
|
||||
a = (ep_corr * FilterTable[63 - dist] >> 8) & 0xff;
|
||||
ICV_PUT_POINT();
|
||||
ICV_PUT_POINT();
|
||||
|
||||
pt1.y += y_step;
|
||||
ptr += 3;
|
||||
scount++;
|
||||
ecount--;
|
||||
if( (unsigned)(y+2) < (unsigned)size0.height )
|
||||
ICV_PUT_POINT(x, y+2)
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr += (pt1.y >> XY_SHIFT) * step;
|
||||
int y = (int)(pt1.y >> XY_SHIFT);
|
||||
|
||||
while( ecount >= 0 )
|
||||
for( ; ecount >= 0; y++, pt1.x += x_step, scount++, ecount-- )
|
||||
{
|
||||
uchar *tptr = ptr + ((pt1.x >> XY_SHIFT) - 1) * 3;
|
||||
|
||||
if( (unsigned)y >= (unsigned)size0.height )
|
||||
continue;
|
||||
int x = (int)((pt1.x >> XY_SHIFT) - 1);
|
||||
int ep_corr = ep_table[(((scount >= 2) + 1) & (scount | 2)) * 3 +
|
||||
(((ecount >= 2) + 1) & (ecount | 2))];
|
||||
int a, dist = (pt1.x >> (XY_SHIFT - 5)) & 31;
|
||||
|
||||
a = (ep_corr * FilterTable[dist + 32] >> 8) & 0xff;
|
||||
ICV_PUT_POINT();
|
||||
ICV_PUT_POINT();
|
||||
if( (unsigned)x < (unsigned)size0.width )
|
||||
ICV_PUT_POINT(x, y)
|
||||
|
||||
tptr += 3;
|
||||
a = (ep_corr * FilterTable[dist] >> 8) & 0xff;
|
||||
ICV_PUT_POINT();
|
||||
ICV_PUT_POINT();
|
||||
if( (unsigned)(x+1) < (unsigned)size0.width )
|
||||
ICV_PUT_POINT(x+1, y)
|
||||
|
||||
tptr += 3;
|
||||
a = (ep_corr * FilterTable[63 - dist] >> 8) & 0xff;
|
||||
ICV_PUT_POINT();
|
||||
ICV_PUT_POINT();
|
||||
|
||||
pt1.x += x_step;
|
||||
ptr += step;
|
||||
scount++;
|
||||
ecount--;
|
||||
if( (unsigned)(x+2) < (unsigned)size0.width )
|
||||
ICV_PUT_POINT(x+2, y)
|
||||
}
|
||||
}
|
||||
#undef ICV_PUT_POINT
|
||||
}
|
||||
else if(nch == 1)
|
||||
{
|
||||
#define ICV_PUT_POINT() \
|
||||
#define ICV_PUT_POINT(x, y) \
|
||||
{ \
|
||||
uchar* tptr = ptr + (x) + (y) * step; \
|
||||
_cb = tptr[0]; \
|
||||
_cb += ((cb - _cb)*a + 127)>> 8;\
|
||||
_cb += ((cb - _cb)*a + 127)>> 8;\
|
||||
tptr[0] = (uchar)_cb; \
|
||||
}
|
||||
|
||||
if( ax > ay )
|
||||
{
|
||||
ptr += (pt1.x >> XY_SHIFT);
|
||||
int x = (int)(pt1.x >> XY_SHIFT);
|
||||
|
||||
while( ecount >= 0 )
|
||||
for( ; ecount >= 0; x++, pt1.y += y_step, scount++, ecount-- )
|
||||
{
|
||||
uchar *tptr = ptr + ((pt1.y >> XY_SHIFT) - 1) * step;
|
||||
if( (unsigned)x >= (unsigned)size0.width )
|
||||
continue;
|
||||
int y = (int)((pt1.y >> XY_SHIFT) - 1);
|
||||
|
||||
int ep_corr = ep_table[(((scount >= 2) + 1) & (scount | 2)) * 3 +
|
||||
(((ecount >= 2) + 1) & (ecount | 2))];
|
||||
int a, dist = (pt1.y >> (XY_SHIFT - 5)) & 31;
|
||||
|
||||
a = (ep_corr * FilterTable[dist + 32] >> 8) & 0xff;
|
||||
ICV_PUT_POINT();
|
||||
ICV_PUT_POINT();
|
||||
if( (unsigned)y < (unsigned)size0.height )
|
||||
ICV_PUT_POINT(x, y)
|
||||
|
||||
tptr += step;
|
||||
a = (ep_corr * FilterTable[dist] >> 8) & 0xff;
|
||||
ICV_PUT_POINT();
|
||||
ICV_PUT_POINT();
|
||||
if( (unsigned)(y+1) < (unsigned)size0.height )
|
||||
ICV_PUT_POINT(x, y+1)
|
||||
|
||||
tptr += step;
|
||||
a = (ep_corr * FilterTable[63 - dist] >> 8) & 0xff;
|
||||
ICV_PUT_POINT();
|
||||
ICV_PUT_POINT();
|
||||
|
||||
pt1.y += y_step;
|
||||
ptr++;
|
||||
scount++;
|
||||
ecount--;
|
||||
if( (unsigned)(y+2) < (unsigned)size0.height )
|
||||
ICV_PUT_POINT(x, y+2)
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr += (pt1.y >> XY_SHIFT) * step;
|
||||
int y = (int)(pt1.y >> XY_SHIFT);
|
||||
|
||||
while( ecount >= 0 )
|
||||
for( ; ecount >= 0; y++, pt1.x += x_step, scount++, ecount-- )
|
||||
{
|
||||
uchar *tptr = ptr + ((pt1.x >> XY_SHIFT) - 1);
|
||||
|
||||
if( (unsigned)y >= (unsigned)size0.height )
|
||||
continue;
|
||||
int x = (int)((pt1.x >> XY_SHIFT) - 1);
|
||||
int ep_corr = ep_table[(((scount >= 2) + 1) & (scount | 2)) * 3 +
|
||||
(((ecount >= 2) + 1) & (ecount | 2))];
|
||||
int a, dist = (pt1.x >> (XY_SHIFT - 5)) & 31;
|
||||
|
||||
a = (ep_corr * FilterTable[dist + 32] >> 8) & 0xff;
|
||||
ICV_PUT_POINT();
|
||||
ICV_PUT_POINT();
|
||||
if( (unsigned)x < (unsigned)size0.width )
|
||||
ICV_PUT_POINT(x, y)
|
||||
|
||||
tptr++;
|
||||
a = (ep_corr * FilterTable[dist] >> 8) & 0xff;
|
||||
ICV_PUT_POINT();
|
||||
ICV_PUT_POINT();
|
||||
if( (unsigned)(x+1) < (unsigned)size0.width )
|
||||
ICV_PUT_POINT(x+1, y)
|
||||
|
||||
tptr++;
|
||||
a = (ep_corr * FilterTable[63 - dist] >> 8) & 0xff;
|
||||
ICV_PUT_POINT();
|
||||
ICV_PUT_POINT();
|
||||
|
||||
pt1.x += x_step;
|
||||
ptr += step;
|
||||
scount++;
|
||||
ecount--;
|
||||
if( (unsigned)(x+2) < (unsigned)size0.width )
|
||||
ICV_PUT_POINT(x+2, y)
|
||||
}
|
||||
}
|
||||
#undef ICV_PUT_POINT
|
||||
}
|
||||
else
|
||||
{
|
||||
#define ICV_PUT_POINT() \
|
||||
#define ICV_PUT_POINT(x, y) \
|
||||
{ \
|
||||
uchar* tptr = ptr + (x)*4 + (y)*step; \
|
||||
_cb = tptr[0]; \
|
||||
_cb += ((cb - _cb)*a + 127)>> 8;\
|
||||
_cb += ((cb - _cb)*a + 127)>> 8;\
|
||||
_cg = tptr[1]; \
|
||||
_cg += ((cg - _cg)*a + 127)>> 8;\
|
||||
_cg += ((cg - _cg)*a + 127)>> 8;\
|
||||
_cr = tptr[2]; \
|
||||
_cr += ((cr - _cr)*a + 127)>> 8;\
|
||||
_cr += ((cr - _cr)*a + 127)>> 8;\
|
||||
_ca = tptr[3]; \
|
||||
_ca += ((ca - _ca)*a + 127)>> 8;\
|
||||
_ca += ((ca - _ca)*a + 127)>> 8;\
|
||||
tptr[0] = (uchar)_cb; \
|
||||
tptr[1] = (uchar)_cg; \
|
||||
tptr[2] = (uchar)_cr; \
|
||||
@ -575,66 +557,55 @@ LineAA( Mat& img, Point2l pt1, Point2l pt2, const void* color )
|
||||
}
|
||||
if( ax > ay )
|
||||
{
|
||||
ptr += (pt1.x >> XY_SHIFT) * 4;
|
||||
int x = (int)(pt1.x >> XY_SHIFT);
|
||||
|
||||
while( ecount >= 0 )
|
||||
for( ; ecount >= 0; x++, pt1.y += y_step, scount++, ecount-- )
|
||||
{
|
||||
uchar *tptr = ptr + ((pt1.y >> XY_SHIFT) - 1) * step;
|
||||
if( (unsigned)x >= (unsigned)size0.width )
|
||||
continue;
|
||||
int y = (int)((pt1.y >> XY_SHIFT) - 1);
|
||||
|
||||
int ep_corr = ep_table[(((scount >= 2) + 1) & (scount | 2)) * 3 +
|
||||
(((ecount >= 2) + 1) & (ecount | 2))];
|
||||
int a, dist = (pt1.y >> (XY_SHIFT - 5)) & 31;
|
||||
|
||||
a = (ep_corr * FilterTable[dist + 32] >> 8) & 0xff;
|
||||
ICV_PUT_POINT();
|
||||
ICV_PUT_POINT();
|
||||
if( (unsigned)y < (unsigned)size0.height )
|
||||
ICV_PUT_POINT(x, y)
|
||||
|
||||
tptr += step;
|
||||
a = (ep_corr * FilterTable[dist] >> 8) & 0xff;
|
||||
ICV_PUT_POINT();
|
||||
ICV_PUT_POINT();
|
||||
if( (unsigned)(y+1) < (unsigned)size0.height )
|
||||
ICV_PUT_POINT(x, y+1)
|
||||
|
||||
tptr += step;
|
||||
a = (ep_corr * FilterTable[63 - dist] >> 8) & 0xff;
|
||||
ICV_PUT_POINT();
|
||||
ICV_PUT_POINT();
|
||||
|
||||
pt1.y += y_step;
|
||||
ptr += 4;
|
||||
scount++;
|
||||
ecount--;
|
||||
if( (unsigned)(y+2) < (unsigned)size0.height )
|
||||
ICV_PUT_POINT(x, y+2)
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr += (pt1.y >> XY_SHIFT) * step;
|
||||
int y = (int)(pt1.y >> XY_SHIFT);
|
||||
|
||||
while( ecount >= 0 )
|
||||
for( ; ecount >= 0; y++, pt1.x += x_step, scount++, ecount-- )
|
||||
{
|
||||
uchar *tptr = ptr + ((pt1.x >> XY_SHIFT) - 1) * 4;
|
||||
|
||||
if( (unsigned)y >= (unsigned)size0.height )
|
||||
continue;
|
||||
int x = (int)((pt1.x >> XY_SHIFT) - 1);
|
||||
int ep_corr = ep_table[(((scount >= 2) + 1) & (scount | 2)) * 3 +
|
||||
(((ecount >= 2) + 1) & (ecount | 2))];
|
||||
int a, dist = (pt1.x >> (XY_SHIFT - 5)) & 31;
|
||||
|
||||
a = (ep_corr * FilterTable[dist + 32] >> 8) & 0xff;
|
||||
ICV_PUT_POINT();
|
||||
ICV_PUT_POINT();
|
||||
if( (unsigned)x < (unsigned)size0.width )
|
||||
ICV_PUT_POINT(x, y)
|
||||
|
||||
tptr += 4;
|
||||
a = (ep_corr * FilterTable[dist] >> 8) & 0xff;
|
||||
ICV_PUT_POINT();
|
||||
ICV_PUT_POINT();
|
||||
if( (unsigned)(x+1) < (unsigned)size0.width )
|
||||
ICV_PUT_POINT(x+1, y)
|
||||
|
||||
tptr += 4;
|
||||
a = (ep_corr * FilterTable[63 - dist] >> 8) & 0xff;
|
||||
ICV_PUT_POINT();
|
||||
ICV_PUT_POINT();
|
||||
|
||||
pt1.x += x_step;
|
||||
ptr += step;
|
||||
scount++;
|
||||
ecount--;
|
||||
if( (unsigned)(x+2) < (unsigned)size0.width )
|
||||
ICV_PUT_POINT(x+2, y)
|
||||
}
|
||||
}
|
||||
#undef ICV_PUT_POINT
|
||||
|
@ -583,4 +583,14 @@ TEST(Drawing, line)
|
||||
ASSERT_THROW(line(mat, Point(1,1),Point(99,99),Scalar(255),0), cv::Exception);
|
||||
}
|
||||
|
||||
TEST(Drawing, regression_16308)
|
||||
{
|
||||
Mat_<uchar> img(Size(100, 100), (uchar)0);
|
||||
circle(img, Point(50, 50), 50, 255, 1, LINE_AA);
|
||||
EXPECT_NE(0, (int)img.at<uchar>(0, 50));
|
||||
EXPECT_NE(0, (int)img.at<uchar>(50, 0));
|
||||
EXPECT_NE(0, (int)img.at<uchar>(50, 99));
|
||||
EXPECT_NE(0, (int)img.at<uchar>(99, 50));
|
||||
}
|
||||
|
||||
}} // namespace
|
||||
|
Loading…
Reference in New Issue
Block a user