cvdrawing.cpp.svn-base
来自「非结构化路识别」· SVN-BASE 代码 · 共 2,174 行 · 第 1/5 页
SVN-BASE
2,174 行
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cv.h"
#include <limits.h>
#include "_cvdatastructs.h"
#define XY_SHIFT 16
#define XY_ONE (1 << XY_SHIFT)
typedef struct CvPolyEdge
{
int x, dx;
union
{
struct CvPolyEdge *next;
int y0;
};
int y1;
}
CvPolyEdge;
static void
icvCollectPolyEdges( CvMat* img, CvSeq* v, CvContour* edges, const void* color );
static void
icvFillEdgeCollection( CvMat* img, CvContour* edges, const void* color );
static void
icvPolyLineAA( CvMat* img, CvPoint *v, int count, int closed,
int scale, const void* color );
static void
icvPolyLine( CvMat* img, CvPoint *v, int count, int closed,
int thickness, const void* color, int connectivity = 8 );
static void
icvFillConvexPoly( CvMat* img, CvPoint* v,
int npts, const void* color );
/****************************************************************************************\
* Lines *
\****************************************************************************************/
int icvClipLine( int right, int bottom, CvPoint* pt1, CvPoint* pt2 )
{
int x1 = pt1->x, y1 = pt1->y, x2 = pt2->x, y2 = pt2->y;
int c1 = (x1 < 0) + (x1 > right) * 2 + (y1 < 0) * 4 + (y1 > bottom) * 8;
int c2 = (x2 < 0) + (x2 > right) * 2 + (y2 < 0) * 4 + (y2 > bottom) * 8;
if( (c1 & c2) == 0 && (c1 | c2) != 0 )
{
int a;
if( c1 & 12 )
{
a = c1 < 8 ? 0 : bottom;
x1 += (int) (((int64) (a - y1)) * (x2 - x1) / (y2 - y1));
y1 = a;
c1 = (x1 < 0) + (x1 > right) * 2;
}
if( c2 & 12 )
{
a = c2 < 8 ? 0 : bottom;
x2 += (int) (((int64) (a - y2)) * (x2 - x1) / (y2 - y1));
y2 = a;
c2 = (x2 < 0) + (x2 > right) * 2;
}
if( (c1 & c2) == 0 && (c1 | c2) != 0 )
{
if( c1 )
{
a = c1 == 1 ? 0 : right;
y1 += (int) (((int64) (a - x1)) * (y2 - y1) / (x2 - x1));
x1 = a;
c1 = 0;
}
if( c2 )
{
a = c2 == 1 ? 0 : right;
y2 += (int) (((int64) (a - x2)) * (y2 - y1) / (x2 - x1));
x2 = a;
c2 = 0;
}
}
assert( (c1 & c2) != 0 || (x1 | y1 | x2 | y2) >= 0 );
pt1->x = x1;
pt1->y = y1;
pt2->x = x2;
pt2->y = y2;
}
return ( c1 | c2 ) == 0;
}
static void
icvLine( CvMat* mat, CvPoint pt1, CvPoint pt2,
const void* color, int connectivity = 8 )
{
if( icvClipLine( mat->width - 1, mat->height - 1, &pt1, &pt2 ))
{
CvLineIterator iterator;
int i, count = icvInitLineIterator( mat, pt1, pt2, &iterator, connectivity, 1 );
int pix_size = icvPixSize[CV_MAT_TYPE(mat->type)];
for( i = 0; i < count; i++ )
{
memcpy( iterator.ptr, color, pix_size );
CV_NEXT_LINE_POINT( iterator );
}
}
}
/* Correction table depended on slope */
static const uchar icvSlopeCorrTable[] = {
181, 181, 181, 182, 182, 183, 184, 185, 187, 188, 190, 192, 194, 196, 198, 201,
203, 206, 209, 211, 214, 218, 221, 224, 227, 231, 235, 238, 242, 246, 250, 254
};
/* Gaussian for antialiasing filter */
static const int icvFilterTable[] = {
168, 177, 185, 194, 202, 210, 218, 224, 231, 236, 241, 246, 249, 252, 254, 254,
254, 254, 252, 249, 246, 241, 236, 231, 224, 218, 210, 202, 194, 185, 177, 168,
158, 149, 140, 131, 122, 114, 105, 97, 89, 82, 75, 68, 62, 56, 50, 45,
40, 36, 32, 28, 25, 22, 19, 16, 14, 12, 11, 9, 8, 7, 5, 5
};
static void
icvLineAA( CvMat* img, CvPoint pt1, CvPoint pt2,
const void* color )
{
int dx, dy;
int ecount, scount = 0;
int slope;
int ax, ay;
int x_step, y_step;
int i, j;
int ep_table[9];
int cb = ((uchar*)color)[0], cg = ((uchar*)color)[1], cr = ((uchar*)color)[2];
int _cb, _cg, _cr;
int nch = CV_MAT_CN( img->type );
uchar* ptr = (uchar*)(img->data.ptr);
int step = img->step;
CvSize size = icvGetMatSize( img );
assert( img && (nch == 1 || nch == 3) && CV_MAT_DEPTH(img->type) == CV_8U );
size.width <<= XY_SHIFT;
size.height <<= XY_SHIFT;
if( !icvClipLine( size.width - XY_ONE, size.height - XY_ONE, &pt1, &pt2 ))
return;
dx = pt2.x - pt1.x;
dy = pt2.y - pt1.y;
j = dx < 0 ? -1 : 0;
ax = (dx ^ j) - j;
i = dy < 0 ? -1 : 0;
ay = (dy ^ i) - i;
if( ax > ay )
{
dx = ax;
dy = (dy ^ j) - j;
pt1.x ^= pt2.x & j;
pt2.x ^= pt1.x & j;
pt1.x ^= pt2.x & j;
pt1.y ^= pt2.y & j;
pt2.y ^= pt1.y & j;
pt1.y ^= pt2.y & j;
x_step = XY_ONE;
y_step = (int) (((int64) dy << XY_SHIFT) / (ax | 1));
pt2.x += XY_ONE;
ecount = (pt2.x >> XY_SHIFT) - (pt1.x >> XY_SHIFT);
j = -(pt1.x & (XY_ONE - 1));
pt1.y += (int) ((((int64) y_step) * j) >> XY_SHIFT) + (XY_ONE >> 1);
slope = (y_step >> (XY_SHIFT - 5)) & 0x3f;
slope ^= (y_step < 0 ? 0x3f : 0);
/* Get 4-bit fractions for end-point adjustments */
i = (pt1.x >> (XY_SHIFT - 7)) & 0x78;
j = (pt2.x >> (XY_SHIFT - 7)) & 0x78;
}
else
{
dy = ay;
dx = (dx ^ i) - i;
pt1.x ^= pt2.x & i;
pt2.x ^= pt1.x & i;
pt1.x ^= pt2.x & i;
pt1.y ^= pt2.y & i;
pt2.y ^= pt1.y & i;
pt1.y ^= pt2.y & i;
x_step = (int) (((int64) dx << XY_SHIFT) / (ay | 1));
y_step = XY_ONE;
pt2.y += XY_ONE;
ecount = (pt2.y >> XY_SHIFT) - (pt1.y >> XY_SHIFT);
j = -(pt1.y & (XY_ONE - 1));
pt1.x += (int) ((((int64) x_step) * j) >> XY_SHIFT) + (XY_ONE >> 1);
slope = (x_step >> (XY_SHIFT - 5)) & 0x3f;
slope ^= (x_step < 0 ? 0x3f : 0);
/* Get 4-bit fractions for end-point adjustments */
i = (pt1.y >> (XY_SHIFT - 7)) & 0x78;
j = (pt2.y >> (XY_SHIFT - 7)) & 0x78;
}
slope = (slope & 0x20) ? 0x100 : icvSlopeCorrTable[slope];
/* Calc end point correction table */
{
int t0 = slope << 7;
int t1 = ((0x78 - i) | 4) * slope;
int t2 = (j | 4) * slope;
ep_table[0] = 0;
ep_table[8] = slope;
ep_table[1] = ep_table[3] = ((((j - i) & 0x78) | 4) * slope >> 8) & 0x1ff;
ep_table[2] = (t1 >> 8) & 0x1ff;
ep_table[4] = ((((j - i) + 0x80) | 4) * slope >> 8) & 0x1ff;
ep_table[5] = ((t1 + t0) >> 8) & 0x1ff;
ep_table[6] = (t2 >> 8) & 0x1ff;
ep_table[7] = ((t2 + t0) >> 8) & 0x1ff;
}
if( nch == 3 )
{
#define ICV_PUT_POINT() \
{ \
_cb = tptr[0]; \
_cb += (cb - _cb)*a >> 8; \
_cg = tptr[1]; \
_cg += (cg - _cg)*a >> 8; \
_cr = tptr[2]; \
_cr += (cr - _cr)*a >> 8; \
tptr[0] = (uchar)_cb; \
tptr[1] = (uchar)_cg; \
tptr[2] = (uchar)_cr; \
}
if( ax > ay )
{
ptr += (pt1.x >> XY_SHIFT) * 3;
while( ecount >= 0 )
{
uchar *tptr = ptr + ((pt1.y >> XY_SHIFT) - 1) * step;
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 * icvFilterTable[dist + 32] >> 8) & 0xff;
ICV_PUT_POINT();
tptr += step;
a = (ep_corr * icvFilterTable[dist] >> 8) & 0xff;
ICV_PUT_POINT();
tptr += step;
a = (ep_corr * icvFilterTable[63 - dist] >> 8) & 0xff;
ICV_PUT_POINT();
pt1.y += y_step;
ptr += 3;
scount++;
ecount--;
}
}
else
{
ptr += (pt1.y >> XY_SHIFT) * step;
while( ecount >= 0 )
{
uchar *tptr = ptr + ((pt1.x >> XY_SHIFT) - 1) * 3;
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 * icvFilterTable[dist + 32] >> 8) & 0xff;
ICV_PUT_POINT();
tptr += 3;
a = (ep_corr * icvFilterTable[dist] >> 8) & 0xff;
ICV_PUT_POINT();
tptr += 3;
a = (ep_corr * icvFilterTable[63 - dist] >> 8) & 0xff;
ICV_PUT_POINT();
pt1.x += x_step;
ptr += step;
scount++;
ecount--;
}
}
#undef ICV_PUT_POINT
}
else
{
#define ICV_PUT_POINT() \
{ \
_cb = tptr[0]; \
_cb += (cb - _cb)*a >> 8; \
tptr[0] = (uchar)_cb; \
}
if( ax > ay )
{
ptr += (pt1.x >> XY_SHIFT);
while( ecount >= 0 )
{
uchar *tptr = ptr + ((pt1.y >> XY_SHIFT) - 1) * step;
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 * icvFilterTable[dist + 32] >> 8) & 0xff;
ICV_PUT_POINT();
tptr += step;
a = (ep_corr * icvFilterTable[dist] >> 8) & 0xff;
ICV_PUT_POINT();
tptr += step;
a = (ep_corr * icvFilterTable[63 - dist] >> 8) & 0xff;
ICV_PUT_POINT();
pt1.y += y_step;
ptr++;
scount++;
ecount--;
}
}
else
{
ptr += (pt1.y >> XY_SHIFT) * step;
while( ecount >= 0 )
{
uchar *tptr = ptr + ((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 * icvFilterTable[dist + 32] >> 8) & 0xff;
ICV_PUT_POINT();
tptr++;
a = (ep_corr * icvFilterTable[dist] >> 8) & 0xff;
ICV_PUT_POINT();
tptr++;
a = (ep_corr * icvFilterTable[63 - dist] >> 8) & 0xff;
ICV_PUT_POINT();
pt1.x += x_step;
ptr += step;
scount++;
ecount--;
}
}
#undef ICV_PUT_POINT
}
}
/****************************************************************************************\
* Antialiazed Elliptic Arcs through Antialiazed Lines *
\****************************************************************************************/
static const float icvSinTable[] =
{ 0.0000000f, 0.0174524f, 0.0348995f, 0.0523360f, 0.0697565f, 0.0871557f,
0.1045285f, 0.1218693f, 0.1391731f, 0.1564345f, 0.1736482f, 0.1908090f,
0.2079117f, 0.2249511f, 0.2419219f, 0.2588190f, 0.2756374f, 0.2923717f,
0.3090170f, 0.3255682f, 0.3420201f, 0.3583679f, 0.3746066f, 0.3907311f,
0.4067366f, 0.4226183f, 0.4383711f, 0.4539905f, 0.4694716f, 0.4848096f,
0.5000000f, 0.5150381f, 0.5299193f, 0.5446390f, 0.5591929f, 0.5735764f,
0.5877853f, 0.6018150f, 0.6156615f, 0.6293204f, 0.6427876f, 0.6560590f,
0.6691306f, 0.6819984f, 0.6946584f, 0.7071068f, 0.7193398f, 0.7313537f,
0.7431448f, 0.7547096f, 0.7660444f, 0.7771460f, 0.7880108f, 0.7986355f,
0.8090170f, 0.8191520f, 0.8290376f, 0.8386706f, 0.8480481f, 0.8571673f,
0.8660254f, 0.8746197f, 0.8829476f, 0.8910065f, 0.8987940f, 0.9063078f,
0.9135455f, 0.9205049f, 0.9271839f, 0.9335804f, 0.9396926f, 0.9455186f,
0.9510565f, 0.9563048f, 0.9612617f, 0.9659258f, 0.9702957f, 0.9743701f,
0.9781476f, 0.9816272f, 0.9848078f, 0.9876883f, 0.9902681f, 0.9925462f,
0.9945219f, 0.9961947f, 0.9975641f, 0.9986295f, 0.9993908f, 0.9998477f,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?