1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
41 #include "precomp.hpp"
46 enum { XY_SHIFT = 16, XY_ONE = 1 << XY_SHIFT, DRAWING_STORAGE_BLOCK = (1<<12) - 256 };
50 PolyEdge() : y0(0), y1(0), x(0), dx(0), next(0) {}
51 //PolyEdge(int _y0, int _y1, int _x, int _dx) : y0(_y0), y1(_y1), x(_x), dx(_dx) {}
59 CollectPolyEdges( Mat& img, const Point* v, int npts,
60 vector<PolyEdge>& edges, const void* color, int line_type,
61 int shift, Point offset=Point() );
64 FillEdgeCollection( Mat& img, vector<PolyEdge>& edges, const void* color );
67 PolyLine( Mat& img, const Point* v, int npts, bool closed,
68 const void* color, int thickness, int line_type, int shift );
71 FillConvexPoly( Mat& img, const Point* v, int npts,
72 const void* color, int line_type, int shift );
74 /****************************************************************************************\
76 \****************************************************************************************/
78 bool clipLine( Size img_size, Point& pt1, Point& pt2 )
82 int64 right = img_size.width-1, bottom = img_size.height-1;
84 if( img_size.width <= 0 || img_size.height <= 0 )
87 x1 = pt1.x; y1 = pt1.y; x2 = pt2.x; y2 = pt2.y;
88 c1 = (x1 < 0) + (x1 > right) * 2 + (y1 < 0) * 4 + (y1 > bottom) * 8;
89 c2 = (x2 < 0) + (x2 > right) * 2 + (y2 < 0) * 4 + (y2 > bottom) * 8;
91 if( (c1 & c2) == 0 && (c1 | c2) != 0 )
96 a = c1 < 8 ? 0 : bottom;
97 x1 += (a - y1) * (x2 - x1) / (y2 - y1);
99 c1 = (x1 < 0) + (x1 > right) * 2;
103 a = c2 < 8 ? 0 : bottom;
104 x2 += (a - y2) * (x2 - x1) / (y2 - y1);
106 c2 = (x2 < 0) + (x2 > right) * 2;
108 if( (c1 & c2) == 0 && (c1 | c2) != 0 )
112 a = c1 == 1 ? 0 : right;
113 y1 += (a - x1) * (y2 - y1) / (x2 - x1);
119 a = c2 == 1 ? 0 : right;
120 y2 += (a - x2) * (y2 - y1) / (x2 - x1);
126 assert( (c1 & c2) != 0 || (x1 | y1 | x2 | y2) >= 0 );
134 return (c1 | c2) == 0;
137 bool clipLine( Rect img_rect, Point& pt1, Point& pt2 )
139 Point tl = img_rect.tl();
140 pt1 -= tl; pt2 -= tl;
141 bool inside = clipLine(img_rect.size(), pt1, pt2);
142 pt1 += tl; pt2 += tl;
148 Initializes line iterator.
149 Returns number of points on the line or negative number if error.
151 LineIterator::LineIterator(const Mat& img, Point pt1, Point pt2,
152 int connectivity, bool left_to_right)
156 CV_Assert( connectivity == 8 || connectivity == 4 );
158 if( (unsigned)pt1.x >= (unsigned)(img.cols) ||
159 (unsigned)pt2.x >= (unsigned)(img.cols) ||
160 (unsigned)pt1.y >= (unsigned)(img.rows) ||
161 (unsigned)pt2.y >= (unsigned)(img.rows) )
163 if( !clipLine( img.size(), pt1, pt2 ) )
166 err = plusDelta = minusDelta = plusStep = minusStep = count = 0;
171 int bt_pix0 = (int)img.elemSize(), bt_pix = bt_pix0;
172 size_t istep = img.step;
174 int dx = pt2.x - pt1.x;
175 int dy = pt2.y - pt1.y;
176 int s = dx < 0 ? -1 : 0;
182 pt1.x ^= (pt1.x ^ pt2.x) & s;
183 pt1.y ^= (pt1.y ^ pt2.y) & s;
188 bt_pix = (bt_pix ^ s) - s;
191 ptr = (uchar*)(img.data + pt1.y * istep + pt1.x * bt_pix0);
195 istep = (istep ^ s) - s;
197 s = dy > dx ? -1 : 0;
199 /* conditional swaps */
208 if( connectivity == 8 )
210 assert( dx >= 0 && dy >= 0 );
212 err = dx - (dy + dy);
214 minusDelta = -(dy + dy);
215 plusStep = (int)istep;
219 else /* connectivity == 4 */
221 assert( dx >= 0 && dy >= 0 );
224 plusDelta = (dx + dx) + (dy + dy);
225 minusDelta = -(dy + dy);
226 plusStep = (int)istep - bt_pix;
231 this->ptr0 = img.data;
232 this->step = (int)img.step;
233 this->elemSize = bt_pix0;
237 Line( Mat& img, Point pt1, Point pt2,
238 const void* _color, int connectivity = 8 )
240 if( connectivity == 0 )
242 if( connectivity == 1 )
245 LineIterator iterator(img, pt1, pt2, connectivity, true);
246 int i, count = iterator.count;
247 int pix_size = (int)img.elemSize();
248 const uchar* color = (const uchar*)_color;
250 for( i = 0; i < count; i++, ++iterator )
252 uchar* ptr = *iterator;
255 else if( pix_size == 3 )
262 memcpy( *iterator, color, pix_size );
267 /* Correction table depent on the slope */
268 static const uchar SlopeCorrTable[] = {
269 181, 181, 181, 182, 182, 183, 184, 185, 187, 188, 190, 192, 194, 196, 198, 201,
270 203, 206, 209, 211, 214, 218, 221, 224, 227, 231, 235, 238, 242, 246, 250, 254
273 /* Gaussian for antialiasing filter */
274 static const int FilterTable[] = {
275 168, 177, 185, 194, 202, 210, 218, 224, 231, 236, 241, 246, 249, 252, 254, 254,
276 254, 254, 252, 249, 246, 241, 236, 231, 224, 218, 210, 202, 194, 185, 177, 168,
277 158, 149, 140, 131, 122, 114, 105, 97, 89, 82, 75, 68, 62, 56, 50, 45,
278 40, 36, 32, 28, 25, 22, 19, 16, 14, 12, 11, 9, 8, 7, 5, 5
282 LineAA( Mat& img, Point pt1, Point pt2, const void* color )
285 int ecount, scount = 0;
291 int cb = ((uchar*)color)[0], cg = ((uchar*)color)[1], cr = ((uchar*)color)[2];
293 int nch = img.channels();
294 uchar* ptr = img.data;
295 size_t step = img.step;
296 Size size = img.size();
298 if( !((nch == 1 || nch == 3) && img.depth() == CV_8U) )
300 Line(img, pt1, pt2, color);
308 ptr += img.step*2 + 2*nch;
310 size.width = ((size.width - 5) << XY_SHIFT) + 1;
311 size.height = ((size.height - 5) << XY_SHIFT) + 1;
313 if( !clipLine( size, pt1, pt2 ))
336 y_step = (int) (((int64) dy << XY_SHIFT) / (ax | 1));
338 ecount = (pt2.x >> XY_SHIFT) - (pt1.x >> XY_SHIFT);
339 j = -(pt1.x & (XY_ONE - 1));
340 pt1.y += (int) ((((int64) y_step) * j) >> XY_SHIFT) + (XY_ONE >> 1);
341 slope = (y_step >> (XY_SHIFT - 5)) & 0x3f;
342 slope ^= (y_step < 0 ? 0x3f : 0);
344 /* Get 4-bit fractions for end-point adjustments */
345 i = (pt1.x >> (XY_SHIFT - 7)) & 0x78;
346 j = (pt2.x >> (XY_SHIFT - 7)) & 0x78;
359 x_step = (int) (((int64) dx << XY_SHIFT) / (ay | 1));
362 ecount = (pt2.y >> XY_SHIFT) - (pt1.y >> XY_SHIFT);
363 j = -(pt1.y & (XY_ONE - 1));
364 pt1.x += (int) ((((int64) x_step) * j) >> XY_SHIFT) + (XY_ONE >> 1);
365 slope = (x_step >> (XY_SHIFT - 5)) & 0x3f;
366 slope ^= (x_step < 0 ? 0x3f : 0);
368 /* Get 4-bit fractions for end-point adjustments */
369 i = (pt1.y >> (XY_SHIFT - 7)) & 0x78;
370 j = (pt2.y >> (XY_SHIFT - 7)) & 0x78;
373 slope = (slope & 0x20) ? 0x100 : SlopeCorrTable[slope];
375 /* Calc end point correction table */
378 int t1 = ((0x78 - i) | 4) * slope;
379 int t2 = (j | 4) * slope;
383 ep_table[1] = ep_table[3] = ((((j - i) & 0x78) | 4) * slope >> 8) & 0x1ff;
384 ep_table[2] = (t1 >> 8) & 0x1ff;
385 ep_table[4] = ((((j - i) + 0x80) | 4) * slope >> 8) & 0x1ff;
386 ep_table[5] = ((t1 + t0) >> 8) & 0x1ff;
387 ep_table[6] = (t2 >> 8) & 0x1ff;
388 ep_table[7] = ((t2 + t0) >> 8) & 0x1ff;
393 #define ICV_PUT_POINT() \
396 _cb += ((cb - _cb)*a + 127)>> 8;\
398 _cg += ((cg - _cg)*a + 127)>> 8;\
400 _cr += ((cr - _cr)*a + 127)>> 8;\
401 tptr[0] = (uchar)_cb; \
402 tptr[1] = (uchar)_cg; \
403 tptr[2] = (uchar)_cr; \
407 ptr += (pt1.x >> XY_SHIFT) * 3;
411 uchar *tptr = ptr + ((pt1.y >> XY_SHIFT) - 1) * step;
413 int ep_corr = ep_table[(((scount >= 2) + 1) & (scount | 2)) * 3 +
414 (((ecount >= 2) + 1) & (ecount | 2))];
415 int a, dist = (pt1.y >> (XY_SHIFT - 5)) & 31;
417 a = (ep_corr * FilterTable[dist + 32] >> 8) & 0xff;
422 a = (ep_corr * FilterTable[dist] >> 8) & 0xff;
427 a = (ep_corr * FilterTable[63 - dist] >> 8) & 0xff;
439 ptr += (pt1.y >> XY_SHIFT) * step;
443 uchar *tptr = ptr + ((pt1.x >> XY_SHIFT) - 1) * 3;
445 int ep_corr = ep_table[(((scount >= 2) + 1) & (scount | 2)) * 3 +
446 (((ecount >= 2) + 1) & (ecount | 2))];
447 int a, dist = (pt1.x >> (XY_SHIFT - 5)) & 31;
449 a = (ep_corr * FilterTable[dist + 32] >> 8) & 0xff;
454 a = (ep_corr * FilterTable[dist] >> 8) & 0xff;
459 a = (ep_corr * FilterTable[63 - dist] >> 8) & 0xff;
473 #define ICV_PUT_POINT() \
476 _cb += ((cb - _cb)*a + 127)>> 8;\
477 tptr[0] = (uchar)_cb; \
482 ptr += (pt1.x >> XY_SHIFT);
486 uchar *tptr = ptr + ((pt1.y >> XY_SHIFT) - 1) * step;
488 int ep_corr = ep_table[(((scount >= 2) + 1) & (scount | 2)) * 3 +
489 (((ecount >= 2) + 1) & (ecount | 2))];
490 int a, dist = (pt1.y >> (XY_SHIFT - 5)) & 31;
492 a = (ep_corr * FilterTable[dist + 32] >> 8) & 0xff;
497 a = (ep_corr * FilterTable[dist] >> 8) & 0xff;
502 a = (ep_corr * FilterTable[63 - dist] >> 8) & 0xff;
514 ptr += (pt1.y >> XY_SHIFT) * step;
518 uchar *tptr = ptr + ((pt1.x >> XY_SHIFT) - 1);
520 int ep_corr = ep_table[(((scount >= 2) + 1) & (scount | 2)) * 3 +
521 (((ecount >= 2) + 1) & (ecount | 2))];
522 int a, dist = (pt1.x >> (XY_SHIFT - 5)) & 31;
524 a = (ep_corr * FilterTable[dist + 32] >> 8) & 0xff;
529 a = (ep_corr * FilterTable[dist] >> 8) & 0xff;
534 a = (ep_corr * FilterTable[63 - dist] >> 8) & 0xff;
550 Line2( Mat& img, Point pt1, Point pt2, const void* color )
557 int cb = ((uchar*)color)[0];
558 int cg = ((uchar*)color)[1];
559 int cr = ((uchar*)color)[2];
560 int pix_size = (int)img.elemSize();
561 uchar *ptr = img.data, *tptr;
562 size_t step = img.step;
563 Size size = img.size(), sizeScaled(size.width*XY_ONE, size.height*XY_ONE);
565 //assert( img && (nch == 1 || nch == 3) && img.depth() == CV_8U );
567 if( !clipLine( sizeScaled, pt1, pt2 ))
590 y_step = (int) (((int64) dy << XY_SHIFT) / (ax | 1));
591 ecount = (pt2.x - pt1.x) >> XY_SHIFT;
604 x_step = (int) (((int64) dx << XY_SHIFT) / (ay | 1));
606 ecount = (pt2.y - pt1.y) >> XY_SHIFT;
609 pt1.x += (XY_ONE >> 1);
610 pt1.y += (XY_ONE >> 1);
614 #define ICV_PUT_POINT(_x,_y) \
615 x = (_x); y = (_y); \
616 if( 0 <= x && x < size.width && \
617 0 <= y && y < size.height ) \
619 tptr = ptr + y*step + x*3; \
620 tptr[0] = (uchar)cb; \
621 tptr[1] = (uchar)cg; \
622 tptr[2] = (uchar)cr; \
625 ICV_PUT_POINT((pt2.x + (XY_ONE >> 1)) >> XY_SHIFT,
626 (pt2.y + (XY_ONE >> 1)) >> XY_SHIFT);
634 ICV_PUT_POINT(pt1.x, pt1.y >> XY_SHIFT);
646 ICV_PUT_POINT(pt1.x >> XY_SHIFT, pt1.y);
655 else if( pix_size == 1 )
657 #define ICV_PUT_POINT(_x,_y) \
658 x = (_x); y = (_y); \
659 if( 0 <= x && x < size.width && \
660 0 <= y && y < size.height ) \
662 tptr = ptr + y*step + x;\
663 tptr[0] = (uchar)cb; \
666 ICV_PUT_POINT((pt2.x + (XY_ONE >> 1)) >> XY_SHIFT,
667 (pt2.y + (XY_ONE >> 1)) >> XY_SHIFT);
675 ICV_PUT_POINT(pt1.x, pt1.y >> XY_SHIFT);
687 ICV_PUT_POINT(pt1.x >> XY_SHIFT, pt1.y);
698 #define ICV_PUT_POINT(_x,_y) \
699 x = (_x); y = (_y); \
700 if( 0 <= x && x < size.width && \
701 0 <= y && y < size.height ) \
703 tptr = ptr + y*step + x*pix_size;\
704 for( j = 0; j < pix_size; j++ ) \
705 tptr[j] = ((uchar*)color)[j]; \
708 ICV_PUT_POINT((pt2.x + (XY_ONE >> 1)) >> XY_SHIFT,
709 (pt2.y + (XY_ONE >> 1)) >> XY_SHIFT);
717 ICV_PUT_POINT(pt1.x, pt1.y >> XY_SHIFT);
729 ICV_PUT_POINT(pt1.x >> XY_SHIFT, pt1.y);
741 /****************************************************************************************\
742 * Antialiazed Elliptic Arcs via Antialiazed Lines *
743 \****************************************************************************************/
745 static const float SinTable[] =
746 { 0.0000000f, 0.0174524f, 0.0348995f, 0.0523360f, 0.0697565f, 0.0871557f,
747 0.1045285f, 0.1218693f, 0.1391731f, 0.1564345f, 0.1736482f, 0.1908090f,
748 0.2079117f, 0.2249511f, 0.2419219f, 0.2588190f, 0.2756374f, 0.2923717f,
749 0.3090170f, 0.3255682f, 0.3420201f, 0.3583679f, 0.3746066f, 0.3907311f,
750 0.4067366f, 0.4226183f, 0.4383711f, 0.4539905f, 0.4694716f, 0.4848096f,
751 0.5000000f, 0.5150381f, 0.5299193f, 0.5446390f, 0.5591929f, 0.5735764f,
752 0.5877853f, 0.6018150f, 0.6156615f, 0.6293204f, 0.6427876f, 0.6560590f,
753 0.6691306f, 0.6819984f, 0.6946584f, 0.7071068f, 0.7193398f, 0.7313537f,
754 0.7431448f, 0.7547096f, 0.7660444f, 0.7771460f, 0.7880108f, 0.7986355f,
755 0.8090170f, 0.8191520f, 0.8290376f, 0.8386706f, 0.8480481f, 0.8571673f,
756 0.8660254f, 0.8746197f, 0.8829476f, 0.8910065f, 0.8987940f, 0.9063078f,
757 0.9135455f, 0.9205049f, 0.9271839f, 0.9335804f, 0.9396926f, 0.9455186f,
758 0.9510565f, 0.9563048f, 0.9612617f, 0.9659258f, 0.9702957f, 0.9743701f,
759 0.9781476f, 0.9816272f, 0.9848078f, 0.9876883f, 0.9902681f, 0.9925462f,
760 0.9945219f, 0.9961947f, 0.9975641f, 0.9986295f, 0.9993908f, 0.9998477f,
761 1.0000000f, 0.9998477f, 0.9993908f, 0.9986295f, 0.9975641f, 0.9961947f,
762 0.9945219f, 0.9925462f, 0.9902681f, 0.9876883f, 0.9848078f, 0.9816272f,
763 0.9781476f, 0.9743701f, 0.9702957f, 0.9659258f, 0.9612617f, 0.9563048f,
764 0.9510565f, 0.9455186f, 0.9396926f, 0.9335804f, 0.9271839f, 0.9205049f,
765 0.9135455f, 0.9063078f, 0.8987940f, 0.8910065f, 0.8829476f, 0.8746197f,
766 0.8660254f, 0.8571673f, 0.8480481f, 0.8386706f, 0.8290376f, 0.8191520f,
767 0.8090170f, 0.7986355f, 0.7880108f, 0.7771460f, 0.7660444f, 0.7547096f,
768 0.7431448f, 0.7313537f, 0.7193398f, 0.7071068f, 0.6946584f, 0.6819984f,
769 0.6691306f, 0.6560590f, 0.6427876f, 0.6293204f, 0.6156615f, 0.6018150f,
770 0.5877853f, 0.5735764f, 0.5591929f, 0.5446390f, 0.5299193f, 0.5150381f,
771 0.5000000f, 0.4848096f, 0.4694716f, 0.4539905f, 0.4383711f, 0.4226183f,
772 0.4067366f, 0.3907311f, 0.3746066f, 0.3583679f, 0.3420201f, 0.3255682f,
773 0.3090170f, 0.2923717f, 0.2756374f, 0.2588190f, 0.2419219f, 0.2249511f,
774 0.2079117f, 0.1908090f, 0.1736482f, 0.1564345f, 0.1391731f, 0.1218693f,
775 0.1045285f, 0.0871557f, 0.0697565f, 0.0523360f, 0.0348995f, 0.0174524f,
776 0.0000000f, -0.0174524f, -0.0348995f, -0.0523360f, -0.0697565f, -0.0871557f,
777 -0.1045285f, -0.1218693f, -0.1391731f, -0.1564345f, -0.1736482f, -0.1908090f,
778 -0.2079117f, -0.2249511f, -0.2419219f, -0.2588190f, -0.2756374f, -0.2923717f,
779 -0.3090170f, -0.3255682f, -0.3420201f, -0.3583679f, -0.3746066f, -0.3907311f,
780 -0.4067366f, -0.4226183f, -0.4383711f, -0.4539905f, -0.4694716f, -0.4848096f,
781 -0.5000000f, -0.5150381f, -0.5299193f, -0.5446390f, -0.5591929f, -0.5735764f,
782 -0.5877853f, -0.6018150f, -0.6156615f, -0.6293204f, -0.6427876f, -0.6560590f,
783 -0.6691306f, -0.6819984f, -0.6946584f, -0.7071068f, -0.7193398f, -0.7313537f,
784 -0.7431448f, -0.7547096f, -0.7660444f, -0.7771460f, -0.7880108f, -0.7986355f,
785 -0.8090170f, -0.8191520f, -0.8290376f, -0.8386706f, -0.8480481f, -0.8571673f,
786 -0.8660254f, -0.8746197f, -0.8829476f, -0.8910065f, -0.8987940f, -0.9063078f,
787 -0.9135455f, -0.9205049f, -0.9271839f, -0.9335804f, -0.9396926f, -0.9455186f,
788 -0.9510565f, -0.9563048f, -0.9612617f, -0.9659258f, -0.9702957f, -0.9743701f,
789 -0.9781476f, -0.9816272f, -0.9848078f, -0.9876883f, -0.9902681f, -0.9925462f,
790 -0.9945219f, -0.9961947f, -0.9975641f, -0.9986295f, -0.9993908f, -0.9998477f,
791 -1.0000000f, -0.9998477f, -0.9993908f, -0.9986295f, -0.9975641f, -0.9961947f,
792 -0.9945219f, -0.9925462f, -0.9902681f, -0.9876883f, -0.9848078f, -0.9816272f,
793 -0.9781476f, -0.9743701f, -0.9702957f, -0.9659258f, -0.9612617f, -0.9563048f,
794 -0.9510565f, -0.9455186f, -0.9396926f, -0.9335804f, -0.9271839f, -0.9205049f,
795 -0.9135455f, -0.9063078f, -0.8987940f, -0.8910065f, -0.8829476f, -0.8746197f,
796 -0.8660254f, -0.8571673f, -0.8480481f, -0.8386706f, -0.8290376f, -0.8191520f,
797 -0.8090170f, -0.7986355f, -0.7880108f, -0.7771460f, -0.7660444f, -0.7547096f,
798 -0.7431448f, -0.7313537f, -0.7193398f, -0.7071068f, -0.6946584f, -0.6819984f,
799 -0.6691306f, -0.6560590f, -0.6427876f, -0.6293204f, -0.6156615f, -0.6018150f,
800 -0.5877853f, -0.5735764f, -0.5591929f, -0.5446390f, -0.5299193f, -0.5150381f,
801 -0.5000000f, -0.4848096f, -0.4694716f, -0.4539905f, -0.4383711f, -0.4226183f,
802 -0.4067366f, -0.3907311f, -0.3746066f, -0.3583679f, -0.3420201f, -0.3255682f,
803 -0.3090170f, -0.2923717f, -0.2756374f, -0.2588190f, -0.2419219f, -0.2249511f,
804 -0.2079117f, -0.1908090f, -0.1736482f, -0.1564345f, -0.1391731f, -0.1218693f,
805 -0.1045285f, -0.0871557f, -0.0697565f, -0.0523360f, -0.0348995f, -0.0174524f,
806 -0.0000000f, 0.0174524f, 0.0348995f, 0.0523360f, 0.0697565f, 0.0871557f,
807 0.1045285f, 0.1218693f, 0.1391731f, 0.1564345f, 0.1736482f, 0.1908090f,
808 0.2079117f, 0.2249511f, 0.2419219f, 0.2588190f, 0.2756374f, 0.2923717f,
809 0.3090170f, 0.3255682f, 0.3420201f, 0.3583679f, 0.3746066f, 0.3907311f,
810 0.4067366f, 0.4226183f, 0.4383711f, 0.4539905f, 0.4694716f, 0.4848096f,
811 0.5000000f, 0.5150381f, 0.5299193f, 0.5446390f, 0.5591929f, 0.5735764f,
812 0.5877853f, 0.6018150f, 0.6156615f, 0.6293204f, 0.6427876f, 0.6560590f,
813 0.6691306f, 0.6819984f, 0.6946584f, 0.7071068f, 0.7193398f, 0.7313537f,
814 0.7431448f, 0.7547096f, 0.7660444f, 0.7771460f, 0.7880108f, 0.7986355f,
815 0.8090170f, 0.8191520f, 0.8290376f, 0.8386706f, 0.8480481f, 0.8571673f,
816 0.8660254f, 0.8746197f, 0.8829476f, 0.8910065f, 0.8987940f, 0.9063078f,
817 0.9135455f, 0.9205049f, 0.9271839f, 0.9335804f, 0.9396926f, 0.9455186f,
818 0.9510565f, 0.9563048f, 0.9612617f, 0.9659258f, 0.9702957f, 0.9743701f,
819 0.9781476f, 0.9816272f, 0.9848078f, 0.9876883f, 0.9902681f, 0.9925462f,
820 0.9945219f, 0.9961947f, 0.9975641f, 0.9986295f, 0.9993908f, 0.9998477f,
826 sincos( int angle, float& cosval, float& sinval )
828 angle += (angle < 0 ? 360 : 0);
829 sinval = SinTable[angle];
830 cosval = SinTable[450 - angle];
834 constructs polygon that represents elliptic arc.
836 void ellipse2Poly( Point center, Size axes, int angle,
837 int arc_start, int arc_end,
838 int delta, vector<Point>& pts )
841 double size_a = axes.width, size_b = axes.height;
842 double cx = center.x, cy = center.y;
843 Point prevPt(INT_MIN,INT_MIN);
851 if( arc_start > arc_end )
857 while( arc_start < 0 )
862 while( arc_end > 360 )
867 if( arc_end - arc_start > 360 )
872 sincos( angle, alpha, beta );
875 for( i = arc_start; i < arc_end + delta; i += delta )
879 if( angle > arc_end )
884 x = size_a * SinTable[450-angle];
885 y = size_b * SinTable[angle];
887 pt.x = cvRound( cx + x * alpha - y * beta );
888 pt.y = cvRound( cy + x * beta + y * alpha );
894 pts.push_back(pts[0]);
899 EllipseEx( Mat& img, Point center, Size axes,
900 int angle, int arc_start, int arc_end,
901 const void* color, int thickness, int line_type )
903 axes.width = std::abs(axes.width), axes.height = std::abs(axes.height);
904 int delta = (std::max(axes.width,axes.height)+(XY_ONE>>1))>>XY_SHIFT;
905 delta = delta < 3 ? 90 : delta < 10 ? 30 : delta < 15 ? 18 : 5;
908 ellipse2Poly( center, axes, angle, arc_start, arc_end, delta, v );
911 PolyLine( img, &v[0], (int)v.size(), false, color, thickness, line_type, XY_SHIFT );
912 else if( arc_end - arc_start >= 360 )
913 FillConvexPoly( img, &v[0], (int)v.size(), color, line_type, XY_SHIFT );
917 vector<PolyEdge> edges;
918 CollectPolyEdges( img, &v[0], (int)v.size(), edges, color, line_type, XY_SHIFT );
919 FillEdgeCollection( img, edges, color );
924 /****************************************************************************************\
926 \****************************************************************************************/
928 /* helper macros: filling horizontal row */
929 #define ICV_HLINE( ptr, xl, xr, color, pix_size ) \
931 uchar* hline_ptr = (uchar*)(ptr) + (xl)*(pix_size); \
932 uchar* hline_max_ptr = (uchar*)(ptr) + (xr)*(pix_size); \
934 for( ; hline_ptr <= hline_max_ptr; hline_ptr += (pix_size))\
937 for( hline_j = 0; hline_j < (pix_size); hline_j++ ) \
939 hline_ptr[hline_j] = ((uchar*)color)[hline_j]; \
945 /* filling convex polygon. v - array of vertices, ntps - number of points */
947 FillConvexPoly( Mat& img, const Point* v, int npts, const void* color, int line_type, int shift )
956 int delta = shift ? 1 << (shift - 1) : 0;
957 int i, y, imin = 0, left = 0, right = 1, x1, x2;
959 int xmin, xmax, ymin, ymax;
960 uchar* ptr = img.data;
961 Size size = img.size();
962 int pix_size = (int)img.elemSize();
966 if( line_type < CV_AA )
967 delta1 = delta2 = XY_ONE >> 1;
969 delta1 = XY_ONE - 1, delta2 = 0;
972 p0.x <<= XY_SHIFT - shift;
973 p0.y <<= XY_SHIFT - shift;
975 assert( 0 <= shift && shift <= XY_SHIFT );
976 xmin = xmax = v[0].x;
977 ymin = ymax = v[0].y;
979 for( i = 0; i < npts; i++ )
988 ymax = std::max( ymax, p.y );
989 xmax = std::max( xmax, p.x );
990 xmin = MIN( xmin, p.x );
992 p.x <<= XY_SHIFT - shift;
993 p.y <<= XY_SHIFT - shift;
1000 pt0.x = p0.x >> XY_SHIFT;
1001 pt0.y = p0.y >> XY_SHIFT;
1002 pt1.x = p.x >> XY_SHIFT;
1003 pt1.y = p.y >> XY_SHIFT;
1004 Line( img, pt0, pt1, color, line_type );
1007 Line2( img, p0, p, color );
1010 LineAA( img, p0, p, color );
1014 xmin = (xmin + delta) >> shift;
1015 xmax = (xmax + delta) >> shift;
1016 ymin = (ymin + delta) >> shift;
1017 ymax = (ymax + delta) >> shift;
1019 if( npts < 3 || xmax < 0 || ymax < 0 || xmin >= size.width || ymin >= size.height )
1022 ymax = MIN( ymax, size.height - 1 );
1023 edge[0].idx = edge[1].idx = imin;
1025 edge[0].ye = edge[1].ye = y = ymin;
1027 edge[1].di = npts - 1;
1033 if( line_type < CV_AA || y < ymax || y == ymin )
1035 for( i = 0; i < 2; i++ )
1037 if( y >= edge[i].ye )
1039 int idx = edge[i].idx, di = edge[i].di;
1040 int xs = 0, xe, ye, ty = 0;
1044 ty = (v[idx].y + delta) >> shift;
1045 if( ty > y || edges == 0 )
1049 idx -= ((idx < npts) - 1) & npts; /* idx -= idx >= npts ? npts : 0 */
1054 xs <<= XY_SHIFT - shift;
1055 xe = v[idx].x << (XY_SHIFT - shift);
1062 edge[i].dx = ((xe - xs)*2 + (ye - y)) / (2 * (ye - y));
1069 if( edge[left].x > edge[right].x )
1080 int xx1 = (x1 + delta1) >> XY_SHIFT;
1081 int xx2 = (x2 + delta2) >> XY_SHIFT;
1083 if( xx2 >= 0 && xx1 < size.width )
1087 if( xx2 >= size.width )
1088 xx2 = size.width - 1;
1089 ICV_HLINE( ptr, xx1, xx2, color, pix_size );
1093 x1 += edge[left].dx;
1094 x2 += edge[right].dx;
1100 while( ++y <= ymax );
1104 /******** Arbitrary polygon **********/
1107 CollectPolyEdges( Mat& img, const Point* v, int count, vector<PolyEdge>& edges,
1108 const void* color, int line_type, int shift, Point offset )
1110 int i, delta = offset.y + (shift ? 1 << (shift - 1) : 0);
1111 Point pt0 = v[count-1], pt1;
1112 pt0.x = (pt0.x + offset.x) << (XY_SHIFT - shift);
1113 pt0.y = (pt0.y + delta) >> shift;
1115 edges.reserve( edges.size() + count );
1117 for( i = 0; i < count; i++, pt0 = pt1 )
1123 pt1.x = (pt1.x + offset.x) << (XY_SHIFT - shift);
1124 pt1.y = (pt1.y + delta) >> shift;
1126 if( line_type < CV_AA )
1128 t0.y = pt0.y; t1.y = pt1.y;
1129 t0.x = (pt0.x + (XY_ONE >> 1)) >> XY_SHIFT;
1130 t1.x = (pt1.x + (XY_ONE >> 1)) >> XY_SHIFT;
1131 Line( img, t0, t1, color, line_type );
1135 t0.x = pt0.x; t1.x = pt1.x;
1136 t0.y = pt0.y << XY_SHIFT;
1137 t1.y = pt1.y << XY_SHIFT;
1138 LineAA( img, t0, t1, color );
1141 if( pt0.y == pt1.y )
1156 edge.dx = (pt1.x - pt0.x) / (pt1.y - pt0.y);
1157 edges.push_back(edge);
1163 bool operator ()(const PolyEdge& e1, const PolyEdge& e2)
1165 return e1.y0 - e2.y0 ? e1.y0 < e2.y0 :
1166 e1.x - e2.x ? e1.x < e2.x : e1.dx < e2.dx;
1170 /**************** helper macros and functions for sequence/contour processing ***********/
1173 FillEdgeCollection( Mat& img, vector<PolyEdge>& edges, const void* color )
1176 int i, y, total = (int)edges.size();
1177 Size size = img.size();
1179 int y_max = INT_MIN, x_max = INT_MIN, y_min = INT_MAX, x_min = INT_MAX;
1180 int pix_size = (int)img.elemSize();
1185 for( i = 0; i < total; i++ )
1187 PolyEdge& e1 = edges[i];
1188 assert( e1.y0 < e1.y1 );
1189 y_min = std::min( y_min, e1.y0 );
1190 y_max = std::max( y_max, e1.y1 );
1191 x_min = std::min( x_min, e1.x );
1192 x_max = std::max( x_max, e1.x );
1195 if( y_max < 0 || y_min >= size.height || x_max < 0 || x_min >= (size.width<<XY_SHIFT) )
1198 std::sort( edges.begin(), edges.end(), CmpEdges() );
1202 edges.push_back(tmp); // after this point we do not add
1203 // any elements to edges, thus we can use pointers
1207 y_max = MIN( y_max, size.height );
1209 for( y = e->y0; y < y_max; y++ )
1211 PolyEdge *last, *prelast, *keep_prelast;
1214 int clipline = y < 0;
1218 while( last || e->y0 == y )
1220 if( last && last->y1 == y )
1222 // exclude edge if y reachs its lower point
1223 prelast->next = last->next;
1227 keep_prelast = prelast;
1228 if( last && (e->y0 > y || last->x < e->x) )
1230 // go to the next edge in active list
1234 else if( i < total )
1236 // insert new edge into active list if y reachs its upper point
1249 // convert x's from fixed-point to image coordinates
1250 uchar *timg = img.data + y * img.step;
1251 int x1 = keep_prelast->x;
1252 int x2 = prelast->x;
1262 x1 = (x1 + XY_ONE - 1) >> XY_SHIFT;
1263 x2 = x2 >> XY_SHIFT;
1265 // clip and draw the line
1266 if( x1 < size.width && x2 >= 0 )
1270 if( x2 >= size.width )
1271 x2 = size.width - 1;
1272 ICV_HLINE( timg, x1, x2, color, pix_size );
1275 keep_prelast->x += keep_prelast->dx;
1276 prelast->x += prelast->dx;
1281 // sort edges (using bubble sort)
1289 while( last != keep_prelast && last->next != 0 )
1291 PolyEdge *te = last->next;
1294 if( last->x > te->x )
1297 last->next = te->next;
1308 keep_prelast = prelast;
1310 while( sort_flag && keep_prelast != tmp.next && keep_prelast != &tmp );
1315 /* draws simple or filled circle */
1317 Circle( Mat& img, Point center, int radius, const void* color, int fill )
1319 Size size = img.size();
1320 size_t step = img.step;
1321 int pix_size = (int)img.elemSize();
1322 uchar* ptr = img.data;
1323 int err = 0, dx = radius, dy = 0, plus = 1, minus = (radius << 1) - 1;
1324 int inside = center.x >= radius && center.x < size.width - radius &&
1325 center.y >= radius && center.y < size.height - radius;
1327 #define ICV_PUT_POINT( ptr, x ) \
1328 memcpy( ptr + (x)*pix_size, color, pix_size );
1333 int y11 = center.y - dy, y12 = center.y + dy, y21 = center.y - dx, y22 = center.y + dx;
1334 int x11 = center.x - dx, x12 = center.x + dx, x21 = center.x - dy, x22 = center.x + dy;
1338 uchar *tptr0 = ptr + y11 * step;
1339 uchar *tptr1 = ptr + y12 * step;
1343 ICV_PUT_POINT( tptr0, x11 );
1344 ICV_PUT_POINT( tptr1, x11 );
1345 ICV_PUT_POINT( tptr0, x12 );
1346 ICV_PUT_POINT( tptr1, x12 );
1350 ICV_HLINE( tptr0, x11, x12, color, pix_size );
1351 ICV_HLINE( tptr1, x11, x12, color, pix_size );
1354 tptr0 = ptr + y21 * step;
1355 tptr1 = ptr + y22 * step;
1359 ICV_PUT_POINT( tptr0, x21 );
1360 ICV_PUT_POINT( tptr1, x21 );
1361 ICV_PUT_POINT( tptr0, x22 );
1362 ICV_PUT_POINT( tptr1, x22 );
1366 ICV_HLINE( tptr0, x21, x22, color, pix_size );
1367 ICV_HLINE( tptr1, x21, x22, color, pix_size );
1370 else if( x11 < size.width && x12 >= 0 && y21 < size.height && y22 >= 0 )
1374 x11 = std::max( x11, 0 );
1375 x12 = MIN( x12, size.width - 1 );
1378 if( (unsigned)y11 < (unsigned)size.height )
1380 uchar *tptr = ptr + y11 * step;
1385 ICV_PUT_POINT( tptr, x11 );
1386 if( x12 < size.width )
1387 ICV_PUT_POINT( tptr, x12 );
1390 ICV_HLINE( tptr, x11, x12, color, pix_size );
1393 if( (unsigned)y12 < (unsigned)size.height )
1395 uchar *tptr = ptr + y12 * step;
1400 ICV_PUT_POINT( tptr, x11 );
1401 if( x12 < size.width )
1402 ICV_PUT_POINT( tptr, x12 );
1405 ICV_HLINE( tptr, x11, x12, color, pix_size );
1408 if( x21 < size.width && x22 >= 0 )
1412 x21 = std::max( x21, 0 );
1413 x22 = MIN( x22, size.width - 1 );
1416 if( (unsigned)y21 < (unsigned)size.height )
1418 uchar *tptr = ptr + y21 * step;
1423 ICV_PUT_POINT( tptr, x21 );
1424 if( x22 < size.width )
1425 ICV_PUT_POINT( tptr, x22 );
1428 ICV_HLINE( tptr, x21, x22, color, pix_size );
1431 if( (unsigned)y22 < (unsigned)size.height )
1433 uchar *tptr = ptr + y22 * step;
1438 ICV_PUT_POINT( tptr, x21 );
1439 if( x22 < size.width )
1440 ICV_PUT_POINT( tptr, x22 );
1443 ICV_HLINE( tptr, x21, x22, color, pix_size );
1451 mask = (err <= 0) - 1;
1453 err -= minus & mask;
1458 #undef ICV_PUT_POINT
1463 ThickLine( Mat& img, Point p0, Point p1, const void* color,
1464 int thickness, int line_type, int flags, int shift )
1466 static const double INV_XY_ONE = 1./XY_ONE;
1468 p0.x <<= XY_SHIFT - shift;
1469 p0.y <<= XY_SHIFT - shift;
1470 p1.x <<= XY_SHIFT - shift;
1471 p1.y <<= XY_SHIFT - shift;
1473 if( thickness <= 1 )
1475 if( line_type < CV_AA )
1477 if( line_type == 1 || line_type == 4 || shift == 0 )
1479 p0.x = (p0.x + (XY_ONE>>1)) >> XY_SHIFT;
1480 p0.y = (p0.y + (XY_ONE>>1)) >> XY_SHIFT;
1481 p1.x = (p1.x + (XY_ONE>>1)) >> XY_SHIFT;
1482 p1.y = (p1.y + (XY_ONE>>1)) >> XY_SHIFT;
1483 Line( img, p0, p1, color, line_type );
1486 Line2( img, p0, p1, color );
1489 LineAA( img, p0, p1, color );
1493 Point pt[4], dp = Point(0,0);
1494 double dx = (p0.x - p1.x)*INV_XY_ONE, dy = (p1.y - p0.y)*INV_XY_ONE;
1495 double r = dx * dx + dy * dy;
1496 int i, oddThickness = thickness & 1;
1497 thickness <<= XY_SHIFT - 1;
1499 if( fabs(r) > DBL_EPSILON )
1501 r = (thickness + oddThickness*XY_ONE*0.5)/std::sqrt(r);
1502 dp.x = cvRound( dy * r );
1503 dp.y = cvRound( dx * r );
1505 pt[0].x = p0.x + dp.x;
1506 pt[0].y = p0.y + dp.y;
1507 pt[1].x = p0.x - dp.x;
1508 pt[1].y = p0.y - dp.y;
1509 pt[2].x = p1.x - dp.x;
1510 pt[2].y = p1.y - dp.y;
1511 pt[3].x = p1.x + dp.x;
1512 pt[3].y = p1.y + dp.y;
1514 FillConvexPoly( img, pt, 4, color, line_type, XY_SHIFT );
1517 for( i = 0; i < 2; i++ )
1521 if( line_type < CV_AA )
1524 center.x = (p0.x + (XY_ONE>>1)) >> XY_SHIFT;
1525 center.y = (p0.y + (XY_ONE>>1)) >> XY_SHIFT;
1526 Circle( img, center, (thickness + (XY_ONE>>1)) >> XY_SHIFT, color, 1 );
1530 EllipseEx( img, p0, cvSize(thickness, thickness),
1531 0, 0, 360, color, -1, line_type );
1541 PolyLine( Mat& img, const Point* v, int count, bool is_closed,
1542 const void* color, int thickness,
1543 int line_type, int shift )
1545 if( !v || count <= 0 )
1548 int i = is_closed ? count - 1 : 0;
1549 int flags = 2 + !is_closed;
1551 CV_Assert( 0 <= shift && shift <= XY_SHIFT && thickness >= 0 );
1554 for( i = !is_closed; i < count; i++ )
1557 ThickLine( img, p0, p, color, thickness, line_type, flags, shift );
1563 /****************************************************************************************\
1564 * External functions *
1565 \****************************************************************************************/
1567 void line( Mat& img, Point pt1, Point pt2, const Scalar& color,
1568 int thickness, int line_type, int shift )
1570 if( line_type == CV_AA && img.depth() != CV_8U )
1573 CV_Assert( 0 <= thickness && thickness <= 255 );
1574 CV_Assert( 0 <= shift && shift <= XY_SHIFT );
1577 scalarToRawData( color, buf, img.type(), 0 );
1578 ThickLine( img, pt1, pt2, buf, thickness, line_type, 3, shift );
1581 void rectangle( Mat& img, Point pt1, Point pt2,
1582 const Scalar& color, int thickness,
1583 int lineType, int shift )
1585 if( lineType == CV_AA && img.depth() != CV_8U )
1588 CV_Assert( thickness <= 255 );
1589 CV_Assert( 0 <= shift && shift <= XY_SHIFT );
1592 scalarToRawData(color, buf, img.type(), 0);
1603 if( thickness >= 0 )
1604 PolyLine( img, pt, 4, true, buf, thickness, lineType, shift );
1606 FillConvexPoly( img, pt, 4, buf, lineType, shift );
1610 void rectangle( Mat& img, Rect rec,
1611 const Scalar& color, int thickness,
1612 int lineType, int shift )
1614 CV_Assert( 0 <= shift && shift <= XY_SHIFT );
1615 if( rec.area() > 0 )
1616 rectangle( img, rec.tl(), rec.br() - Point(1<<shift,1<<shift),
1617 color, thickness, lineType, shift );
1621 void circle( Mat& img, Point center, int radius,
1622 const Scalar& color, int thickness, int line_type, int shift )
1624 if( line_type == CV_AA && img.depth() != CV_8U )
1627 CV_Assert( radius >= 0 && thickness <= 255 &&
1628 0 <= shift && shift <= XY_SHIFT );
1631 scalarToRawData(color, buf, img.type(), 0);
1633 if( thickness > 1 || line_type >= CV_AA )
1635 center.x <<= XY_SHIFT - shift;
1636 center.y <<= XY_SHIFT - shift;
1637 radius <<= XY_SHIFT - shift;
1638 EllipseEx( img, center, Size(radius, radius),
1639 0, 0, 360, buf, thickness, line_type );
1642 Circle( img, center, radius, buf, thickness < 0 );
1646 void ellipse( Mat& img, Point center, Size axes,
1647 double angle, double start_angle, double end_angle,
1648 const Scalar& color, int thickness, int line_type, int shift )
1650 if( line_type == CV_AA && img.depth() != CV_8U )
1653 CV_Assert( axes.width >= 0 && axes.height >= 0 &&
1654 thickness <= 255 && 0 <= shift && shift <= XY_SHIFT );
1657 scalarToRawData(color, buf, img.type(), 0);
1659 int _angle = cvRound(angle);
1660 int _start_angle = cvRound(start_angle);
1661 int _end_angle = cvRound(end_angle);
1662 center.x <<= XY_SHIFT - shift;
1663 center.y <<= XY_SHIFT - shift;
1664 axes.width <<= XY_SHIFT - shift;
1665 axes.height <<= XY_SHIFT - shift;
1667 EllipseEx( img, center, axes, _angle, _start_angle,
1668 _end_angle, buf, thickness, line_type );
1671 void ellipse(Mat& img, const RotatedRect& box, const Scalar& color,
1672 int thickness, int lineType)
1674 if( lineType == CV_AA && img.depth() != CV_8U )
1677 CV_Assert( box.size.width >= 0 && box.size.height >= 0 &&
1681 scalarToRawData(color, buf, img.type(), 0);
1683 int _angle = cvRound(box.angle);
1684 Point center(cvRound(box.center.x*(1 << XY_SHIFT)),
1685 cvRound(box.center.y*(1 << XY_SHIFT)));
1686 Size axes(cvRound(box.size.width*(1 << (XY_SHIFT - 1))),
1687 cvRound(box.size.height*(1 << (XY_SHIFT - 1))));
1688 EllipseEx( img, center, axes, _angle, 0, 360, buf, thickness, lineType );
1691 void fillConvexPoly( Mat& img, const Point* pts, int npts,
1692 const Scalar& color, int line_type, int shift )
1694 if( !pts || npts <= 0 )
1697 if( line_type == CV_AA && img.depth() != CV_8U )
1701 CV_Assert( 0 <= shift && shift <= XY_SHIFT );
1702 scalarToRawData(color, buf, img.type(), 0);
1703 FillConvexPoly( img, pts, npts, buf, line_type, shift );
1707 void fillPoly( Mat& img, const Point** pts, const int* npts, int ncontours,
1708 const Scalar& color, int line_type,
1709 int shift, Point offset )
1711 if( line_type == CV_AA && img.depth() != CV_8U )
1714 CV_Assert( pts && npts && ncontours >= 0 && 0 <= shift && shift <= XY_SHIFT );
1717 scalarToRawData(color, buf, img.type(), 0);
1719 vector<PolyEdge> edges;
1722 for( i = 0; i < ncontours; i++ )
1725 edges.reserve( total + 1 );
1726 for( i = 0; i < ncontours; i++ )
1727 CollectPolyEdges( img, pts[i], npts[i], edges, buf, line_type, shift, offset );
1729 FillEdgeCollection(img, edges, buf);
1733 void polylines( Mat& img, const Point** pts, const int* npts, int ncontours, bool isClosed,
1734 const Scalar& color, int thickness, int line_type, int shift )
1736 if( line_type == CV_AA && img.depth() != CV_8U )
1739 CV_Assert( pts && npts && ncontours >= 0 &&
1740 0 <= thickness && thickness <= 255 &&
1741 0 <= shift && shift <= XY_SHIFT );
1744 scalarToRawData( color, buf, img.type(), 0 );
1746 for( int i = 0; i < ncontours; i++ )
1747 PolyLine( img, pts[i], npts[i], isClosed, buf, thickness, line_type, shift );
1751 enum { FONT_SIZE_SHIFT=8, FONT_ITALIC_ALPHA=(1 << 8),
1752 FONT_ITALIC_DIGIT=(2 << 8), FONT_ITALIC_PUNCT=(4 << 8),
1753 FONT_ITALIC_BRACES=(8 << 8), FONT_HAVE_GREEK=(16 << 8),
1754 FONT_HAVE_CYRILLIC=(32 << 8) };
1756 static const int HersheyPlain[] = {
1757 (5 + 4*16) + FONT_HAVE_GREEK,
1758 199, 214, 217, 233, 219, 197, 234, 216, 221, 222, 228, 225, 211, 224, 210, 220,
1759 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 212, 213, 191, 226, 192,
1760 215, 190, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
1761 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 193, 84,
1762 194, 85, 86, 87, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
1763 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
1764 195, 223, 196, 88 };
1766 static const int HersheyPlainItalic[] = {
1767 (5 + 4*16) + FONT_ITALIC_ALPHA + FONT_HAVE_GREEK,
1768 199, 214, 217, 233, 219, 197, 234, 216, 221, 222, 228, 225, 211, 224, 210, 220,
1769 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 212, 213, 191, 226, 192,
1770 215, 190, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
1771 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 193, 84,
1772 194, 85, 86, 87, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161,
1773 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176,
1774 195, 223, 196, 88 };
1776 static const int HersheyComplexSmall[] = {
1777 (6 + 7*16) + FONT_HAVE_GREEK,
1778 1199, 1214, 1217, 1275, 1274, 1271, 1272, 1216, 1221, 1222, 1219, 1232, 1211, 1231, 1210, 1220,
1779 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1212, 2213, 1241, 1238, 1242,
1780 1215, 1273, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013,
1781 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1223, 1084,
1782 1224, 1247, 586, 1249, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111,
1783 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126,
1784 1225, 1229, 1226, 1246 };
1786 static const int HersheyComplexSmallItalic[] = {
1787 (6 + 7*16) + FONT_ITALIC_ALPHA + FONT_HAVE_GREEK,
1788 1199, 1214, 1217, 1275, 1274, 1271, 1272, 1216, 1221, 1222, 1219, 1232, 1211, 1231, 1210, 1220,
1789 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1212, 1213, 1241, 1238, 1242,
1790 1215, 1273, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063,
1791 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1223, 1084,
1792 1224, 1247, 586, 1249, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161,
1793 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176,
1794 1225, 1229, 1226, 1246 };
1796 static const int HersheySimplex[] = {
1797 (9 + 12*16) + FONT_HAVE_GREEK,
1798 2199, 714, 717, 733, 719, 697, 734, 716, 721, 722, 728, 725, 711, 724, 710, 720,
1799 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 712, 713, 691, 726, 692,
1800 715, 690, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513,
1801 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 693, 584,
1802 694, 2247, 586, 2249, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611,
1803 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626,
1804 695, 723, 696, 2246 };
1806 static const int HersheyDuplex[] = {
1807 (9 + 12*16) + FONT_HAVE_GREEK,
1808 2199, 2714, 2728, 2732, 2719, 2733, 2718, 2727, 2721, 2722, 2723, 2725, 2711, 2724, 2710, 2720,
1809 2700, 2701, 2702, 2703, 2704, 2705, 2706, 2707, 2708, 2709, 2712, 2713, 2730, 2726, 2731,
1810 2715, 2734, 2501, 2502, 2503, 2504, 2505, 2506, 2507, 2508, 2509, 2510, 2511, 2512, 2513,
1811 2514, 2515, 2516, 2517, 2518, 2519, 2520, 2521, 2522, 2523, 2524, 2525, 2526, 2223, 2084,
1812 2224, 2247, 587, 2249, 2601, 2602, 2603, 2604, 2605, 2606, 2607, 2608, 2609, 2610, 2611,
1813 2612, 2613, 2614, 2615, 2616, 2617, 2618, 2619, 2620, 2621, 2622, 2623, 2624, 2625, 2626,
1814 2225, 2229, 2226, 2246 };
1816 static const int HersheyComplex[] = {
1817 (9 + 12*16) + FONT_HAVE_GREEK + FONT_HAVE_CYRILLIC,
1818 2199, 2214, 2217, 2275, 2274, 2271, 2272, 2216, 2221, 2222, 2219, 2232, 2211, 2231, 2210, 2220,
1819 2200, 2201, 2202, 2203, 2204, 2205, 2206, 2207, 2208, 2209, 2212, 2213, 2241, 2238, 2242,
1820 2215, 2273, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013,
1821 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2223, 2084,
1822 2224, 2247, 587, 2249, 2101, 2102, 2103, 2104, 2105, 2106, 2107, 2108, 2109, 2110, 2111,
1823 2112, 2113, 2114, 2115, 2116, 2117, 2118, 2119, 2120, 2121, 2122, 2123, 2124, 2125, 2126,
1824 2225, 2229, 2226, 2246 };
1826 static const int HersheyComplexItalic[] = {
1827 (9 + 12*16) + FONT_ITALIC_ALPHA + FONT_ITALIC_DIGIT + FONT_ITALIC_PUNCT +
1828 FONT_HAVE_GREEK + FONT_HAVE_CYRILLIC,
1829 2199, 2764, 2778, 2782, 2769, 2783, 2768, 2777, 2771, 2772, 2219, 2232, 2211, 2231, 2210, 2220,
1830 2750, 2751, 2752, 2753, 2754, 2755, 2756, 2757, 2758, 2759, 2212, 2213, 2241, 2238, 2242,
1831 2765, 2273, 2051, 2052, 2053, 2054, 2055, 2056, 2057, 2058, 2059, 2060, 2061, 2062, 2063,
1832 2064, 2065, 2066, 2067, 2068, 2069, 2070, 2071, 2072, 2073, 2074, 2075, 2076, 2223, 2084,
1833 2224, 2247, 587, 2249, 2151, 2152, 2153, 2154, 2155, 2156, 2157, 2158, 2159, 2160, 2161,
1834 2162, 2163, 2164, 2165, 2166, 2167, 2168, 2169, 2170, 2171, 2172, 2173, 2174, 2175, 2176,
1835 2225, 2229, 2226, 2246 };
1837 static const int HersheyTriplex[] = {
1838 (9 + 12*16) + FONT_HAVE_GREEK,
1839 2199, 3214, 3228, 3232, 3219, 3233, 3218, 3227, 3221, 3222, 3223, 3225, 3211, 3224, 3210, 3220,
1840 3200, 3201, 3202, 3203, 3204, 3205, 3206, 3207, 3208, 3209, 3212, 3213, 3230, 3226, 3231,
1841 3215, 3234, 3001, 3002, 3003, 3004, 3005, 3006, 3007, 3008, 3009, 3010, 3011, 3012, 3013,
1842 2014, 3015, 3016, 3017, 3018, 3019, 3020, 3021, 3022, 3023, 3024, 3025, 3026, 2223, 2084,
1843 2224, 2247, 587, 2249, 3101, 3102, 3103, 3104, 3105, 3106, 3107, 3108, 3109, 3110, 3111,
1844 3112, 3113, 3114, 3115, 3116, 3117, 3118, 3119, 3120, 3121, 3122, 3123, 3124, 3125, 3126,
1845 2225, 2229, 2226, 2246 };
1847 static const int HersheyTriplexItalic[] = {
1848 (9 + 12*16) + FONT_ITALIC_ALPHA + FONT_ITALIC_DIGIT +
1849 FONT_ITALIC_PUNCT + FONT_HAVE_GREEK,
1850 2199, 3264, 3278, 3282, 3269, 3233, 3268, 3277, 3271, 3272, 3223, 3225, 3261, 3224, 3260, 3270,
1851 3250, 3251, 3252, 3253, 3254, 3255, 3256, 3257, 3258, 3259, 3262, 3263, 3230, 3226, 3231,
1852 3265, 3234, 3051, 3052, 3053, 3054, 3055, 3056, 3057, 3058, 3059, 3060, 3061, 3062, 3063,
1853 2064, 3065, 3066, 3067, 3068, 3069, 3070, 3071, 3072, 3073, 3074, 3075, 3076, 2223, 2084,
1854 2224, 2247, 587, 2249, 3151, 3152, 3153, 3154, 3155, 3156, 3157, 3158, 3159, 3160, 3161,
1855 3162, 3163, 3164, 3165, 3166, 3167, 3168, 3169, 3170, 3171, 3172, 3173, 3174, 3175, 3176,
1856 2225, 2229, 2226, 2246 };
1858 static const int HersheyScriptSimplex[] = {
1859 (9 + 12*16) + FONT_ITALIC_ALPHA + FONT_HAVE_GREEK,
1860 2199, 714, 717, 733, 719, 697, 734, 716, 721, 722, 728, 725, 711, 724, 710, 720,
1861 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 712, 713, 691, 726, 692,
1862 715, 690, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563,
1863 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 693, 584,
1864 694, 2247, 586, 2249, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661,
1865 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676,
1866 695, 723, 696, 2246 };
1868 static const int HersheyScriptComplex[] = {
1869 (9 + 12*16) + FONT_ITALIC_ALPHA + FONT_ITALIC_DIGIT + FONT_ITALIC_PUNCT + FONT_HAVE_GREEK,
1870 2199, 2764, 2778, 2782, 2769, 2783, 2768, 2777, 2771, 2772, 2219, 2232, 2211, 2231, 2210, 2220,
1871 2750, 2751, 2752, 2753, 2754, 2755, 2756, 2757, 2758, 2759, 2212, 2213, 2241, 2238, 2242,
1872 2215, 2273, 2551, 2552, 2553, 2554, 2555, 2556, 2557, 2558, 2559, 2560, 2561, 2562, 2563,
1873 2564, 2565, 2566, 2567, 2568, 2569, 2570, 2571, 2572, 2573, 2574, 2575, 2576, 2223, 2084,
1874 2224, 2247, 586, 2249, 2651, 2652, 2653, 2654, 2655, 2656, 2657, 2658, 2659, 2660, 2661,
1875 2662, 2663, 2664, 2665, 2666, 2667, 2668, 2669, 2670, 2671, 2672, 2673, 2674, 2675, 2676,
1876 2225, 2229, 2226, 2246 };
1879 static const int* getFontData(int fontFace)
1881 bool isItalic = (fontFace & FONT_ITALIC) != 0;
1882 const int* ascii = 0;
1884 switch( fontFace & 15 )
1886 case FONT_HERSHEY_SIMPLEX:
1887 ascii = HersheySimplex;
1889 case FONT_HERSHEY_PLAIN:
1890 ascii = !isItalic ? HersheyPlain : HersheyPlainItalic;
1892 case FONT_HERSHEY_DUPLEX:
1893 ascii = HersheyDuplex;
1895 case FONT_HERSHEY_COMPLEX:
1896 ascii = !isItalic ? HersheyComplex : HersheyComplexItalic;
1898 case FONT_HERSHEY_TRIPLEX:
1899 ascii = !isItalic ? HersheyTriplex : HersheyTriplexItalic;
1901 case FONT_HERSHEY_COMPLEX_SMALL:
1902 ascii = !isItalic ? HersheyComplexSmall : HersheyComplexSmallItalic;
1904 case FONT_HERSHEY_SCRIPT_SIMPLEX:
1905 ascii = HersheyScriptSimplex;
1907 case FONT_HERSHEY_SCRIPT_COMPLEX:
1908 ascii = HersheyScriptComplex;
1911 CV_Error( CV_StsOutOfRange, "Unknown font type" );
1917 void putText( Mat& img, const string& text, Point org,
1918 int fontFace, double fontScale, Scalar color,
1919 int thickness, int line_type, bool bottomLeftOrigin )
1922 const int* ascii = getFontData(fontFace);
1925 scalarToRawData(color, buf, img.type(), 0);
1927 int base_line = -(ascii[0] & 15);
1928 int hscale = cvRound(fontScale*XY_ONE), vscale = hscale;
1930 if( line_type == CV_AA && img.depth() != CV_8U )
1933 if( bottomLeftOrigin )
1936 int view_x = org.x << XY_SHIFT;
1937 int view_y = (org.y << XY_SHIFT) + base_line*vscale;
1939 pts.reserve(1 << 10);
1940 const char **faces = cv::g_HersheyGlyphs;
1942 for( int i = 0; text[i] != '\0'; i++ )
1944 int c = (uchar)text[i];
1947 if( c >= 127 || c < ' ' )
1950 const char* ptr = faces[ascii[(c-' ')+1]];
1951 p.x = (uchar)ptr[0] - 'R';
1952 p.y = (uchar)ptr[1] - 'R';
1953 int dx = p.y*hscale;
1954 view_x -= p.x*hscale;
1959 if( *ptr == ' ' || !*ptr )
1961 if( pts.size() > 1 )
1962 PolyLine( img, &pts[0], (int)pts.size(), false, buf, thickness, line_type, XY_SHIFT );
1969 p.x = (uchar)ptr[0] - 'R';
1970 p.y = (uchar)ptr[1] - 'R';
1972 pts.push_back(Point(p.x*hscale + view_x, p.y*vscale + view_y));
1979 Size getTextSize( const string& text, int fontFace, double fontScale, int thickness, int* _base_line)
1983 const char **faces = cv::g_HersheyGlyphs;
1984 const int* ascii = getFontData(fontFace);
1986 int base_line = (ascii[0] & 15);
1987 int cap_line = (ascii[0] >> 4) & 15;
1988 size.height = cvRound((cap_line + base_line)*fontScale + (thickness+1)/2);
1990 for( int i = 0; text[i] != '\0'; i++ )
1992 int c = (uchar)text[i];
1995 if( c >= 127 || c < ' ' )
1998 const char* ptr = faces[ascii[(c-' ')+1]];
1999 p.x = (uchar)ptr[0] - 'R';
2000 p.y = (uchar)ptr[1] - 'R';
2001 view_x += (p.y - p.x)*fontScale;
2004 size.width = cvRound(view_x + thickness);
2006 *_base_line = cvRound(base_line*fontScale + thickness*0.5);
2013 void cv::fillConvexPoly(InputOutputArray _img, InputArray _points,
2014 const Scalar& color, int lineType, int shift)
2016 Mat img = _img.getMat(), points = _points.getMat();
2017 CV_Assert(points.checkVector(2, CV_32S) >= 0);
2018 fillConvexPoly(img, (const Point*)points.data, points.rows*points.cols*points.channels()/2, color, lineType, shift);
2022 void cv::fillPoly(InputOutputArray _img, InputArrayOfArrays pts,
2023 const Scalar& color, int lineType, int shift, Point offset)
2025 Mat img = _img.getMat();
2026 int i, ncontours = (int)pts.total();
2027 if( ncontours == 0 )
2029 AutoBuffer<Point*> _ptsptr(ncontours);
2030 AutoBuffer<int> _npts(ncontours);
2031 Point** ptsptr = _ptsptr;
2034 for( i = 0; i < ncontours; i++ )
2036 Mat p = pts.getMat(i);
2037 CV_Assert(p.checkVector(2, CV_32S) >= 0);
2038 ptsptr[i] = (Point*)p.data;
2039 npts[i] = p.rows*p.cols*p.channels()/2;
2041 fillPoly(img, (const Point**)ptsptr, npts, (int)ncontours, color, lineType, shift, offset);
2045 void cv::polylines(InputOutputArray _img, InputArrayOfArrays pts,
2046 bool isClosed, const Scalar& color,
2047 int thickness, int lineType, int shift )
2049 Mat img = _img.getMat();
2050 bool manyContours = pts.kind() == _InputArray::STD_VECTOR_VECTOR ||
2051 pts.kind() == _InputArray::STD_VECTOR_MAT;
2052 int i, ncontours = manyContours ? (int)pts.total() : 1;
2053 if( ncontours == 0 )
2055 AutoBuffer<Point*> _ptsptr(ncontours);
2056 AutoBuffer<int> _npts(ncontours);
2057 Point** ptsptr = _ptsptr;
2060 for( i = 0; i < ncontours; i++ )
2062 Mat p = pts.getMat(manyContours ? i : -1);
2063 if( p.total() == 0 )
2065 CV_Assert(p.checkVector(2, CV_32S) >= 0);
2066 ptsptr[i] = (Point*)p.data;
2067 npts[i] = p.rows*p.cols*p.channels()/2;
2069 polylines(img, (const Point**)ptsptr, npts, (int)ncontours, isClosed, color, thickness, lineType, shift);
2073 static const int CodeDeltas[8][2] =
2074 { {1, 0}, {1, -1}, {0, -1}, {-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1} };
2076 #define CV_ADJUST_EDGE_COUNT( count, seq ) \
2077 ((count) -= ((count) == (seq)->total && !CV_IS_SEQ_CLOSED(seq)))
2080 cvDrawContours( void* _img, CvSeq* contour,
2081 CvScalar _externalColor, CvScalar _holeColor,
2082 int maxLevel, int thickness,
2083 int line_type, CvPoint _offset )
2085 CvSeq *contour0 = contour, *h_next = 0;
2086 CvTreeNodeIterator iterator;
2087 cv::vector<cv::PolyEdge> edges;
2088 cv::vector<cv::Point> pts;
2089 cv::Scalar externalColor = _externalColor, holeColor = _holeColor;
2090 cv::Mat img = cv::cvarrToMat(_img);
2091 cv::Point offset = _offset;
2092 double ext_buf[4], hole_buf[4];
2094 if( line_type == CV_AA && img.depth() != CV_8U )
2100 CV_Assert( thickness <= 255 );
2102 scalarToRawData( externalColor, ext_buf, img.type(), 0 );
2103 scalarToRawData( holeColor, hole_buf, img.type(), 0 );
2105 maxLevel = MAX(maxLevel, INT_MIN+2);
2106 maxLevel = MIN(maxLevel, INT_MAX-1);
2110 h_next = contour->h_next;
2111 contour->h_next = 0;
2112 maxLevel = -maxLevel+1;
2115 cvInitTreeNodeIterator( &iterator, contour, maxLevel );
2116 while( (contour = (CvSeq*)cvNextTreeNode( &iterator )) != 0 )
2119 int i, count = contour->total;
2120 int elem_type = CV_MAT_TYPE(contour->flags);
2121 void* clr = (contour->flags & CV_SEQ_FLAG_HOLE) == 0 ? ext_buf : hole_buf;
2123 cvStartReadSeq( contour, &reader, 0 );
2127 if( CV_IS_SEQ_CHAIN_CONTOUR( contour ))
2129 cv::Point pt = ((CvChain*)contour)->origin;
2130 cv::Point prev_pt = pt;
2131 char prev_code = reader.ptr ? reader.ptr[0] : '\0';
2135 for( i = 0; i < count; i++ )
2138 CV_READ_SEQ_ELEM( code, reader );
2140 assert( (code & ~7) == 0 );
2142 if( code != prev_code )
2145 if( thickness >= 0 )
2146 cv::ThickLine( img, prev_pt, pt, clr, thickness, line_type, 2, 0 );
2152 pt.x += CodeDeltas[(int)code][0];
2153 pt.y += CodeDeltas[(int)code][1];
2156 if( thickness >= 0 )
2157 cv::ThickLine( img, prev_pt,
2158 cv::Point(((CvChain*)contour)->origin) + offset,
2159 clr, thickness, line_type, 2, 0 );
2161 cv::CollectPolyEdges(img, &pts[0], (int)pts.size(),
2162 edges, ext_buf, line_type, 0, offset);
2164 else if( CV_IS_SEQ_POLYLINE( contour ))
2166 CV_Assert( elem_type == CV_32SC2 );
2170 count -= !CV_IS_SEQ_CLOSED(contour);
2171 CV_READ_SEQ_ELEM( pt1, reader );
2176 for( i = 0; i < count; i++ )
2178 CV_READ_SEQ_ELEM( pt2, reader );
2180 if( thickness >= 0 )
2181 cv::ThickLine( img, pt1, pt2, clr, thickness, line_type, 2, shift );
2187 cv::CollectPolyEdges( img, &pts[0], (int)pts.size(),
2188 edges, ext_buf, line_type, 0, cv::Point() );
2193 cv::FillEdgeCollection( img, edges, ext_buf );
2195 if( h_next && contour0 )
2196 contour0->h_next = h_next;
2200 cvClipLine( CvSize size, CvPoint* pt1, CvPoint* pt2 )
2202 CV_Assert( pt1 && pt2 );
2203 return cv::clipLine( size, *(cv::Point*)pt1, *(cv::Point*)pt2 );
2208 cvEllipse2Poly( CvPoint center, CvSize axes, int angle,
2209 int arc_start, int arc_end, CvPoint* _pts, int delta )
2211 cv::vector<cv::Point> pts;
2212 cv::ellipse2Poly( center, axes, angle, arc_start, arc_end, delta, pts );
2213 memcpy( _pts, &pts[0], pts.size()*sizeof(_pts[0]) );
2214 return (int)pts.size();
2218 cvColorToScalar( double packed_color, int type )
2222 if( CV_MAT_DEPTH( type ) == CV_8U )
2224 int icolor = cvRound( packed_color );
2225 if( CV_MAT_CN( type ) > 1 )
2227 scalar.val[0] = icolor & 255;
2228 scalar.val[1] = (icolor >> 8) & 255;
2229 scalar.val[2] = (icolor >> 16) & 255;
2230 scalar.val[3] = (icolor >> 24) & 255;
2234 scalar.val[0] = CV_CAST_8U( icolor );
2235 scalar.val[1] = scalar.val[2] = scalar.val[3] = 0;
2238 else if( CV_MAT_DEPTH( type ) == CV_8S )
2240 int icolor = cvRound( packed_color );
2241 if( CV_MAT_CN( type ) > 1 )
2243 scalar.val[0] = (char)icolor;
2244 scalar.val[1] = (char)(icolor >> 8);
2245 scalar.val[2] = (char)(icolor >> 16);
2246 scalar.val[3] = (char)(icolor >> 24);
2250 scalar.val[0] = CV_CAST_8S( icolor );
2251 scalar.val[1] = scalar.val[2] = scalar.val[3] = 0;
2256 int cn = CV_MAT_CN( type );
2260 scalar.val[0] = packed_color;
2261 scalar.val[1] = scalar.val[2] = scalar.val[3] = 0;
2264 scalar.val[0] = scalar.val[1] = packed_color;
2265 scalar.val[2] = scalar.val[3] = 0;
2268 scalar.val[0] = scalar.val[1] = scalar.val[2] = packed_color;
2272 scalar.val[0] = scalar.val[1] =
2273 scalar.val[2] = scalar.val[3] = packed_color;
2282 cvInitLineIterator( const CvArr* img, CvPoint pt1, CvPoint pt2,
2283 CvLineIterator* iterator, int connectivity,
2286 CV_Assert( iterator != 0 );
2287 cv::LineIterator li(cv::cvarrToMat(img), pt1, pt2, connectivity, left_to_right!=0);
2289 iterator->err = li.err;
2290 iterator->minus_delta = li.minusDelta;
2291 iterator->plus_delta = li.plusDelta;
2292 iterator->minus_step = li.minusStep;
2293 iterator->plus_step = li.plusStep;
2294 iterator->ptr = li.ptr;
2300 cvLine( CvArr* _img, CvPoint pt1, CvPoint pt2, CvScalar color,
2301 int thickness, int line_type, int shift )
2303 cv::Mat img = cv::cvarrToMat(_img);
2304 cv::line( img, pt1, pt2, color, thickness, line_type, shift );
2308 cvRectangle( CvArr* _img, CvPoint pt1, CvPoint pt2,
2309 CvScalar color, int thickness,
2310 int line_type, int shift )
2312 cv::Mat img = cv::cvarrToMat(_img);
2313 cv::rectangle( img, pt1, pt2, color, thickness, line_type, shift );
2317 cvRectangleR( CvArr* _img, CvRect rec,
2318 CvScalar color, int thickness,
2319 int line_type, int shift )
2321 cv::Mat img = cv::cvarrToMat(_img);
2322 cv::rectangle( img, rec, color, thickness, line_type, shift );
2326 cvCircle( CvArr* _img, CvPoint center, int radius,
2327 CvScalar color, int thickness, int line_type, int shift )
2329 cv::Mat img = cv::cvarrToMat(_img);
2330 cv::circle( img, center, radius, color, thickness, line_type, shift );
2334 cvEllipse( CvArr* _img, CvPoint center, CvSize axes,
2335 double angle, double start_angle, double end_angle,
2336 CvScalar color, int thickness, int line_type, int shift )
2338 cv::Mat img = cv::cvarrToMat(_img);
2339 cv::ellipse( img, center, axes, angle, start_angle, end_angle,
2340 color, thickness, line_type, shift );
2344 cvFillConvexPoly( CvArr* _img, const CvPoint *pts, int npts,
2345 CvScalar color, int line_type, int shift )
2347 cv::Mat img = cv::cvarrToMat(_img);
2348 cv::fillConvexPoly( img, (const cv::Point*)pts, npts,
2349 color, line_type, shift );
2353 cvFillPoly( CvArr* _img, CvPoint **pts, const int *npts, int ncontours,
2354 CvScalar color, int line_type, int shift )
2356 cv::Mat img = cv::cvarrToMat(_img);
2358 cv::fillPoly( img, (const cv::Point**)pts, npts, ncontours, color, line_type, shift );
2362 cvPolyLine( CvArr* _img, CvPoint **pts, const int *npts,
2363 int ncontours, int closed, CvScalar color,
2364 int thickness, int line_type, int shift )
2366 cv::Mat img = cv::cvarrToMat(_img);
2368 cv::polylines( img, (const cv::Point**)pts, npts, ncontours,
2369 closed != 0, color, thickness, line_type, shift );
2373 cvPutText( CvArr* _img, const char *text, CvPoint org, const CvFont *_font, CvScalar color )
2375 cv::Mat img = cv::cvarrToMat(_img);
2376 CV_Assert( text != 0 && _font != 0);
2377 cv::putText( img, text, org, _font->font_face, (_font->hscale+_font->vscale)*0.5,
2378 color, _font->thickness, _font->line_type,
2379 CV_IS_IMAGE(_img) && ((IplImage*)_img)->origin != 0 );
2384 cvInitFont( CvFont *font, int font_face, double hscale, double vscale,
2385 double shear, int thickness, int line_type )
2387 CV_Assert( font != 0 && hscale > 0 && vscale > 0 && thickness >= 0 );
2389 font->ascii = cv::getFontData(font_face);
2390 font->font_face = font_face;
2391 font->hscale = (float)hscale;
2392 font->vscale = (float)vscale;
2393 font->thickness = thickness;
2394 font->shear = (float)shear;
2395 font->greek = font->cyrillic = 0;
2396 font->line_type = line_type;
2400 cvGetTextSize( const char *text, const CvFont *_font, CvSize *_size, int *_base_line )
2402 CV_Assert(text != 0 && _font != 0);
2403 cv::Size size = cv::getTextSize( text, _font->font_face, (_font->hscale + _font->vscale)*0.5,
2404 _font->thickness, _base_line );