imagecore 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. data/.gitignore +24 -0
  2. data/Gemfile +4 -0
  3. data/Rakefile +2 -0
  4. data/ext/imagecore/analyze_image.cxx +58 -0
  5. data/ext/imagecore/analyze_image.h +6 -0
  6. data/ext/imagecore/extconf.rb +9 -0
  7. data/ext/imagecore/imagecore.cxx +34 -0
  8. data/ext/opencv/core/___.c +3 -0
  9. data/ext/opencv/core/alloc.cpp +697 -0
  10. data/ext/opencv/core/array.cpp +3206 -0
  11. data/ext/opencv/core/datastructs.cpp +4064 -0
  12. data/ext/opencv/core/extconf.rb +22 -0
  13. data/ext/opencv/core/matrix.cpp +3777 -0
  14. data/ext/opencv/core/precomp.hpp +216 -0
  15. data/ext/opencv/core/system.cpp +832 -0
  16. data/ext/opencv/core/tables.cpp +3512 -0
  17. data/ext/opencv/highgui/___.c +3 -0
  18. data/ext/opencv/highgui/bitstrm.cpp +582 -0
  19. data/ext/opencv/highgui/bitstrm.hpp +182 -0
  20. data/ext/opencv/highgui/extconf.rb +28 -0
  21. data/ext/opencv/highgui/grfmt_base.cpp +128 -0
  22. data/ext/opencv/highgui/grfmt_base.hpp +113 -0
  23. data/ext/opencv/highgui/grfmt_bmp.cpp +564 -0
  24. data/ext/opencv/highgui/grfmt_bmp.hpp +99 -0
  25. data/ext/opencv/highgui/grfmt_exr.hpp +113 -0
  26. data/ext/opencv/highgui/grfmt_imageio.hpp +56 -0
  27. data/ext/opencv/highgui/grfmt_jpeg.cpp +622 -0
  28. data/ext/opencv/highgui/grfmt_jpeg.hpp +90 -0
  29. data/ext/opencv/highgui/grfmt_jpeg2000.cpp +529 -0
  30. data/ext/opencv/highgui/grfmt_jpeg2000.hpp +95 -0
  31. data/ext/opencv/highgui/grfmt_png.cpp +406 -0
  32. data/ext/opencv/highgui/grfmt_png.hpp +101 -0
  33. data/ext/opencv/highgui/grfmt_pxm.cpp +513 -0
  34. data/ext/opencv/highgui/grfmt_pxm.hpp +92 -0
  35. data/ext/opencv/highgui/grfmt_sunras.cpp +425 -0
  36. data/ext/opencv/highgui/grfmt_sunras.hpp +105 -0
  37. data/ext/opencv/highgui/grfmt_tiff.cpp +718 -0
  38. data/ext/opencv/highgui/grfmt_tiff.hpp +136 -0
  39. data/ext/opencv/highgui/grfmts.hpp +56 -0
  40. data/ext/opencv/highgui/loadsave.cpp +535 -0
  41. data/ext/opencv/highgui/precomp.hpp +223 -0
  42. data/ext/opencv/highgui/utils.cpp +689 -0
  43. data/ext/opencv/highgui/utils.hpp +128 -0
  44. data/ext/opencv/imgproc/___.c +3 -0
  45. data/ext/opencv/imgproc/_geom.h +72 -0
  46. data/ext/opencv/imgproc/color.cpp +3179 -0
  47. data/ext/opencv/imgproc/contours.cpp +1780 -0
  48. data/ext/opencv/imgproc/extconf.rb +11 -0
  49. data/ext/opencv/imgproc/filter.cpp +3063 -0
  50. data/ext/opencv/imgproc/precomp.hpp +159 -0
  51. data/ext/opencv/imgproc/shapedescr.cpp +1306 -0
  52. data/ext/opencv/imgproc/smooth.cpp +1566 -0
  53. data/ext/opencv/imgproc/tables.cpp +214 -0
  54. data/ext/opencv/imgproc/thresh.cpp +636 -0
  55. data/ext/opencv/imgproc/utils.cpp +242 -0
  56. data/ext/opencv/include/opencv2/core/core.hpp +4344 -0
  57. data/ext/opencv/include/opencv2/core/core_c.h +1885 -0
  58. data/ext/opencv/include/opencv2/core/internal.hpp +710 -0
  59. data/ext/opencv/include/opencv2/core/mat.hpp +2557 -0
  60. data/ext/opencv/include/opencv2/core/operations.hpp +3623 -0
  61. data/ext/opencv/include/opencv2/core/types_c.h +1875 -0
  62. data/ext/opencv/include/opencv2/core/version.hpp +58 -0
  63. data/ext/opencv/include/opencv2/highgui/highgui.hpp +198 -0
  64. data/ext/opencv/include/opencv2/highgui/highgui_c.h +506 -0
  65. data/ext/opencv/include/opencv2/imgproc/imgproc.hpp +1139 -0
  66. data/ext/opencv/include/opencv2/imgproc/imgproc_c.h +783 -0
  67. data/ext/opencv/include/opencv2/imgproc/types_c.h +538 -0
  68. data/imagecore.gemspec +20 -0
  69. data/lib/imagecore.rb +16 -0
  70. data/lib/imagecore/version.rb +3 -0
  71. metadata +119 -0
@@ -0,0 +1,3623 @@
1
+ /*M///////////////////////////////////////////////////////////////////////////////////////
2
+ //
3
+ // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4
+ //
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.
8
+ //
9
+ //
10
+ // License Agreement
11
+ // For Open Source Computer Vision Library
12
+ //
13
+ // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14
+ // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
15
+ // Third party copyrights are property of their respective owners.
16
+ //
17
+ // Redistribution and use in source and binary forms, with or without modification,
18
+ // are permitted provided that the following conditions are met:
19
+ //
20
+ // * Redistribution's of source code must retain the above copyright notice,
21
+ // this list of conditions and the following disclaimer.
22
+ //
23
+ // * Redistribution's in binary form must reproduce the above copyright notice,
24
+ // this list of conditions and the following disclaimer in the documentation
25
+ // and/or other materials provided with the distribution.
26
+ //
27
+ // * The name of the copyright holders may not be used to endorse or promote products
28
+ // derived from this software without specific prior written permission.
29
+ //
30
+ // This software is provided by the copyright holders and contributors "as is" and
31
+ // any express or implied warranties, including, but not limited to, the implied
32
+ // warranties of merchantability and fitness for a particular purpose are disclaimed.
33
+ // In no event shall the Intel Corporation or contributors be liable for any direct,
34
+ // indirect, incidental, special, exemplary, or consequential damages
35
+ // (including, but not limited to, procurement of substitute goods or services;
36
+ // loss of use, data, or profits; or business interruption) however caused
37
+ // and on any theory of liability, whether in contract, strict liability,
38
+ // or tort (including negligence or otherwise) arising in any way out of
39
+ // the use of this software, even if advised of the possibility of such damage.
40
+ //
41
+ //M*/
42
+
43
+ #ifndef __OPENCV_CORE_OPERATIONS_HPP__
44
+ #define __OPENCV_CORE_OPERATIONS_HPP__
45
+
46
+ #ifndef SKIP_INCLUDES
47
+ #include <string.h>
48
+ #include <limits.h>
49
+ #endif // SKIP_INCLUDES
50
+
51
+ #ifdef __cplusplus
52
+
53
+ /////// exchange-add operation for atomic operations on reference counters ///////
54
+ #ifdef __GNUC__
55
+
56
+ #if __GNUC__*10 + __GNUC_MINOR__ >= 42
57
+
58
+ #if !defined WIN32 && (defined __i486__ || defined __i586__ || \
59
+ defined __i686__ || defined __MMX__ || defined __SSE__ || defined __ppc__)
60
+ #define CV_XADD __sync_fetch_and_add
61
+ #else
62
+ #include <ext/atomicity.h>
63
+ #define CV_XADD __gnu_cxx::__exchange_and_add
64
+ #endif
65
+
66
+ #else
67
+ #include <bits/atomicity.h>
68
+ #if __GNUC__*10 + __GNUC_MINOR__ >= 34
69
+ #define CV_XADD __gnu_cxx::__exchange_and_add
70
+ #else
71
+ #define CV_XADD __exchange_and_add
72
+ #endif
73
+ #endif
74
+
75
+ #elif defined WIN32 || defined _WIN32
76
+ #include <intrin.h>
77
+ #define CV_XADD(addr,delta) _InterlockedExchangeAdd((long volatile*)(addr), (delta))
78
+ #else
79
+
80
+ template<typename _Tp> static inline _Tp CV_XADD(_Tp* addr, _Tp delta)
81
+ { int tmp = *addr; *addr += delta; return tmp; }
82
+
83
+ #endif
84
+
85
+ #include <limits>
86
+
87
+ namespace cv
88
+ {
89
+
90
+ using std::cos;
91
+ using std::sin;
92
+ using std::max;
93
+ using std::min;
94
+ using std::exp;
95
+ using std::log;
96
+ using std::pow;
97
+ using std::sqrt;
98
+
99
+
100
+ /////////////// saturate_cast (used in image & signal processing) ///////////////////
101
+
102
+ template<typename _Tp> static inline _Tp saturate_cast(uchar v) { return _Tp(v); }
103
+ template<typename _Tp> static inline _Tp saturate_cast(schar v) { return _Tp(v); }
104
+ template<typename _Tp> static inline _Tp saturate_cast(ushort v) { return _Tp(v); }
105
+ template<typename _Tp> static inline _Tp saturate_cast(short v) { return _Tp(v); }
106
+ template<typename _Tp> static inline _Tp saturate_cast(unsigned v) { return _Tp(v); }
107
+ template<typename _Tp> static inline _Tp saturate_cast(int v) { return _Tp(v); }
108
+ template<typename _Tp> static inline _Tp saturate_cast(float v) { return _Tp(v); }
109
+ template<typename _Tp> static inline _Tp saturate_cast(double v) { return _Tp(v); }
110
+
111
+ template<> inline uchar saturate_cast<uchar>(schar v)
112
+ { return (uchar)std::max((int)v, 0); }
113
+ template<> inline uchar saturate_cast<uchar>(ushort v)
114
+ { return (uchar)std::min((unsigned)v, (unsigned)UCHAR_MAX); }
115
+ template<> inline uchar saturate_cast<uchar>(int v)
116
+ { return (uchar)((unsigned)v <= UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0); }
117
+ template<> inline uchar saturate_cast<uchar>(short v)
118
+ { return saturate_cast<uchar>((int)v); }
119
+ template<> inline uchar saturate_cast<uchar>(unsigned v)
120
+ { return (uchar)std::min(v, (unsigned)UCHAR_MAX); }
121
+ template<> inline uchar saturate_cast<uchar>(float v)
122
+ { int iv = cvRound(v); return saturate_cast<uchar>(iv); }
123
+ template<> inline uchar saturate_cast<uchar>(double v)
124
+ { int iv = cvRound(v); return saturate_cast<uchar>(iv); }
125
+
126
+ template<> inline schar saturate_cast<schar>(uchar v)
127
+ { return (schar)std::min((int)v, SCHAR_MAX); }
128
+ template<> inline schar saturate_cast<schar>(ushort v)
129
+ { return (schar)std::min((unsigned)v, (unsigned)SCHAR_MAX); }
130
+ template<> inline schar saturate_cast<schar>(int v)
131
+ {
132
+ return (schar)((unsigned)(v-SCHAR_MIN) <= (unsigned)UCHAR_MAX ?
133
+ v : v > 0 ? SCHAR_MAX : SCHAR_MIN);
134
+ }
135
+ template<> inline schar saturate_cast<schar>(short v)
136
+ { return saturate_cast<schar>((int)v); }
137
+ template<> inline schar saturate_cast<schar>(unsigned v)
138
+ { return (schar)std::min(v, (unsigned)SCHAR_MAX); }
139
+
140
+ template<> inline schar saturate_cast<schar>(float v)
141
+ { int iv = cvRound(v); return saturate_cast<schar>(iv); }
142
+ template<> inline schar saturate_cast<schar>(double v)
143
+ { int iv = cvRound(v); return saturate_cast<schar>(iv); }
144
+
145
+ template<> inline ushort saturate_cast<ushort>(schar v)
146
+ { return (ushort)std::max((int)v, 0); }
147
+ template<> inline ushort saturate_cast<ushort>(short v)
148
+ { return (ushort)std::max((int)v, 0); }
149
+ template<> inline ushort saturate_cast<ushort>(int v)
150
+ { return (ushort)((unsigned)v <= (unsigned)USHRT_MAX ? v : v > 0 ? USHRT_MAX : 0); }
151
+ template<> inline ushort saturate_cast<ushort>(unsigned v)
152
+ { return (ushort)std::min(v, (unsigned)USHRT_MAX); }
153
+ template<> inline ushort saturate_cast<ushort>(float v)
154
+ { int iv = cvRound(v); return saturate_cast<ushort>(iv); }
155
+ template<> inline ushort saturate_cast<ushort>(double v)
156
+ { int iv = cvRound(v); return saturate_cast<ushort>(iv); }
157
+
158
+ template<> inline short saturate_cast<short>(ushort v)
159
+ { return (short)std::min((int)v, SHRT_MAX); }
160
+ template<> inline short saturate_cast<short>(int v)
161
+ {
162
+ return (short)((unsigned)(v - SHRT_MIN) <= (unsigned)USHRT_MAX ?
163
+ v : v > 0 ? SHRT_MAX : SHRT_MIN);
164
+ }
165
+ template<> inline short saturate_cast<short>(unsigned v)
166
+ { return (short)std::min(v, (unsigned)SHRT_MAX); }
167
+ template<> inline short saturate_cast<short>(float v)
168
+ { int iv = cvRound(v); return saturate_cast<short>(iv); }
169
+ template<> inline short saturate_cast<short>(double v)
170
+ { int iv = cvRound(v); return saturate_cast<short>(iv); }
171
+
172
+ template<> inline int saturate_cast<int>(float v) { return cvRound(v); }
173
+ template<> inline int saturate_cast<int>(double v) { return cvRound(v); }
174
+
175
+ // we intentionally do not clip negative numbers, to make -1 become 0xffffffff etc.
176
+ template<> inline unsigned saturate_cast<unsigned>(float v){ return cvRound(v); }
177
+ template<> inline unsigned saturate_cast<unsigned>(double v) { return cvRound(v); }
178
+
179
+
180
+ //////////////////////////////// Matx /////////////////////////////////
181
+
182
+
183
+ template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx()
184
+ {
185
+ for(int i = 0; i < channels; i++) val[i] = _Tp(0);
186
+ }
187
+
188
+ template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0)
189
+ {
190
+ val[0] = v0;
191
+ for(int i = 1; i < channels; i++) val[i] = _Tp(0);
192
+ }
193
+
194
+ template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1)
195
+ {
196
+ assert(channels >= 2);
197
+ val[0] = v0; val[1] = v1;
198
+ for(int i = 2; i < channels; i++) val[i] = _Tp(0);
199
+ }
200
+
201
+ template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2)
202
+ {
203
+ assert(channels >= 3);
204
+ val[0] = v0; val[1] = v1; val[2] = v2;
205
+ for(int i = 3; i < channels; i++) val[i] = _Tp(0);
206
+ }
207
+
208
+ template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3)
209
+ {
210
+ assert(channels >= 4);
211
+ val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
212
+ for(int i = 4; i < channels; i++) val[i] = _Tp(0);
213
+ }
214
+
215
+ template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4)
216
+ {
217
+ assert(channels >= 5);
218
+ val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; val[4] = v4;
219
+ for(int i = 5; i < channels; i++) val[i] = _Tp(0);
220
+ }
221
+
222
+ template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
223
+ _Tp v4, _Tp v5)
224
+ {
225
+ assert(channels >= 6);
226
+ val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
227
+ val[4] = v4; val[5] = v5;
228
+ for(int i = 6; i < channels; i++) val[i] = _Tp(0);
229
+ }
230
+
231
+ template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
232
+ _Tp v4, _Tp v5, _Tp v6)
233
+ {
234
+ assert(channels >= 7);
235
+ val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
236
+ val[4] = v4; val[5] = v5; val[6] = v6;
237
+ for(int i = 7; i < channels; i++) val[i] = _Tp(0);
238
+ }
239
+
240
+ template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
241
+ _Tp v4, _Tp v5, _Tp v6, _Tp v7)
242
+ {
243
+ assert(channels >= 8);
244
+ val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
245
+ val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
246
+ for(int i = 8; i < channels; i++) val[i] = _Tp(0);
247
+ }
248
+
249
+ template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
250
+ _Tp v4, _Tp v5, _Tp v6, _Tp v7,
251
+ _Tp v8)
252
+ {
253
+ assert(channels >= 9);
254
+ val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
255
+ val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
256
+ val[8] = v8;
257
+ for(int i = 9; i < channels; i++) val[i] = _Tp(0);
258
+ }
259
+
260
+ template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
261
+ _Tp v4, _Tp v5, _Tp v6, _Tp v7,
262
+ _Tp v8, _Tp v9)
263
+ {
264
+ assert(channels >= 10);
265
+ val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
266
+ val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
267
+ val[8] = v8; val[9] = v9;
268
+ for(int i = 10; i < channels; i++) val[i] = _Tp(0);
269
+ }
270
+
271
+
272
+ template<typename _Tp, int m, int n>
273
+ inline Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
274
+ _Tp v4, _Tp v5, _Tp v6, _Tp v7,
275
+ _Tp v8, _Tp v9, _Tp v10, _Tp v11)
276
+ {
277
+ assert(channels == 12);
278
+ val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
279
+ val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
280
+ val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11;
281
+ }
282
+
283
+ template<typename _Tp, int m, int n>
284
+ inline Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
285
+ _Tp v4, _Tp v5, _Tp v6, _Tp v7,
286
+ _Tp v8, _Tp v9, _Tp v10, _Tp v11,
287
+ _Tp v12, _Tp v13, _Tp v14, _Tp v15)
288
+ {
289
+ assert(channels == 16);
290
+ val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
291
+ val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
292
+ val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11;
293
+ val[12] = v12; val[13] = v13; val[14] = v14; val[15] = v15;
294
+ }
295
+
296
+ template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(const _Tp* values)
297
+ {
298
+ for( int i = 0; i < channels; i++ ) val[i] = values[i];
299
+ }
300
+
301
+ template<typename _Tp, int m, int n> inline Matx<_Tp, m, n> Matx<_Tp, m, n>::all(_Tp alpha)
302
+ {
303
+ Matx<_Tp, m, n> M;
304
+ for( int i = 0; i < m*n; i++ ) M.val[i] = alpha;
305
+ return M;
306
+ }
307
+
308
+ template<typename _Tp, int m, int n> inline
309
+ Matx<_Tp,m,n> Matx<_Tp,m,n>::zeros()
310
+ {
311
+ return all(0);
312
+ }
313
+
314
+ template<typename _Tp, int m, int n> inline
315
+ Matx<_Tp,m,n> Matx<_Tp,m,n>::ones()
316
+ {
317
+ return all(1);
318
+ }
319
+
320
+ template<typename _Tp, int m, int n> inline
321
+ Matx<_Tp,m,n> Matx<_Tp,m,n>::eye()
322
+ {
323
+ Matx<_Tp,m,n> M;
324
+ for(int i = 0; i < MIN(m,n); i++)
325
+ M(i,i) = 1;
326
+ return M;
327
+ }
328
+
329
+ template<typename _Tp, int m, int n> inline _Tp Matx<_Tp, m, n>::dot(const Matx<_Tp, m, n>& M) const
330
+ {
331
+ _Tp s = 0;
332
+ for( int i = 0; i < m*n; i++ ) s += val[i]*M.val[i];
333
+ return s;
334
+ }
335
+
336
+
337
+ template<typename _Tp, int m, int n> inline double Matx<_Tp, m, n>::ddot(const Matx<_Tp, m, n>& M) const
338
+ {
339
+ double s = 0;
340
+ for( int i = 0; i < m*n; i++ ) s += (double)val[i]*M.val[i];
341
+ return s;
342
+ }
343
+
344
+
345
+
346
+ template<typename _Tp, int m, int n> inline
347
+ Matx<_Tp,m,n> Matx<_Tp,m,n>::diag(const Matx<_Tp,MIN(m,n),1>& d)
348
+ {
349
+ Matx<_Tp,m,n> M;
350
+ for(int i = 0; i < MIN(m,n); i++)
351
+ M(i,i) = d(i, 0);
352
+ return M;
353
+ }
354
+
355
+ template<typename _Tp, int m, int n> inline
356
+ Matx<_Tp,m,n> Matx<_Tp,m,n>::randu(_Tp a, _Tp b)
357
+ {
358
+ Matx<_Tp,m,n> M;
359
+ Mat matM(M, false);
360
+ cv::randu(matM, Scalar(a), Scalar(b));
361
+ return M;
362
+ }
363
+
364
+ template<typename _Tp, int m, int n> inline
365
+ Matx<_Tp,m,n> Matx<_Tp,m,n>::randn(_Tp a, _Tp b)
366
+ {
367
+ Matx<_Tp,m,n> M;
368
+ Mat matM(M, false);
369
+ cv::randn(matM, Scalar(a), Scalar(b));
370
+ return M;
371
+ }
372
+
373
+ template<typename _Tp, int m, int n> template<typename T2>
374
+ inline Matx<_Tp, m, n>::operator Matx<T2, m, n>() const
375
+ {
376
+ Matx<T2, m, n> M;
377
+ for( int i = 0; i < m*n; i++ ) M.val[i] = saturate_cast<T2>(val[i]);
378
+ return M;
379
+ }
380
+
381
+
382
+ template<typename _Tp, int m, int n> template<int m1, int n1> inline
383
+ Matx<_Tp, m1, n1> Matx<_Tp, m, n>::reshape() const
384
+ {
385
+ CV_DbgAssert(m1*n1 == m*n);
386
+ return (const Matx<_Tp, m1, n1>&)*this;
387
+ }
388
+
389
+
390
+ template<typename _Tp, int m, int n>
391
+ template<int m1, int n1> inline
392
+ Matx<_Tp, m1, n1> Matx<_Tp, m, n>::get_minor(int i, int j) const
393
+ {
394
+ CV_DbgAssert(0 <= i && i+m1 <= m && 0 <= j && j+n1 <= n);
395
+ Matx<_Tp, m1, n1> s;
396
+ for( int di = 0; di < m1; di++ )
397
+ for( int dj = 0; dj < n1; dj++ )
398
+ s(di, dj) = (*this)(i+di, j+dj);
399
+ return s;
400
+ }
401
+
402
+
403
+ template<typename _Tp, int m, int n> inline
404
+ Matx<_Tp, 1, n> Matx<_Tp, m, n>::row(int i) const
405
+ {
406
+ CV_DbgAssert((unsigned)i < (unsigned)m);
407
+ return Matx<_Tp, 1, n>(&val[i*n]);
408
+ }
409
+
410
+
411
+ template<typename _Tp, int m, int n> inline
412
+ Matx<_Tp, m, 1> Matx<_Tp, m, n>::col(int j) const
413
+ {
414
+ CV_DbgAssert((unsigned)j < (unsigned)n);
415
+ Matx<_Tp, m, 1> v;
416
+ for( int i = 0; i < m; i++ )
417
+ v[i] = val[i*n + j];
418
+ return v;
419
+ }
420
+
421
+
422
+ template<typename _Tp, int m, int n> inline
423
+ Matx<_Tp, MIN(m,n), 1> Matx<_Tp, m, n>::diag() const
424
+ {
425
+ diag_type d;
426
+ for( int i = 0; i < MIN(m, n); i++ )
427
+ d.val[i] = val[i*n + i];
428
+ return d;
429
+ }
430
+
431
+
432
+ template<typename _Tp, int m, int n> inline
433
+ const _Tp& Matx<_Tp, m, n>::operator ()(int i, int j) const
434
+ {
435
+ CV_DbgAssert( (unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n );
436
+ return this->val[i*n + j];
437
+ }
438
+
439
+
440
+ template<typename _Tp, int m, int n> inline
441
+ _Tp& Matx<_Tp, m, n>::operator ()(int i, int j)
442
+ {
443
+ CV_DbgAssert( (unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n );
444
+ return val[i*n + j];
445
+ }
446
+
447
+
448
+ template<typename _Tp, int m, int n> inline
449
+ const _Tp& Matx<_Tp, m, n>::operator ()(int i) const
450
+ {
451
+ CV_DbgAssert( (m == 1 || n == 1) && (unsigned)i < (unsigned)(m+n-1) );
452
+ return val[i];
453
+ }
454
+
455
+
456
+ template<typename _Tp, int m, int n> inline
457
+ _Tp& Matx<_Tp, m, n>::operator ()(int i)
458
+ {
459
+ CV_DbgAssert( (m == 1 || n == 1) && (unsigned)i < (unsigned)(m+n-1) );
460
+ return val[i];
461
+ }
462
+
463
+
464
+ template<typename _Tp1, typename _Tp2, int m, int n> static inline
465
+ Matx<_Tp1, m, n>& operator += (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b)
466
+ {
467
+ for( int i = 0; i < m*n; i++ )
468
+ a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]);
469
+ return a;
470
+ }
471
+
472
+
473
+ template<typename _Tp1, typename _Tp2, int m, int n> static inline
474
+ Matx<_Tp1, m, n>& operator -= (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b)
475
+ {
476
+ for( int i = 0; i < m*n; i++ )
477
+ a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]);
478
+ return a;
479
+ }
480
+
481
+
482
+ template<typename _Tp, int m, int n> inline
483
+ Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_AddOp)
484
+ {
485
+ for( int i = 0; i < m*n; i++ )
486
+ val[i] = saturate_cast<_Tp>(a.val[i] + b.val[i]);
487
+ }
488
+
489
+
490
+ template<typename _Tp, int m, int n> inline
491
+ Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_SubOp)
492
+ {
493
+ for( int i = 0; i < m*n; i++ )
494
+ val[i] = saturate_cast<_Tp>(a.val[i] - b.val[i]);
495
+ }
496
+
497
+
498
+ template<typename _Tp, int m, int n> template<typename _T2> inline
499
+ Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, _T2 alpha, Matx_ScaleOp)
500
+ {
501
+ for( int i = 0; i < m*n; i++ )
502
+ val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
503
+ }
504
+
505
+
506
+ template<typename _Tp, int m, int n> inline
507
+ Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_MulOp)
508
+ {
509
+ for( int i = 0; i < m*n; i++ )
510
+ val[i] = saturate_cast<_Tp>(a.val[i] * b.val[i]);
511
+ }
512
+
513
+
514
+ template<typename _Tp, int m, int n> template<int l> inline
515
+ Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b, Matx_MatMulOp)
516
+ {
517
+ for( int i = 0; i < m; i++ )
518
+ for( int j = 0; j < n; j++ )
519
+ {
520
+ _Tp s = 0;
521
+ for( int k = 0; k < l; k++ )
522
+ s += a(i, k) * b(k, j);
523
+ val[i*n + j] = s;
524
+ }
525
+ }
526
+
527
+
528
+ template<typename _Tp, int m, int n> inline
529
+ Matx<_Tp,m,n>::Matx(const Matx<_Tp, n, m>& a, Matx_TOp)
530
+ {
531
+ for( int i = 0; i < m; i++ )
532
+ for( int j = 0; j < n; j++ )
533
+ val[i*n + j] = a(j, i);
534
+ }
535
+
536
+
537
+ template<typename _Tp, int m, int n> static inline
538
+ Matx<_Tp, m, n> operator + (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
539
+ {
540
+ return Matx<_Tp, m, n>(a, b, Matx_AddOp());
541
+ }
542
+
543
+
544
+ template<typename _Tp, int m, int n> static inline
545
+ Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
546
+ {
547
+ return Matx<_Tp, m, n>(a, b, Matx_SubOp());
548
+ }
549
+
550
+
551
+ template<typename _Tp, int m, int n> static inline
552
+ Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, int alpha)
553
+ {
554
+ for( int i = 0; i < m*n; i++ )
555
+ a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
556
+ return a;
557
+ }
558
+
559
+ template<typename _Tp, int m, int n> static inline
560
+ Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, float alpha)
561
+ {
562
+ for( int i = 0; i < m*n; i++ )
563
+ a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
564
+ return a;
565
+ }
566
+
567
+ template<typename _Tp, int m, int n> static inline
568
+ Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, double alpha)
569
+ {
570
+ for( int i = 0; i < m*n; i++ )
571
+ a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
572
+ return a;
573
+ }
574
+
575
+ template<typename _Tp, int m, int n> static inline
576
+ Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, int alpha)
577
+ {
578
+ return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
579
+ }
580
+
581
+ template<typename _Tp, int m, int n> static inline
582
+ Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, float alpha)
583
+ {
584
+ return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
585
+ }
586
+
587
+ template<typename _Tp, int m, int n> static inline
588
+ Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, double alpha)
589
+ {
590
+ return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
591
+ }
592
+
593
+ template<typename _Tp, int m, int n> static inline
594
+ Matx<_Tp, m, n> operator * (int alpha, const Matx<_Tp, m, n>& a)
595
+ {
596
+ return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
597
+ }
598
+
599
+ template<typename _Tp, int m, int n> static inline
600
+ Matx<_Tp, m, n> operator * (float alpha, const Matx<_Tp, m, n>& a)
601
+ {
602
+ return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
603
+ }
604
+
605
+ template<typename _Tp, int m, int n> static inline
606
+ Matx<_Tp, m, n> operator * (double alpha, const Matx<_Tp, m, n>& a)
607
+ {
608
+ return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
609
+ }
610
+
611
+ template<typename _Tp, int m, int n> static inline
612
+ Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a)
613
+ {
614
+ return Matx<_Tp, m, n>(a, -1, Matx_ScaleOp());
615
+ }
616
+
617
+
618
+ template<typename _Tp, int m, int n, int l> static inline
619
+ Matx<_Tp, m, n> operator * (const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b)
620
+ {
621
+ return Matx<_Tp, m, n>(a, b, Matx_MatMulOp());
622
+ }
623
+
624
+
625
+ template<typename _Tp> static inline
626
+ Point_<_Tp> operator * (const Matx<_Tp, 2, 2>& a, const Point_<_Tp>& b)
627
+ {
628
+ Matx<_Tp, 2, 1> tmp = a*Vec<_Tp,2>(b.x, b.y);
629
+ return Point_<_Tp>(tmp.val[0], tmp.val[1]);
630
+ }
631
+
632
+
633
+ template<typename _Tp> static inline
634
+ Point3_<_Tp> operator * (const Matx<_Tp, 3, 3>& a, const Point3_<_Tp>& b)
635
+ {
636
+ Matx<_Tp, 3, 1> tmp = a*Vec<_Tp,3>(b.x, b.y, b.z);
637
+ return Point3_<_Tp>(tmp.val[0], tmp.val[1], tmp.val[2]);
638
+ }
639
+
640
+
641
+ template<typename _Tp> static inline
642
+ Point3_<_Tp> operator * (const Matx<_Tp, 3, 3>& a, const Point_<_Tp>& b)
643
+ {
644
+ Matx<_Tp, 3, 1> tmp = a*Vec<_Tp,3>(b.x, b.y, 1);
645
+ return Point3_<_Tp>(tmp.val[0], tmp.val[1], tmp.val[2]);
646
+ }
647
+
648
+
649
+ template<typename _Tp> static inline
650
+ Matx<_Tp, 4, 1> operator * (const Matx<_Tp, 4, 4>& a, const Point3_<_Tp>& b)
651
+ {
652
+ return a*Matx<_Tp, 4, 1>(b.x, b.y, b.z, 1);
653
+ }
654
+
655
+
656
+ template<typename _Tp> static inline
657
+ Scalar operator * (const Matx<_Tp, 4, 4>& a, const Scalar& b)
658
+ {
659
+ return Scalar(a*Matx<_Tp, 4, 1>(b[0],b[1],b[2],b[3]));
660
+ }
661
+
662
+
663
+ template<typename _Tp, int m, int n> inline
664
+ Matx<_Tp, m, n> Matx<_Tp, m, n>::mul(const Matx<_Tp, m, n>& a) const
665
+ {
666
+ return Matx<_Tp, m, n>(*this, a, Matx_MulOp());
667
+ }
668
+
669
+
670
+ CV_EXPORTS int LU(float* A, size_t astep, int m, float* b, size_t bstep, int n);
671
+ CV_EXPORTS int LU(double* A, size_t astep, int m, double* b, size_t bstep, int n);
672
+ CV_EXPORTS bool Cholesky(float* A, size_t astep, int m, float* b, size_t bstep, int n);
673
+ CV_EXPORTS bool Cholesky(double* A, size_t astep, int m, double* b, size_t bstep, int n);
674
+
675
+
676
+ template<typename _Tp, int m> struct CV_EXPORTS Matx_DetOp
677
+ {
678
+ double operator ()(const Matx<_Tp, m, m>& a) const
679
+ {
680
+ Matx<_Tp, m, m> temp = a;
681
+ double p = LU(temp.val, m, m, 0, 0, 0);
682
+ if( p == 0 )
683
+ return p;
684
+ for( int i = 0; i < m; i++ )
685
+ p *= temp(i, i);
686
+ return p;
687
+ }
688
+ };
689
+
690
+
691
+ template<typename _Tp> struct CV_EXPORTS Matx_DetOp<_Tp, 1>
692
+ {
693
+ double operator ()(const Matx<_Tp, 1, 1>& a) const
694
+ {
695
+ return a(0,0);
696
+ }
697
+ };
698
+
699
+
700
+ template<typename _Tp> struct CV_EXPORTS Matx_DetOp<_Tp, 2>
701
+ {
702
+ double operator ()(const Matx<_Tp, 2, 2>& a) const
703
+ {
704
+ return a(0,0)*a(1,1) - a(0,1)*a(1,0);
705
+ }
706
+ };
707
+
708
+
709
+ template<typename _Tp> struct CV_EXPORTS Matx_DetOp<_Tp, 3>
710
+ {
711
+ double operator ()(const Matx<_Tp, 3, 3>& a) const
712
+ {
713
+ return a(0,0)*(a(1,1)*a(2,2) - a(2,1)*a(1,2)) -
714
+ a(0,1)*(a(1,0)*a(2,2) - a(2,0)*a(1,2)) +
715
+ a(0,2)*(a(1,0)*a(2,1) - a(2,0)*a(1,1));
716
+ }
717
+ };
718
+
719
+ template<typename _Tp, int m> static inline
720
+ double determinant(const Matx<_Tp, m, m>& a)
721
+ {
722
+ return Matx_DetOp<_Tp, m>()(a);
723
+ }
724
+
725
+
726
+ template<typename _Tp, int m, int n> static inline
727
+ double trace(const Matx<_Tp, m, n>& a)
728
+ {
729
+ _Tp s = 0;
730
+ for( int i = 0; i < std::min(m, n); i++ )
731
+ s += a(i,i);
732
+ return s;
733
+ }
734
+
735
+
736
+ template<typename _Tp, int m, int n> inline
737
+ Matx<_Tp, n, m> Matx<_Tp, m, n>::t() const
738
+ {
739
+ return Matx<_Tp, n, m>(*this, Matx_TOp());
740
+ }
741
+
742
+
743
+ template<typename _Tp, int m> struct CV_EXPORTS Matx_FastInvOp
744
+ {
745
+ bool operator()(const Matx<_Tp, m, m>& a, Matx<_Tp, m, m>& b, int method) const
746
+ {
747
+ Matx<_Tp, m, m> temp = a;
748
+
749
+ // assume that b is all 0's on input => make it a unity matrix
750
+ for( int i = 0; i < m; i++ )
751
+ b(i, i) = (_Tp)1;
752
+
753
+ if( method == DECOMP_CHOLESKY )
754
+ return Cholesky(temp.val, m*sizeof(_Tp), m, b.val, m*sizeof(_Tp), m);
755
+
756
+ return LU(temp.val, m*sizeof(_Tp), m, b.val, m*sizeof(_Tp), m) != 0;
757
+ }
758
+ };
759
+
760
+
761
+ template<typename _Tp> struct CV_EXPORTS Matx_FastInvOp<_Tp, 2>
762
+ {
763
+ bool operator()(const Matx<_Tp, 2, 2>& a, Matx<_Tp, 2, 2>& b, int) const
764
+ {
765
+ _Tp d = determinant(a);
766
+ if( d == 0 )
767
+ return false;
768
+ d = 1/d;
769
+ b(1,1) = a(0,0)*d;
770
+ b(0,0) = a(1,1)*d;
771
+ b(0,1) = -a(0,1)*d;
772
+ b(1,0) = -a(1,0)*d;
773
+ return true;
774
+ }
775
+ };
776
+
777
+
778
+ template<typename _Tp> struct CV_EXPORTS Matx_FastInvOp<_Tp, 3>
779
+ {
780
+ bool operator()(const Matx<_Tp, 3, 3>& a, Matx<_Tp, 3, 3>& b, int) const
781
+ {
782
+ _Tp d = determinant(a);
783
+ if( d == 0 )
784
+ return false;
785
+ d = 1/d;
786
+ b(0,0) = (a(1,1) * a(2,2) - a(1,2) * a(2,1)) * d;
787
+ b(0,1) = (a(0,2) * a(2,1) - a(0,1) * a(2,2)) * d;
788
+ b(0,2) = (a(0,1) * a(1,2) - a(0,2) * a(1,1)) * d;
789
+
790
+ b(1,0) = (a(1,2) * a(2,0) - a(1,0) * a(2,2)) * d;
791
+ b(1,1) = (a(0,0) * a(2,2) - a(0,2) * a(2,0)) * d;
792
+ b(1,2) = (a(0,2) * a(1,0) - a(0,0) * a(1,2)) * d;
793
+
794
+ b(2,0) = (a(1,0) * a(2,1) - a(1,1) * a(2,0)) * d;
795
+ b(2,1) = (a(0,1) * a(2,0) - a(0,0) * a(2,1)) * d;
796
+ b(2,2) = (a(0,0) * a(1,1) - a(0,1) * a(1,0)) * d;
797
+ return true;
798
+ }
799
+ };
800
+
801
+
802
+ template<typename _Tp, int m, int n> inline
803
+ Matx<_Tp, n, m> Matx<_Tp, m, n>::inv(int method) const
804
+ {
805
+ Matx<_Tp, n, m> b;
806
+ bool ok;
807
+ if( method == DECOMP_LU || method == DECOMP_CHOLESKY )
808
+ ok = Matx_FastInvOp<_Tp, m>()(*this, b, method);
809
+ else
810
+ {
811
+ Mat A(*this, false), B(b, false);
812
+ ok = invert(A, B, method);
813
+ }
814
+ return ok ? b : Matx<_Tp, n, m>::zeros();
815
+ }
816
+
817
+
818
+ template<typename _Tp, int m, int n> struct CV_EXPORTS Matx_FastSolveOp
819
+ {
820
+ bool operator()(const Matx<_Tp, m, m>& a, const Matx<_Tp, m, n>& b,
821
+ Matx<_Tp, m, n>& x, int method) const
822
+ {
823
+ Matx<_Tp, m, m> temp = a;
824
+ x = b;
825
+ if( method == DECOMP_CHOLESKY )
826
+ return Cholesky(temp.val, m*sizeof(_Tp), m, x.val, n*sizeof(_Tp), n);
827
+
828
+ return LU(temp.val, m*sizeof(_Tp), m, x.val, n*sizeof(_Tp), n) != 0;
829
+ }
830
+ };
831
+
832
+
833
+ template<typename _Tp> struct CV_EXPORTS Matx_FastSolveOp<_Tp, 2, 1>
834
+ {
835
+ bool operator()(const Matx<_Tp, 2, 2>& a, const Matx<_Tp, 2, 1>& b,
836
+ Matx<_Tp, 2, 1>& x, int method) const
837
+ {
838
+ _Tp d = determinant(a);
839
+ if( d == 0 )
840
+ return false;
841
+ d = 1/d;
842
+ x(0) = (b(0)*a(1,1) - b(1)*a(0,1))*d;
843
+ x(1) = (b(1)*a(0,0) - b(0)*a(1,0))*d;
844
+ return true;
845
+ }
846
+ };
847
+
848
+
849
+ template<typename _Tp> struct CV_EXPORTS Matx_FastSolveOp<_Tp, 3, 1>
850
+ {
851
+ bool operator()(const Matx<_Tp, 3, 3>& a, const Matx<_Tp, 3, 1>& b,
852
+ Matx<_Tp, 3, 1>& x, int method) const
853
+ {
854
+ _Tp d = determinant(a);
855
+ if( d == 0 )
856
+ return false;
857
+ d = 1/d;
858
+ x(0) = d*(b(0)*(a(1,1)*a(2,2) - a(1,2)*a(2,1)) -
859
+ a(0,1)*(b(1)*a(2,2) - a(1,2)*b(2)) +
860
+ a(0,2)*(b(1)*a(2,1) - a(1,1)*b(2)));
861
+
862
+ x(1) = d*(a(0,0)*(b(1)*a(2,2) - a(1,2)*b(2)) -
863
+ b(0)*(a(1,0)*a(2,2) - a(1,2)*a(2,0)) +
864
+ a(0,2)*(a(1,0)*b(2) - b(1)*a(2,0)));
865
+
866
+ x(2) = d*(a(0,0)*(a(1,1)*b(2) - b(1)*a(2,1)) -
867
+ a(0,1)*(a(1,0)*b(2) - b(1)*a(2,0)) +
868
+ b(0)*(a(1,0)*a(2,1) - a(1,1)*a(2,0)));
869
+ return true;
870
+ }
871
+ };
872
+
873
+
874
+ template<typename _Tp, int m, int n> template<int l> inline
875
+ Matx<_Tp, n, l> Matx<_Tp, m, n>::solve(const Matx<_Tp, m, l>& rhs, int method) const
876
+ {
877
+ Matx<_Tp, n, l> x;
878
+ bool ok;
879
+ if( method == DECOMP_LU || method == DECOMP_CHOLESKY )
880
+ ok = Matx_FastSolveOp<_Tp, m, l>()(*this, rhs, x, method);
881
+ else
882
+ {
883
+ Mat A(*this, false), B(rhs, false), X(x, false);
884
+ ok = cv::solve(A, B, X, method);
885
+ }
886
+
887
+ return ok ? x : Matx<_Tp, n, l>::zeros();
888
+ }
889
+
890
+
891
+ template<typename _Tp, int m, int n> static inline
892
+ double norm(const Matx<_Tp, m, n>& M)
893
+ {
894
+ double s = 0;
895
+ for( int i = 0; i < m*n; i++ )
896
+ s += (double)M.val[i]*M.val[i];
897
+ return std::sqrt(s);
898
+ }
899
+
900
+
901
+ template<typename _Tp, int m, int n> static inline
902
+ double norm(const Matx<_Tp, m, n>& M, int normType)
903
+ {
904
+ if( normType == NORM_INF )
905
+ {
906
+ _Tp s = 0;
907
+ for( int i = 0; i < m*n; i++ )
908
+ s = std::max(s, std::abs(M.val[i]));
909
+ return s;
910
+ }
911
+
912
+ if( normType == NORM_L1 )
913
+ {
914
+ _Tp s = 0;
915
+ for( int i = 0; i < m*n; i++ )
916
+ s += std::abs(M.val[i]);
917
+ return s;
918
+ }
919
+
920
+ CV_DbgAssert( normType == NORM_L2 );
921
+ return norm(M);
922
+ }
923
+
924
+
925
+ template<typename _Tp, int m, int n> static inline
926
+ bool operator == (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
927
+ {
928
+ for( int i = 0; i < m*n; i++ )
929
+ if( a.val[i] != b.val[i] ) return false;
930
+ return true;
931
+ }
932
+
933
+ template<typename _Tp, int m, int n> static inline
934
+ bool operator != (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
935
+ {
936
+ return !(a == b);
937
+ }
938
+
939
+
940
+ template<typename _Tp, typename _T2, int m, int n> static inline
941
+ MatxCommaInitializer<_Tp, m, n> operator << (const Matx<_Tp, m, n>& mtx, _T2 val)
942
+ {
943
+ MatxCommaInitializer<_Tp, m, n> commaInitializer((Matx<_Tp, m, n>*)&mtx);
944
+ return (commaInitializer, val);
945
+ }
946
+
947
+ template<typename _Tp, int m, int n> inline
948
+ MatxCommaInitializer<_Tp, m, n>::MatxCommaInitializer(Matx<_Tp, m, n>* _mtx)
949
+ : dst(_mtx), idx(0)
950
+ {}
951
+
952
+ template<typename _Tp, int m, int n> template<typename _T2> inline
953
+ MatxCommaInitializer<_Tp, m, n>& MatxCommaInitializer<_Tp, m, n>::operator , (_T2 value)
954
+ {
955
+ CV_DbgAssert( idx < m*n );
956
+ dst->val[idx++] = saturate_cast<_Tp>(value);
957
+ return *this;
958
+ }
959
+
960
+ template<typename _Tp, int m, int n> inline
961
+ Matx<_Tp, m, n> MatxCommaInitializer<_Tp, m, n>::operator *() const
962
+ {
963
+ CV_DbgAssert( idx == n*m );
964
+ return *dst;
965
+ }
966
+
967
+ /////////////////////////// short vector (Vec) /////////////////////////////
968
+
969
+ template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec()
970
+ {}
971
+
972
+ template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0)
973
+ : Matx<_Tp, cn, 1>(v0)
974
+ {}
975
+
976
+ template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1)
977
+ : Matx<_Tp, cn, 1>(v0, v1)
978
+ {}
979
+
980
+ template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2)
981
+ : Matx<_Tp, cn, 1>(v0, v1, v2)
982
+ {}
983
+
984
+ template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3)
985
+ : Matx<_Tp, cn, 1>(v0, v1, v2, v3)
986
+ {}
987
+
988
+ template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4)
989
+ : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4)
990
+ {}
991
+
992
+ template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5)
993
+ : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5)
994
+ {}
995
+
996
+ template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
997
+ _Tp v4, _Tp v5, _Tp v6)
998
+ : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6)
999
+ {}
1000
+
1001
+ template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
1002
+ _Tp v4, _Tp v5, _Tp v6, _Tp v7)
1003
+ : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7)
1004
+ {}
1005
+
1006
+ template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
1007
+ _Tp v4, _Tp v5, _Tp v6, _Tp v7,
1008
+ _Tp v8)
1009
+ : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8)
1010
+ {}
1011
+
1012
+ template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
1013
+ _Tp v4, _Tp v5, _Tp v6, _Tp v7,
1014
+ _Tp v8, _Tp v9)
1015
+ : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9)
1016
+ {}
1017
+
1018
+ template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(const _Tp* values)
1019
+ : Matx<_Tp, cn, 1>(values)
1020
+ {}
1021
+
1022
+
1023
+ template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(const Vec<_Tp, cn>& m)
1024
+ : Matx<_Tp, cn, 1>(m.val)
1025
+ {}
1026
+
1027
+ template<typename _Tp, int cn> inline
1028
+ Vec<_Tp, cn>::Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_AddOp op)
1029
+ : Matx<_Tp, cn, 1>(a, b, op)
1030
+ {}
1031
+
1032
+ template<typename _Tp, int cn> inline
1033
+ Vec<_Tp, cn>::Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_SubOp op)
1034
+ : Matx<_Tp, cn, 1>(a, b, op)
1035
+ {}
1036
+
1037
+ template<typename _Tp, int cn> template<typename _T2> inline
1038
+ Vec<_Tp, cn>::Vec(const Matx<_Tp, cn, 1>& a, _T2 alpha, Matx_ScaleOp op)
1039
+ : Matx<_Tp, cn, 1>(a, alpha, op)
1040
+ {}
1041
+
1042
+ template<typename _Tp, int cn> inline Vec<_Tp, cn> Vec<_Tp, cn>::all(_Tp alpha)
1043
+ {
1044
+ Vec v;
1045
+ for( int i = 0; i < cn; i++ ) v.val[i] = alpha;
1046
+ return v;
1047
+ }
1048
+
1049
+ template<typename _Tp, int cn> inline Vec<_Tp, cn> Vec<_Tp, cn>::mul(const Vec<_Tp, cn>& v) const
1050
+ {
1051
+ Vec<_Tp, cn> w;
1052
+ for( int i = 0; i < cn; i++ ) w.val[i] = saturate_cast<_Tp>(this->val[i]*v.val[i]);
1053
+ return w;
1054
+ }
1055
+
1056
+ template<typename _Tp, int cn> inline Vec<_Tp, cn> Vec<_Tp, cn>::cross(const Vec<_Tp, cn>& v) const
1057
+ {
1058
+ CV_Error(CV_StsError, "for arbitrary-size vector there is no cross-product defined");
1059
+ return Vec<_Tp, cn>();
1060
+ }
1061
+
1062
+ template<typename _Tp, int cn> template<typename T2>
1063
+ inline Vec<_Tp, cn>::operator Vec<T2, cn>() const
1064
+ {
1065
+ Vec<T2, cn> v;
1066
+ for( int i = 0; i < cn; i++ ) v.val[i] = saturate_cast<T2>(this->val[i]);
1067
+ return v;
1068
+ }
1069
+
1070
+ template<typename _Tp, int cn> inline Vec<_Tp, cn>::operator CvScalar() const
1071
+ {
1072
+ CvScalar s = {{0,0,0,0}};
1073
+ int i;
1074
+ for( i = 0; i < std::min(cn, 4); i++ ) s.val[i] = this->val[i];
1075
+ for( ; i < 4; i++ ) s.val[i] = 0;
1076
+ return s;
1077
+ }
1078
+
1079
+ template<typename _Tp, int cn> inline const _Tp& Vec<_Tp, cn>::operator [](int i) const
1080
+ {
1081
+ CV_DbgAssert( (unsigned)i < (unsigned)cn );
1082
+ return this->val[i];
1083
+ }
1084
+
1085
+ template<typename _Tp, int cn> inline _Tp& Vec<_Tp, cn>::operator [](int i)
1086
+ {
1087
+ CV_DbgAssert( (unsigned)i < (unsigned)cn );
1088
+ return this->val[i];
1089
+ }
1090
+
1091
+ template<typename _Tp, int cn> inline const _Tp& Vec<_Tp, cn>::operator ()(int i) const
1092
+ {
1093
+ CV_DbgAssert( (unsigned)i < (unsigned)cn );
1094
+ return this->val[i];
1095
+ }
1096
+
1097
+ template<typename _Tp, int cn> inline _Tp& Vec<_Tp, cn>::operator ()(int i)
1098
+ {
1099
+ CV_DbgAssert( (unsigned)i < (unsigned)cn );
1100
+ return this->val[i];
1101
+ }
1102
+
1103
+ template<typename _Tp1, typename _Tp2, int cn> static inline Vec<_Tp1, cn>&
1104
+ operator += (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b)
1105
+ {
1106
+ for( int i = 0; i < cn; i++ )
1107
+ a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]);
1108
+ return a;
1109
+ }
1110
+
1111
+ template<typename _Tp1, typename _Tp2, int cn> static inline Vec<_Tp1, cn>&
1112
+ operator -= (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b)
1113
+ {
1114
+ for( int i = 0; i < cn; i++ )
1115
+ a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]);
1116
+ return a;
1117
+ }
1118
+
1119
+ template<typename _Tp, int cn> static inline Vec<_Tp, cn>
1120
+ operator + (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b)
1121
+ {
1122
+ return Vec<_Tp, cn>(a, b, Matx_AddOp());
1123
+ }
1124
+
1125
+ template<typename _Tp, int cn> static inline Vec<_Tp, cn>
1126
+ operator - (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b)
1127
+ {
1128
+ return Vec<_Tp, cn>(a, b, Matx_SubOp());
1129
+ }
1130
+
1131
+ template<typename _Tp, int cn> static inline
1132
+ Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, int alpha)
1133
+ {
1134
+ for( int i = 0; i < cn; i++ )
1135
+ a[i] = saturate_cast<_Tp>(a[i]*alpha);
1136
+ return a;
1137
+ }
1138
+
1139
+ template<typename _Tp, int cn> static inline
1140
+ Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, float alpha)
1141
+ {
1142
+ for( int i = 0; i < cn; i++ )
1143
+ a[i] = saturate_cast<_Tp>(a[i]*alpha);
1144
+ return a;
1145
+ }
1146
+
1147
+ template<typename _Tp, int cn> static inline
1148
+ Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, double alpha)
1149
+ {
1150
+ for( int i = 0; i < cn; i++ )
1151
+ a[i] = saturate_cast<_Tp>(a[i]*alpha);
1152
+ return a;
1153
+ }
1154
+
1155
+
1156
+ template<typename _Tp, int cn> static inline Vec<_Tp, cn>
1157
+ operator * (const Vec<_Tp, cn>& a, int alpha)
1158
+ {
1159
+ return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp());
1160
+ }
1161
+
1162
+ template<typename _Tp, int cn> static inline Vec<_Tp, cn>
1163
+ operator * (int alpha, const Vec<_Tp, cn>& a)
1164
+ {
1165
+ return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp());
1166
+ }
1167
+
1168
+ template<typename _Tp, int cn> static inline Vec<_Tp, cn>
1169
+ operator * (const Vec<_Tp, cn>& a, float alpha)
1170
+ {
1171
+ return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp());
1172
+ }
1173
+
1174
+ template<typename _Tp, int cn> static inline Vec<_Tp, cn>
1175
+ operator * (float alpha, const Vec<_Tp, cn>& a)
1176
+ {
1177
+ return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp());
1178
+ }
1179
+
1180
+ template<typename _Tp, int cn> static inline Vec<_Tp, cn>
1181
+ operator * (const Vec<_Tp, cn>& a, double alpha)
1182
+ {
1183
+ return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp());
1184
+ }
1185
+
1186
+ template<typename _Tp, int cn> static inline Vec<_Tp, cn>
1187
+ operator * (double alpha, const Vec<_Tp, cn>& a)
1188
+ {
1189
+ return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp());
1190
+ }
1191
+
1192
+ template<typename _Tp, int cn> static inline Vec<_Tp, cn>
1193
+ operator - (const Vec<_Tp, cn>& a)
1194
+ {
1195
+ Vec<_Tp,cn> t;
1196
+ for( int i = 0; i < cn; i++ ) t.val[i] = saturate_cast<_Tp>(-a.val[i]);
1197
+ return t;
1198
+ }
1199
+
1200
+ template<> inline Vec<float, 3> Vec<float, 3>::cross(const Vec<float, 3>& v) const
1201
+ {
1202
+ return Vec<float,3>(val[1]*v.val[2] - val[2]*v.val[1],
1203
+ val[2]*v.val[0] - val[0]*v.val[2],
1204
+ val[0]*v.val[1] - val[1]*v.val[0]);
1205
+ }
1206
+
1207
+ template<> inline Vec<double, 3> Vec<double, 3>::cross(const Vec<double, 3>& v) const
1208
+ {
1209
+ return Vec<double,3>(val[1]*v.val[2] - val[2]*v.val[1],
1210
+ val[2]*v.val[0] - val[0]*v.val[2],
1211
+ val[0]*v.val[1] - val[1]*v.val[0]);
1212
+ }
1213
+
1214
+ template<typename T1, typename T2> static inline
1215
+ Vec<T1, 2>& operator += (Vec<T1, 2>& a, const Vec<T2, 2>& b)
1216
+ {
1217
+ a[0] = saturate_cast<T1>(a[0] + b[0]);
1218
+ a[1] = saturate_cast<T1>(a[1] + b[1]);
1219
+ return a;
1220
+ }
1221
+
1222
+ template<typename T1, typename T2> static inline
1223
+ Vec<T1, 3>& operator += (Vec<T1, 3>& a, const Vec<T2, 3>& b)
1224
+ {
1225
+ a[0] = saturate_cast<T1>(a[0] + b[0]);
1226
+ a[1] = saturate_cast<T1>(a[1] + b[1]);
1227
+ a[2] = saturate_cast<T1>(a[2] + b[2]);
1228
+ return a;
1229
+ }
1230
+
1231
+
1232
+ template<typename T1, typename T2> static inline
1233
+ Vec<T1, 4>& operator += (Vec<T1, 4>& a, const Vec<T2, 4>& b)
1234
+ {
1235
+ a[0] = saturate_cast<T1>(a[0] + b[0]);
1236
+ a[1] = saturate_cast<T1>(a[1] + b[1]);
1237
+ a[2] = saturate_cast<T1>(a[2] + b[2]);
1238
+ a[3] = saturate_cast<T1>(a[3] + b[3]);
1239
+ return a;
1240
+ }
1241
+
1242
+
1243
+ template<typename _Tp, typename _T2, int cn> static inline
1244
+ VecCommaInitializer<_Tp, cn> operator << (const Vec<_Tp, cn>& vec, _T2 val)
1245
+ {
1246
+ VecCommaInitializer<_Tp, cn> commaInitializer((Vec<_Tp, cn>*)&vec);
1247
+ return (commaInitializer, val);
1248
+ }
1249
+
1250
+ template<typename _Tp, int cn> inline
1251
+ VecCommaInitializer<_Tp, cn>::VecCommaInitializer(Vec<_Tp, cn>* _vec)
1252
+ : MatxCommaInitializer<_Tp, cn, 1>(_vec)
1253
+ {}
1254
+
1255
+ template<typename _Tp, int cn> template<typename _T2> inline
1256
+ VecCommaInitializer<_Tp, cn>& VecCommaInitializer<_Tp, cn>::operator , (_T2 value)
1257
+ {
1258
+ CV_DbgAssert( this->idx < cn );
1259
+ this->dst->val[this->idx++] = saturate_cast<_Tp>(value);
1260
+ return *this;
1261
+ }
1262
+
1263
+ template<typename _Tp, int cn> inline
1264
+ Vec<_Tp, cn> VecCommaInitializer<_Tp, cn>::operator *() const
1265
+ {
1266
+ CV_DbgAssert( this->idx == cn );
1267
+ return *this->dst;
1268
+ }
1269
+
1270
+ //////////////////////////////// Complex //////////////////////////////
1271
+
1272
+ template<typename _Tp> inline Complex<_Tp>::Complex() : re(0), im(0) {}
1273
+ template<typename _Tp> inline Complex<_Tp>::Complex( _Tp _re, _Tp _im ) : re(_re), im(_im) {}
1274
+ template<typename _Tp> template<typename T2> inline Complex<_Tp>::operator Complex<T2>() const
1275
+ { return Complex<T2>(saturate_cast<T2>(re), saturate_cast<T2>(im)); }
1276
+ template<typename _Tp> inline Complex<_Tp> Complex<_Tp>::conj() const
1277
+ { return Complex<_Tp>(re, -im); }
1278
+
1279
+ template<typename _Tp> static inline
1280
+ bool operator == (const Complex<_Tp>& a, const Complex<_Tp>& b)
1281
+ { return a.re == b.re && a.im == b.im; }
1282
+
1283
+ template<typename _Tp> static inline
1284
+ bool operator != (const Complex<_Tp>& a, const Complex<_Tp>& b)
1285
+ { return a.re != b.re || a.im != b.im; }
1286
+
1287
+ template<typename _Tp> static inline
1288
+ Complex<_Tp> operator + (const Complex<_Tp>& a, const Complex<_Tp>& b)
1289
+ { return Complex<_Tp>( a.re + b.re, a.im + b.im ); }
1290
+
1291
+ template<typename _Tp> static inline
1292
+ Complex<_Tp>& operator += (Complex<_Tp>& a, const Complex<_Tp>& b)
1293
+ { a.re += b.re; a.im += b.im; return a; }
1294
+
1295
+ template<typename _Tp> static inline
1296
+ Complex<_Tp> operator - (const Complex<_Tp>& a, const Complex<_Tp>& b)
1297
+ { return Complex<_Tp>( a.re - b.re, a.im - b.im ); }
1298
+
1299
+ template<typename _Tp> static inline
1300
+ Complex<_Tp>& operator -= (Complex<_Tp>& a, const Complex<_Tp>& b)
1301
+ { a.re -= b.re; a.im -= b.im; return a; }
1302
+
1303
+ template<typename _Tp> static inline
1304
+ Complex<_Tp> operator - (const Complex<_Tp>& a)
1305
+ { return Complex<_Tp>(-a.re, -a.im); }
1306
+
1307
+ template<typename _Tp> static inline
1308
+ Complex<_Tp> operator * (const Complex<_Tp>& a, const Complex<_Tp>& b)
1309
+ { return Complex<_Tp>( a.re*b.re - a.im*b.im, a.re*b.im + a.im*b.re ); }
1310
+
1311
+ template<typename _Tp> static inline
1312
+ Complex<_Tp> operator * (const Complex<_Tp>& a, _Tp b)
1313
+ { return Complex<_Tp>( a.re*b, a.im*b ); }
1314
+
1315
+ template<typename _Tp> static inline
1316
+ Complex<_Tp> operator * (_Tp b, const Complex<_Tp>& a)
1317
+ { return Complex<_Tp>( a.re*b, a.im*b ); }
1318
+
1319
+ template<typename _Tp> static inline
1320
+ Complex<_Tp> operator + (const Complex<_Tp>& a, _Tp b)
1321
+ { return Complex<_Tp>( a.re + b, a.im ); }
1322
+
1323
+ template<typename _Tp> static inline
1324
+ Complex<_Tp> operator - (const Complex<_Tp>& a, _Tp b)
1325
+ { return Complex<_Tp>( a.re - b, a.im ); }
1326
+
1327
+ template<typename _Tp> static inline
1328
+ Complex<_Tp> operator + (_Tp b, const Complex<_Tp>& a)
1329
+ { return Complex<_Tp>( a.re + b, a.im ); }
1330
+
1331
+ template<typename _Tp> static inline
1332
+ Complex<_Tp> operator - (_Tp b, const Complex<_Tp>& a)
1333
+ { return Complex<_Tp>( b - a.re, -a.im ); }
1334
+
1335
+ template<typename _Tp> static inline
1336
+ Complex<_Tp>& operator += (Complex<_Tp>& a, _Tp b)
1337
+ { a.re += b; return a; }
1338
+
1339
+ template<typename _Tp> static inline
1340
+ Complex<_Tp>& operator -= (Complex<_Tp>& a, _Tp b)
1341
+ { a.re -= b; return a; }
1342
+
1343
+ template<typename _Tp> static inline
1344
+ Complex<_Tp>& operator *= (Complex<_Tp>& a, _Tp b)
1345
+ { a.re *= b; a.im *= b; return a; }
1346
+
1347
+ template<typename _Tp> static inline
1348
+ double abs(const Complex<_Tp>& a)
1349
+ { return std::sqrt( (double)a.re*a.re + (double)a.im*a.im); }
1350
+
1351
+ template<typename _Tp> static inline
1352
+ Complex<_Tp> operator / (const Complex<_Tp>& a, const Complex<_Tp>& b)
1353
+ {
1354
+ double t = 1./((double)b.re*b.re + (double)b.im*b.im);
1355
+ return Complex<_Tp>( (_Tp)((a.re*b.re + a.im*b.im)*t),
1356
+ (_Tp)((-a.re*b.im + a.im*b.re)*t) );
1357
+ }
1358
+
1359
+ template<typename _Tp> static inline
1360
+ Complex<_Tp>& operator /= (Complex<_Tp>& a, const Complex<_Tp>& b)
1361
+ {
1362
+ return (a = a / b);
1363
+ }
1364
+
1365
+ template<typename _Tp> static inline
1366
+ Complex<_Tp> operator / (const Complex<_Tp>& a, _Tp b)
1367
+ {
1368
+ _Tp t = (_Tp)1/b;
1369
+ return Complex<_Tp>( a.re*t, a.im*t );
1370
+ }
1371
+
1372
+ template<typename _Tp> static inline
1373
+ Complex<_Tp> operator / (_Tp b, const Complex<_Tp>& a)
1374
+ {
1375
+ return Complex<_Tp>(b)/a;
1376
+ }
1377
+
1378
+ template<typename _Tp> static inline
1379
+ Complex<_Tp> operator /= (const Complex<_Tp>& a, _Tp b)
1380
+ {
1381
+ _Tp t = (_Tp)1/b;
1382
+ a.re *= t; a.im *= t; return a;
1383
+ }
1384
+
1385
+ //////////////////////////////// 2D Point ////////////////////////////////
1386
+
1387
+ template<typename _Tp> inline Point_<_Tp>::Point_() : x(0), y(0) {}
1388
+ template<typename _Tp> inline Point_<_Tp>::Point_(_Tp _x, _Tp _y) : x(_x), y(_y) {}
1389
+ template<typename _Tp> inline Point_<_Tp>::Point_(const Point_& pt) : x(pt.x), y(pt.y) {}
1390
+ template<typename _Tp> inline Point_<_Tp>::Point_(const CvPoint& pt) : x((_Tp)pt.x), y((_Tp)pt.y) {}
1391
+ template<typename _Tp> inline Point_<_Tp>::Point_(const CvPoint2D32f& pt)
1392
+ : x(saturate_cast<_Tp>(pt.x)), y(saturate_cast<_Tp>(pt.y)) {}
1393
+ template<typename _Tp> inline Point_<_Tp>::Point_(const Size_<_Tp>& sz) : x(sz.width), y(sz.height) {}
1394
+ template<typename _Tp> inline Point_<_Tp>::Point_(const Vec<_Tp,2>& v) : x(v[0]), y(v[1]) {}
1395
+ template<typename _Tp> inline Point_<_Tp>& Point_<_Tp>::operator = (const Point_& pt)
1396
+ { x = pt.x; y = pt.y; return *this; }
1397
+
1398
+ template<typename _Tp> template<typename _Tp2> inline Point_<_Tp>::operator Point_<_Tp2>() const
1399
+ { return Point_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y)); }
1400
+ template<typename _Tp> inline Point_<_Tp>::operator CvPoint() const
1401
+ { return cvPoint(saturate_cast<int>(x), saturate_cast<int>(y)); }
1402
+ template<typename _Tp> inline Point_<_Tp>::operator CvPoint2D32f() const
1403
+ { return cvPoint2D32f((float)x, (float)y); }
1404
+ template<typename _Tp> inline Point_<_Tp>::operator Vec<_Tp, 2>() const
1405
+ { return Vec<_Tp, 2>(x, y); }
1406
+
1407
+ template<typename _Tp> inline _Tp Point_<_Tp>::dot(const Point_& pt) const
1408
+ { return saturate_cast<_Tp>(x*pt.x + y*pt.y); }
1409
+ template<typename _Tp> inline double Point_<_Tp>::ddot(const Point_& pt) const
1410
+ { return (double)x*pt.x + (double)y*pt.y; }
1411
+
1412
+ template<typename _Tp> static inline Point_<_Tp>&
1413
+ operator += (Point_<_Tp>& a, const Point_<_Tp>& b)
1414
+ {
1415
+ a.x = saturate_cast<_Tp>(a.x + b.x);
1416
+ a.y = saturate_cast<_Tp>(a.y + b.y);
1417
+ return a;
1418
+ }
1419
+
1420
+ template<typename _Tp> static inline Point_<_Tp>&
1421
+ operator -= (Point_<_Tp>& a, const Point_<_Tp>& b)
1422
+ {
1423
+ a.x = saturate_cast<_Tp>(a.x - b.x);
1424
+ a.y = saturate_cast<_Tp>(a.y - b.y);
1425
+ return a;
1426
+ }
1427
+
1428
+ template<typename _Tp> static inline Point_<_Tp>&
1429
+ operator *= (Point_<_Tp>& a, int b)
1430
+ {
1431
+ a.x = saturate_cast<_Tp>(a.x*b);
1432
+ a.y = saturate_cast<_Tp>(a.y*b);
1433
+ return a;
1434
+ }
1435
+
1436
+ template<typename _Tp> static inline Point_<_Tp>&
1437
+ operator *= (Point_<_Tp>& a, float b)
1438
+ {
1439
+ a.x = saturate_cast<_Tp>(a.x*b);
1440
+ a.y = saturate_cast<_Tp>(a.y*b);
1441
+ return a;
1442
+ }
1443
+
1444
+ template<typename _Tp> static inline Point_<_Tp>&
1445
+ operator *= (Point_<_Tp>& a, double b)
1446
+ {
1447
+ a.x = saturate_cast<_Tp>(a.x*b);
1448
+ a.y = saturate_cast<_Tp>(a.y*b);
1449
+ return a;
1450
+ }
1451
+
1452
+ template<typename _Tp> static inline double norm(const Point_<_Tp>& pt)
1453
+ { return std::sqrt((double)pt.x*pt.x + (double)pt.y*pt.y); }
1454
+
1455
+ template<typename _Tp> static inline bool operator == (const Point_<_Tp>& a, const Point_<_Tp>& b)
1456
+ { return a.x == b.x && a.y == b.y; }
1457
+
1458
+ template<typename _Tp> static inline bool operator != (const Point_<_Tp>& a, const Point_<_Tp>& b)
1459
+ { return a.x != b.x || a.y != b.y; }
1460
+
1461
+ template<typename _Tp> static inline Point_<_Tp> operator + (const Point_<_Tp>& a, const Point_<_Tp>& b)
1462
+ { return Point_<_Tp>( saturate_cast<_Tp>(a.x + b.x), saturate_cast<_Tp>(a.y + b.y) ); }
1463
+
1464
+ template<typename _Tp> static inline Point_<_Tp> operator - (const Point_<_Tp>& a, const Point_<_Tp>& b)
1465
+ { return Point_<_Tp>( saturate_cast<_Tp>(a.x - b.x), saturate_cast<_Tp>(a.y - b.y) ); }
1466
+
1467
+ template<typename _Tp> static inline Point_<_Tp> operator - (const Point_<_Tp>& a)
1468
+ { return Point_<_Tp>( saturate_cast<_Tp>(-a.x), saturate_cast<_Tp>(-a.y) ); }
1469
+
1470
+ template<typename _Tp> static inline Point_<_Tp> operator * (const Point_<_Tp>& a, int b)
1471
+ { return Point_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b) ); }
1472
+
1473
+ template<typename _Tp> static inline Point_<_Tp> operator * (int a, const Point_<_Tp>& b)
1474
+ { return Point_<_Tp>( saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a) ); }
1475
+
1476
+ template<typename _Tp> static inline Point_<_Tp> operator * (const Point_<_Tp>& a, float b)
1477
+ { return Point_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b) ); }
1478
+
1479
+ template<typename _Tp> static inline Point_<_Tp> operator * (float a, const Point_<_Tp>& b)
1480
+ { return Point_<_Tp>( saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a) ); }
1481
+
1482
+ template<typename _Tp> static inline Point_<_Tp> operator * (const Point_<_Tp>& a, double b)
1483
+ { return Point_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b) ); }
1484
+
1485
+ template<typename _Tp> static inline Point_<_Tp> operator * (double a, const Point_<_Tp>& b)
1486
+ { return Point_<_Tp>( saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a) ); }
1487
+
1488
+ //////////////////////////////// 3D Point ////////////////////////////////
1489
+
1490
+ template<typename _Tp> inline Point3_<_Tp>::Point3_() : x(0), y(0), z(0) {}
1491
+ template<typename _Tp> inline Point3_<_Tp>::Point3_(_Tp _x, _Tp _y, _Tp _z) : x(_x), y(_y), z(_z) {}
1492
+ template<typename _Tp> inline Point3_<_Tp>::Point3_(const Point3_& pt) : x(pt.x), y(pt.y), z(pt.z) {}
1493
+ template<typename _Tp> inline Point3_<_Tp>::Point3_(const Point_<_Tp>& pt) : x(pt.x), y(pt.y), z(_Tp()) {}
1494
+ template<typename _Tp> inline Point3_<_Tp>::Point3_(const CvPoint3D32f& pt) :
1495
+ x(saturate_cast<_Tp>(pt.x)), y(saturate_cast<_Tp>(pt.y)), z(saturate_cast<_Tp>(pt.z)) {}
1496
+ template<typename _Tp> inline Point3_<_Tp>::Point3_(const Vec<_Tp, 3>& v) : x(v[0]), y(v[1]), z(v[2]) {}
1497
+
1498
+ template<typename _Tp> template<typename _Tp2> inline Point3_<_Tp>::operator Point3_<_Tp2>() const
1499
+ { return Point3_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y), saturate_cast<_Tp2>(z)); }
1500
+
1501
+ template<typename _Tp> inline Point3_<_Tp>::operator CvPoint3D32f() const
1502
+ { return cvPoint3D32f((float)x, (float)y, (float)z); }
1503
+
1504
+ template<typename _Tp> inline Point3_<_Tp>::operator Vec<_Tp, 3>() const
1505
+ { return Vec<_Tp, 3>(x, y, z); }
1506
+
1507
+ template<typename _Tp> inline Point3_<_Tp>& Point3_<_Tp>::operator = (const Point3_& pt)
1508
+ { x = pt.x; y = pt.y; z = pt.z; return *this; }
1509
+
1510
+ template<typename _Tp> inline _Tp Point3_<_Tp>::dot(const Point3_& pt) const
1511
+ { return saturate_cast<_Tp>(x*pt.x + y*pt.y + z*pt.z); }
1512
+ template<typename _Tp> inline double Point3_<_Tp>::ddot(const Point3_& pt) const
1513
+ { return (double)x*pt.x + (double)y*pt.y + (double)z*pt.z; }
1514
+
1515
+ template<typename _Tp> inline Point3_<_Tp> Point3_<_Tp>::cross(const Point3_<_Tp>& pt) const
1516
+ {
1517
+ return Point3_<_Tp>(y*pt.z - z*pt.y, z*pt.x - x*pt.z, x*pt.y - y*pt.x);
1518
+ }
1519
+
1520
+ template<typename _Tp> static inline Point3_<_Tp>&
1521
+ operator += (Point3_<_Tp>& a, const Point3_<_Tp>& b)
1522
+ {
1523
+ a.x = saturate_cast<_Tp>(a.x + b.x);
1524
+ a.y = saturate_cast<_Tp>(a.y + b.y);
1525
+ a.z = saturate_cast<_Tp>(a.z + b.z);
1526
+ return a;
1527
+ }
1528
+
1529
+ template<typename _Tp> static inline Point3_<_Tp>&
1530
+ operator -= (Point3_<_Tp>& a, const Point3_<_Tp>& b)
1531
+ {
1532
+ a.x = saturate_cast<_Tp>(a.x - b.x);
1533
+ a.y = saturate_cast<_Tp>(a.y - b.y);
1534
+ a.z = saturate_cast<_Tp>(a.z - b.z);
1535
+ return a;
1536
+ }
1537
+
1538
+ template<typename _Tp> static inline Point3_<_Tp>&
1539
+ operator *= (Point3_<_Tp>& a, int b)
1540
+ {
1541
+ a.x = saturate_cast<_Tp>(a.x*b);
1542
+ a.y = saturate_cast<_Tp>(a.y*b);
1543
+ a.z = saturate_cast<_Tp>(a.z*b);
1544
+ return a;
1545
+ }
1546
+
1547
+ template<typename _Tp> static inline Point3_<_Tp>&
1548
+ operator *= (Point3_<_Tp>& a, float b)
1549
+ {
1550
+ a.x = saturate_cast<_Tp>(a.x*b);
1551
+ a.y = saturate_cast<_Tp>(a.y*b);
1552
+ a.z = saturate_cast<_Tp>(a.z*b);
1553
+ return a;
1554
+ }
1555
+
1556
+ template<typename _Tp> static inline Point3_<_Tp>&
1557
+ operator *= (Point3_<_Tp>& a, double b)
1558
+ {
1559
+ a.x = saturate_cast<_Tp>(a.x*b);
1560
+ a.y = saturate_cast<_Tp>(a.y*b);
1561
+ a.z = saturate_cast<_Tp>(a.z*b);
1562
+ return a;
1563
+ }
1564
+
1565
+ template<typename _Tp> static inline double norm(const Point3_<_Tp>& pt)
1566
+ { return std::sqrt((double)pt.x*pt.x + (double)pt.y*pt.y + (double)pt.z*pt.z); }
1567
+
1568
+ template<typename _Tp> static inline bool operator == (const Point3_<_Tp>& a, const Point3_<_Tp>& b)
1569
+ { return a.x == b.x && a.y == b.y && a.z == b.z; }
1570
+
1571
+ template<typename _Tp> static inline bool operator != (const Point3_<_Tp>& a, const Point3_<_Tp>& b)
1572
+ { return a.x != b.x || a.y != b.y || a.z != b.z; }
1573
+
1574
+ template<typename _Tp> static inline Point3_<_Tp> operator + (const Point3_<_Tp>& a, const Point3_<_Tp>& b)
1575
+ { return Point3_<_Tp>( saturate_cast<_Tp>(a.x + b.x),
1576
+ saturate_cast<_Tp>(a.y + b.y),
1577
+ saturate_cast<_Tp>(a.z + b.z)); }
1578
+
1579
+ template<typename _Tp> static inline Point3_<_Tp> operator - (const Point3_<_Tp>& a, const Point3_<_Tp>& b)
1580
+ { return Point3_<_Tp>( saturate_cast<_Tp>(a.x - b.x),
1581
+ saturate_cast<_Tp>(a.y - b.y),
1582
+ saturate_cast<_Tp>(a.z - b.z)); }
1583
+
1584
+ template<typename _Tp> static inline Point3_<_Tp> operator - (const Point3_<_Tp>& a)
1585
+ { return Point3_<_Tp>( saturate_cast<_Tp>(-a.x),
1586
+ saturate_cast<_Tp>(-a.y),
1587
+ saturate_cast<_Tp>(-a.z) ); }
1588
+
1589
+ template<typename _Tp> static inline Point3_<_Tp> operator * (const Point3_<_Tp>& a, int b)
1590
+ { return Point3_<_Tp>( saturate_cast<_Tp>(a.x*b),
1591
+ saturate_cast<_Tp>(a.y*b),
1592
+ saturate_cast<_Tp>(a.z*b) ); }
1593
+
1594
+ template<typename _Tp> static inline Point3_<_Tp> operator * (int a, const Point3_<_Tp>& b)
1595
+ { return Point3_<_Tp>( saturate_cast<_Tp>(b.x*a),
1596
+ saturate_cast<_Tp>(b.y*a),
1597
+ saturate_cast<_Tp>(b.z*a) ); }
1598
+
1599
+ template<typename _Tp> static inline Point3_<_Tp> operator * (const Point3_<_Tp>& a, float b)
1600
+ { return Point3_<_Tp>( saturate_cast<_Tp>(a.x*b),
1601
+ saturate_cast<_Tp>(a.y*b),
1602
+ saturate_cast<_Tp>(a.z*b) ); }
1603
+
1604
+ template<typename _Tp> static inline Point3_<_Tp> operator * (float a, const Point3_<_Tp>& b)
1605
+ { return Point3_<_Tp>( saturate_cast<_Tp>(b.x*a),
1606
+ saturate_cast<_Tp>(b.y*a),
1607
+ saturate_cast<_Tp>(b.z*a) ); }
1608
+
1609
+ template<typename _Tp> static inline Point3_<_Tp> operator * (const Point3_<_Tp>& a, double b)
1610
+ { return Point3_<_Tp>( saturate_cast<_Tp>(a.x*b),
1611
+ saturate_cast<_Tp>(a.y*b),
1612
+ saturate_cast<_Tp>(a.z*b) ); }
1613
+
1614
+ template<typename _Tp> static inline Point3_<_Tp> operator * (double a, const Point3_<_Tp>& b)
1615
+ { return Point3_<_Tp>( saturate_cast<_Tp>(b.x*a),
1616
+ saturate_cast<_Tp>(b.y*a),
1617
+ saturate_cast<_Tp>(b.z*a) ); }
1618
+
1619
+ //////////////////////////////// Size ////////////////////////////////
1620
+
1621
+ template<typename _Tp> inline Size_<_Tp>::Size_()
1622
+ : width(0), height(0) {}
1623
+ template<typename _Tp> inline Size_<_Tp>::Size_(_Tp _width, _Tp _height)
1624
+ : width(_width), height(_height) {}
1625
+ template<typename _Tp> inline Size_<_Tp>::Size_(const Size_& sz)
1626
+ : width(sz.width), height(sz.height) {}
1627
+ template<typename _Tp> inline Size_<_Tp>::Size_(const CvSize& sz)
1628
+ : width(saturate_cast<_Tp>(sz.width)), height(saturate_cast<_Tp>(sz.height)) {}
1629
+ template<typename _Tp> inline Size_<_Tp>::Size_(const CvSize2D32f& sz)
1630
+ : width(saturate_cast<_Tp>(sz.width)), height(saturate_cast<_Tp>(sz.height)) {}
1631
+ template<typename _Tp> inline Size_<_Tp>::Size_(const Point_<_Tp>& pt) : width(pt.x), height(pt.y) {}
1632
+
1633
+ template<typename _Tp> template<typename _Tp2> inline Size_<_Tp>::operator Size_<_Tp2>() const
1634
+ { return Size_<_Tp2>(saturate_cast<_Tp2>(width), saturate_cast<_Tp2>(height)); }
1635
+ template<typename _Tp> inline Size_<_Tp>::operator CvSize() const
1636
+ { return cvSize(saturate_cast<int>(width), saturate_cast<int>(height)); }
1637
+ template<typename _Tp> inline Size_<_Tp>::operator CvSize2D32f() const
1638
+ { return cvSize2D32f((float)width, (float)height); }
1639
+
1640
+ template<typename _Tp> inline Size_<_Tp>& Size_<_Tp>::operator = (const Size_<_Tp>& sz)
1641
+ { width = sz.width; height = sz.height; return *this; }
1642
+ template<typename _Tp> static inline Size_<_Tp> operator * (const Size_<_Tp>& a, _Tp b)
1643
+ { return Size_<_Tp>(a.width * b, a.height * b); }
1644
+ template<typename _Tp> static inline Size_<_Tp> operator + (const Size_<_Tp>& a, const Size_<_Tp>& b)
1645
+ { return Size_<_Tp>(a.width + b.width, a.height + b.height); }
1646
+ template<typename _Tp> static inline Size_<_Tp> operator - (const Size_<_Tp>& a, const Size_<_Tp>& b)
1647
+ { return Size_<_Tp>(a.width - b.width, a.height - b.height); }
1648
+ template<typename _Tp> inline _Tp Size_<_Tp>::area() const { return width*height; }
1649
+
1650
+ template<typename _Tp> static inline Size_<_Tp>& operator += (Size_<_Tp>& a, const Size_<_Tp>& b)
1651
+ { a.width += b.width; a.height += b.height; return a; }
1652
+ template<typename _Tp> static inline Size_<_Tp>& operator -= (Size_<_Tp>& a, const Size_<_Tp>& b)
1653
+ { a.width -= b.width; a.height -= b.height; return a; }
1654
+
1655
+ template<typename _Tp> static inline bool operator == (const Size_<_Tp>& a, const Size_<_Tp>& b)
1656
+ { return a.width == b.width && a.height == b.height; }
1657
+ template<typename _Tp> static inline bool operator != (const Size_<_Tp>& a, const Size_<_Tp>& b)
1658
+ { return a.width != b.width || a.height != b.height; }
1659
+
1660
+ //////////////////////////////// Rect ////////////////////////////////
1661
+
1662
+
1663
+ template<typename _Tp> inline Rect_<_Tp>::Rect_() : x(0), y(0), width(0), height(0) {}
1664
+ template<typename _Tp> inline Rect_<_Tp>::Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height) : x(_x), y(_y), width(_width), height(_height) {}
1665
+ template<typename _Tp> inline Rect_<_Tp>::Rect_(const Rect_<_Tp>& r) : x(r.x), y(r.y), width(r.width), height(r.height) {}
1666
+ template<typename _Tp> inline Rect_<_Tp>::Rect_(const CvRect& r) : x((_Tp)r.x), y((_Tp)r.y), width((_Tp)r.width), height((_Tp)r.height) {}
1667
+ template<typename _Tp> inline Rect_<_Tp>::Rect_(const Point_<_Tp>& org, const Size_<_Tp>& sz) :
1668
+ x(org.x), y(org.y), width(sz.width), height(sz.height) {}
1669
+ template<typename _Tp> inline Rect_<_Tp>::Rect_(const Point_<_Tp>& pt1, const Point_<_Tp>& pt2)
1670
+ {
1671
+ x = std::min(pt1.x, pt2.x); y = std::min(pt1.y, pt2.y);
1672
+ width = std::max(pt1.x, pt2.x) - x; height = std::max(pt1.y, pt2.y) - y;
1673
+ }
1674
+ template<typename _Tp> inline Rect_<_Tp>& Rect_<_Tp>::operator = ( const Rect_<_Tp>& r )
1675
+ { x = r.x; y = r.y; width = r.width; height = r.height; return *this; }
1676
+
1677
+ template<typename _Tp> inline Point_<_Tp> Rect_<_Tp>::tl() const { return Point_<_Tp>(x,y); }
1678
+ template<typename _Tp> inline Point_<_Tp> Rect_<_Tp>::br() const { return Point_<_Tp>(x+width, y+height); }
1679
+
1680
+ template<typename _Tp> static inline Rect_<_Tp>& operator += ( Rect_<_Tp>& a, const Point_<_Tp>& b )
1681
+ { a.x += b.x; a.y += b.y; return a; }
1682
+ template<typename _Tp> static inline Rect_<_Tp>& operator -= ( Rect_<_Tp>& a, const Point_<_Tp>& b )
1683
+ { a.x -= b.x; a.y -= b.y; return a; }
1684
+
1685
+ template<typename _Tp> static inline Rect_<_Tp>& operator += ( Rect_<_Tp>& a, const Size_<_Tp>& b )
1686
+ { a.width += b.width; a.height += b.height; return a; }
1687
+
1688
+ template<typename _Tp> static inline Rect_<_Tp>& operator -= ( Rect_<_Tp>& a, const Size_<_Tp>& b )
1689
+ { a.width -= b.width; a.height -= b.height; return a; }
1690
+
1691
+ template<typename _Tp> static inline Rect_<_Tp>& operator &= ( Rect_<_Tp>& a, const Rect_<_Tp>& b )
1692
+ {
1693
+ _Tp x1 = std::max(a.x, b.x), y1 = std::max(a.y, b.y);
1694
+ a.width = std::min(a.x + a.width, b.x + b.width) - x1;
1695
+ a.height = std::min(a.y + a.height, b.y + b.height) - y1;
1696
+ a.x = x1; a.y = y1;
1697
+ if( a.width <= 0 || a.height <= 0 )
1698
+ a = Rect();
1699
+ return a;
1700
+ }
1701
+
1702
+ template<typename _Tp> static inline Rect_<_Tp>& operator |= ( Rect_<_Tp>& a, const Rect_<_Tp>& b )
1703
+ {
1704
+ _Tp x1 = std::min(a.x, b.x), y1 = std::min(a.y, b.y);
1705
+ a.width = std::max(a.x + a.width, b.x + b.width) - x1;
1706
+ a.height = std::max(a.y + a.height, b.y + b.height) - y1;
1707
+ a.x = x1; a.y = y1;
1708
+ return a;
1709
+ }
1710
+
1711
+ template<typename _Tp> inline Size_<_Tp> Rect_<_Tp>::size() const { return Size_<_Tp>(width, height); }
1712
+ template<typename _Tp> inline _Tp Rect_<_Tp>::area() const { return width*height; }
1713
+
1714
+ template<typename _Tp> template<typename _Tp2> inline Rect_<_Tp>::operator Rect_<_Tp2>() const
1715
+ { return Rect_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y),
1716
+ saturate_cast<_Tp2>(width), saturate_cast<_Tp2>(height)); }
1717
+ template<typename _Tp> inline Rect_<_Tp>::operator CvRect() const
1718
+ { return cvRect(saturate_cast<int>(x), saturate_cast<int>(y),
1719
+ saturate_cast<int>(width), saturate_cast<int>(height)); }
1720
+
1721
+ template<typename _Tp> inline bool Rect_<_Tp>::contains(const Point_<_Tp>& pt) const
1722
+ { return x <= pt.x && pt.x < x + width && y <= pt.y && pt.y < y + height; }
1723
+
1724
+ template<typename _Tp> static inline bool operator == (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
1725
+ {
1726
+ return a.x == b.x && a.y == b.y && a.width == b.width && a.height == b.height;
1727
+ }
1728
+
1729
+ template<typename _Tp> static inline bool operator != (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
1730
+ {
1731
+ return a.x != b.x || a.y != b.y || a.width != b.width || a.height != b.height;
1732
+ }
1733
+
1734
+ template<typename _Tp> static inline Rect_<_Tp> operator + (const Rect_<_Tp>& a, const Point_<_Tp>& b)
1735
+ {
1736
+ return Rect_<_Tp>( a.x + b.x, a.y + b.y, a.width, a.height );
1737
+ }
1738
+
1739
+ template<typename _Tp> static inline Rect_<_Tp> operator - (const Rect_<_Tp>& a, const Point_<_Tp>& b)
1740
+ {
1741
+ return Rect_<_Tp>( a.x - b.x, a.y - b.y, a.width, a.height );
1742
+ }
1743
+
1744
+ template<typename _Tp> static inline Rect_<_Tp> operator + (const Rect_<_Tp>& a, const Size_<_Tp>& b)
1745
+ {
1746
+ return Rect_<_Tp>( a.x, a.y, a.width + b.width, a.height + b.height );
1747
+ }
1748
+
1749
+ template<typename _Tp> static inline Rect_<_Tp> operator & (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
1750
+ {
1751
+ Rect_<_Tp> c = a;
1752
+ return c &= b;
1753
+ }
1754
+
1755
+ template<typename _Tp> static inline Rect_<_Tp> operator | (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
1756
+ {
1757
+ Rect_<_Tp> c = a;
1758
+ return c |= b;
1759
+ }
1760
+
1761
+ template<typename _Tp> inline bool Point_<_Tp>::inside( const Rect_<_Tp>& r ) const
1762
+ {
1763
+ return r.contains(*this);
1764
+ }
1765
+
1766
+ inline RotatedRect::RotatedRect() { angle = 0; }
1767
+ inline RotatedRect::RotatedRect(const Point2f& _center, const Size2f& _size, float _angle)
1768
+ : center(_center), size(_size), angle(_angle) {}
1769
+ inline RotatedRect::RotatedRect(const CvBox2D& box)
1770
+ : center(box.center), size(box.size), angle(box.angle) {}
1771
+ inline RotatedRect::operator CvBox2D() const
1772
+ {
1773
+ CvBox2D box; box.center = center; box.size = size; box.angle = angle;
1774
+ return box;
1775
+ }
1776
+
1777
+ //////////////////////////////// Scalar_ ///////////////////////////////
1778
+
1779
+ template<typename _Tp> inline Scalar_<_Tp>::Scalar_()
1780
+ { this->val[0] = this->val[1] = this->val[2] = this->val[3] = 0; }
1781
+
1782
+ template<typename _Tp> inline Scalar_<_Tp>::Scalar_(_Tp v0, _Tp v1, _Tp v2, _Tp v3)
1783
+ { this->val[0] = v0; this->val[1] = v1; this->val[2] = v2; this->val[3] = v3; }
1784
+
1785
+ template<typename _Tp> inline Scalar_<_Tp>::Scalar_(const CvScalar& s)
1786
+ {
1787
+ this->val[0] = saturate_cast<_Tp>(s.val[0]);
1788
+ this->val[1] = saturate_cast<_Tp>(s.val[1]);
1789
+ this->val[2] = saturate_cast<_Tp>(s.val[2]);
1790
+ this->val[3] = saturate_cast<_Tp>(s.val[3]);
1791
+ }
1792
+
1793
+ template<typename _Tp> inline Scalar_<_Tp>::Scalar_(_Tp v0)
1794
+ { this->val[0] = v0; this->val[1] = this->val[2] = this->val[3] = 0; }
1795
+
1796
+ template<typename _Tp> inline Scalar_<_Tp> Scalar_<_Tp>::all(_Tp v0)
1797
+ { return Scalar_<_Tp>(v0, v0, v0, v0); }
1798
+ template<typename _Tp> inline Scalar_<_Tp>::operator CvScalar() const
1799
+ { return cvScalar(this->val[0], this->val[1], this->val[2], this->val[3]); }
1800
+
1801
+ template<typename _Tp> template<typename T2> inline Scalar_<_Tp>::operator Scalar_<T2>() const
1802
+ {
1803
+ return Scalar_<T2>(saturate_cast<T2>(this->val[0]),
1804
+ saturate_cast<T2>(this->val[1]),
1805
+ saturate_cast<T2>(this->val[2]),
1806
+ saturate_cast<T2>(this->val[3]));
1807
+ }
1808
+
1809
+ template<typename _Tp> static inline Scalar_<_Tp>& operator += (Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
1810
+ {
1811
+ a.val[0] = saturate_cast<_Tp>(a.val[0] + b.val[0]);
1812
+ a.val[1] = saturate_cast<_Tp>(a.val[1] + b.val[1]);
1813
+ a.val[2] = saturate_cast<_Tp>(a.val[2] + b.val[2]);
1814
+ a.val[3] = saturate_cast<_Tp>(a.val[3] + b.val[3]);
1815
+ return a;
1816
+ }
1817
+
1818
+ template<typename _Tp> static inline Scalar_<_Tp>& operator -= (Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
1819
+ {
1820
+ a.val[0] = saturate_cast<_Tp>(a.val[0] - b.val[0]);
1821
+ a.val[1] = saturate_cast<_Tp>(a.val[1] - b.val[1]);
1822
+ a.val[2] = saturate_cast<_Tp>(a.val[2] - b.val[2]);
1823
+ a.val[3] = saturate_cast<_Tp>(a.val[3] - b.val[3]);
1824
+ return a;
1825
+ }
1826
+
1827
+ template<typename _Tp> static inline Scalar_<_Tp>& operator *= ( Scalar_<_Tp>& a, _Tp v )
1828
+ {
1829
+ a.val[0] = saturate_cast<_Tp>(a.val[0] * v);
1830
+ a.val[1] = saturate_cast<_Tp>(a.val[1] * v);
1831
+ a.val[2] = saturate_cast<_Tp>(a.val[2] * v);
1832
+ a.val[3] = saturate_cast<_Tp>(a.val[3] * v);
1833
+ return a;
1834
+ }
1835
+
1836
+ template<typename _Tp> inline Scalar_<_Tp> Scalar_<_Tp>::mul(const Scalar_<_Tp>& t, double scale ) const
1837
+ {
1838
+ return Scalar_<_Tp>( saturate_cast<_Tp>(this->val[0]*t.val[0]*scale),
1839
+ saturate_cast<_Tp>(this->val[1]*t.val[1]*scale),
1840
+ saturate_cast<_Tp>(this->val[2]*t.val[2]*scale),
1841
+ saturate_cast<_Tp>(this->val[3]*t.val[3]*scale));
1842
+ }
1843
+
1844
+ template<typename _Tp> static inline bool operator == ( const Scalar_<_Tp>& a, const Scalar_<_Tp>& b )
1845
+ {
1846
+ return a.val[0] == b.val[0] && a.val[1] == b.val[1] &&
1847
+ a.val[2] == b.val[2] && a.val[3] == b.val[3];
1848
+ }
1849
+
1850
+ template<typename _Tp> static inline bool operator != ( const Scalar_<_Tp>& a, const Scalar_<_Tp>& b )
1851
+ {
1852
+ return a.val[0] != b.val[0] || a.val[1] != b.val[1] ||
1853
+ a.val[2] != b.val[2] || a.val[3] != b.val[3];
1854
+ }
1855
+
1856
+ template<typename _Tp> static inline Scalar_<_Tp> operator + (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
1857
+ {
1858
+ return Scalar_<_Tp>(saturate_cast<_Tp>(a.val[0] + b.val[0]),
1859
+ saturate_cast<_Tp>(a.val[1] + b.val[1]),
1860
+ saturate_cast<_Tp>(a.val[2] + b.val[2]),
1861
+ saturate_cast<_Tp>(a.val[3] + b.val[3]));
1862
+ }
1863
+
1864
+ template<typename _Tp> static inline Scalar_<_Tp> operator - (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
1865
+ {
1866
+ return Scalar_<_Tp>(saturate_cast<_Tp>(a.val[0] - b.val[0]),
1867
+ saturate_cast<_Tp>(a.val[1] - b.val[1]),
1868
+ saturate_cast<_Tp>(a.val[2] - b.val[2]),
1869
+ saturate_cast<_Tp>(a.val[3] - b.val[3]));
1870
+ }
1871
+
1872
+ template<typename _Tp> static inline Scalar_<_Tp> operator * (const Scalar_<_Tp>& a, _Tp alpha)
1873
+ {
1874
+ return Scalar_<_Tp>(saturate_cast<_Tp>(a.val[0] * alpha),
1875
+ saturate_cast<_Tp>(a.val[1] * alpha),
1876
+ saturate_cast<_Tp>(a.val[2] * alpha),
1877
+ saturate_cast<_Tp>(a.val[3] * alpha));
1878
+ }
1879
+
1880
+ template<typename _Tp> static inline Scalar_<_Tp> operator * (_Tp alpha, const Scalar_<_Tp>& a)
1881
+ {
1882
+ return a*alpha;
1883
+ }
1884
+
1885
+ template<typename _Tp> static inline Scalar_<_Tp> operator - (const Scalar_<_Tp>& a)
1886
+ {
1887
+ return Scalar_<_Tp>(saturate_cast<_Tp>(-a.val[0]), saturate_cast<_Tp>(-a.val[1]),
1888
+ saturate_cast<_Tp>(-a.val[2]), saturate_cast<_Tp>(-a.val[3]));
1889
+ }
1890
+
1891
+
1892
+ template<typename _Tp> static inline Scalar_<_Tp>
1893
+ operator * (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
1894
+ {
1895
+ return Scalar_<_Tp>(saturate_cast<_Tp>(a[0]*b[0] - a[1]*b[1] - a[2]*b[2] - a[3]*b[3]),
1896
+ saturate_cast<_Tp>(a[0]*b[1] + a[1]*b[0] + a[2]*b[3] - a[3]*b[2]),
1897
+ saturate_cast<_Tp>(a[0]*b[2] - a[1]*b[3] + a[2]*b[0] - a[3]*b[1]),
1898
+ saturate_cast<_Tp>(a[0]*b[3] + a[1]*b[2] - a[2]*b[1] - a[3]*b[0]));
1899
+ }
1900
+
1901
+ template<typename _Tp> static inline Scalar_<_Tp>&
1902
+ operator *= (Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
1903
+ {
1904
+ a = a*b;
1905
+ return a;
1906
+ }
1907
+
1908
+ template<typename _Tp> inline Scalar_<_Tp> Scalar_<_Tp>::conj() const
1909
+ {
1910
+ return Scalar_<_Tp>(saturate_cast<_Tp>(this->val[0]),
1911
+ saturate_cast<_Tp>(-this->val[1]),
1912
+ saturate_cast<_Tp>(-this->val[2]),
1913
+ saturate_cast<_Tp>(-this->val[3]));
1914
+ }
1915
+
1916
+ template<typename _Tp> inline bool Scalar_<_Tp>::isReal() const
1917
+ {
1918
+ return this->val[1] == 0 && this->val[2] == 0 && this->val[3] == 0;
1919
+ }
1920
+
1921
+ template<typename _Tp> static inline
1922
+ Scalar_<_Tp> operator / (const Scalar_<_Tp>& a, _Tp alpha)
1923
+ {
1924
+ return Scalar_<_Tp>(saturate_cast<_Tp>(a.val[0] / alpha),
1925
+ saturate_cast<_Tp>(a.val[1] / alpha),
1926
+ saturate_cast<_Tp>(a.val[2] / alpha),
1927
+ saturate_cast<_Tp>(a.val[3] / alpha));
1928
+ }
1929
+
1930
+ template<typename _Tp> static inline
1931
+ Scalar_<float> operator / (const Scalar_<float>& a, float alpha)
1932
+ {
1933
+ float s = 1/alpha;
1934
+ return Scalar_<float>(a.val[0]*s, a.val[1]*s, a.val[2]*s, a.val[3]*s);
1935
+ }
1936
+
1937
+ template<typename _Tp> static inline
1938
+ Scalar_<double> operator / (const Scalar_<double>& a, double alpha)
1939
+ {
1940
+ double s = 1/alpha;
1941
+ return Scalar_<double>(a.val[0]*s, a.val[1]*s, a.val[2]*s, a.val[3]*s);
1942
+ }
1943
+
1944
+ template<typename _Tp> static inline
1945
+ Scalar_<_Tp>& operator /= (Scalar_<_Tp>& a, _Tp alpha)
1946
+ {
1947
+ a = a/alpha;
1948
+ return a;
1949
+ }
1950
+
1951
+ template<typename _Tp> static inline
1952
+ Scalar_<_Tp> operator / (_Tp a, const Scalar_<_Tp>& b)
1953
+ {
1954
+ _Tp s = a/(b[0]*b[0] + b[1]*b[1] + b[2]*b[2] + b[3]*b[3]);
1955
+ return b.conj()*s;
1956
+ }
1957
+
1958
+ template<typename _Tp> static inline
1959
+ Scalar_<_Tp> operator / (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
1960
+ {
1961
+ return a*((_Tp)1/b);
1962
+ }
1963
+
1964
+ template<typename _Tp> static inline
1965
+ Scalar_<_Tp>& operator /= (Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
1966
+ {
1967
+ a = a/b;
1968
+ return a;
1969
+ }
1970
+
1971
+ //////////////////////////////// Range /////////////////////////////////
1972
+
1973
+ inline Range::Range() : start(0), end(0) {}
1974
+ inline Range::Range(int _start, int _end) : start(_start), end(_end) {}
1975
+ inline Range::Range(const CvSlice& slice) : start(slice.start_index), end(slice.end_index)
1976
+ {
1977
+ if( start == 0 && end == CV_WHOLE_SEQ_END_INDEX )
1978
+ *this = Range::all();
1979
+ }
1980
+
1981
+ inline int Range::size() const { return end - start; }
1982
+ inline bool Range::empty() const { return start == end; }
1983
+ inline Range Range::all() { return Range(INT_MIN, INT_MAX); }
1984
+
1985
+ static inline bool operator == (const Range& r1, const Range& r2)
1986
+ { return r1.start == r2.start && r1.end == r2.end; }
1987
+
1988
+ static inline bool operator != (const Range& r1, const Range& r2)
1989
+ { return !(r1 == r2); }
1990
+
1991
+ static inline bool operator !(const Range& r)
1992
+ { return r.start == r.end; }
1993
+
1994
+ static inline Range operator & (const Range& r1, const Range& r2)
1995
+ {
1996
+ Range r(std::max(r1.start, r2.start), std::min(r1.end, r2.end));
1997
+ r.end = std::max(r.end, r.start);
1998
+ return r;
1999
+ }
2000
+
2001
+ static inline Range& operator &= (Range& r1, const Range& r2)
2002
+ {
2003
+ r1 = r1 & r2;
2004
+ return r1;
2005
+ }
2006
+
2007
+ static inline Range operator + (const Range& r1, int delta)
2008
+ {
2009
+ return Range(r1.start + delta, r1.end + delta);
2010
+ }
2011
+
2012
+ static inline Range operator + (int delta, const Range& r1)
2013
+ {
2014
+ return Range(r1.start + delta, r1.end + delta);
2015
+ }
2016
+
2017
+ static inline Range operator - (const Range& r1, int delta)
2018
+ {
2019
+ return r1 + (-delta);
2020
+ }
2021
+
2022
+ inline Range::operator CvSlice() const
2023
+ { return *this != Range::all() ? cvSlice(start, end) : CV_WHOLE_SEQ; }
2024
+
2025
+
2026
+
2027
+ //////////////////////////////// Vector ////////////////////////////////
2028
+
2029
+ // template vector class. It is similar to STL's vector,
2030
+ // with a few important differences:
2031
+ // 1) it can be created on top of user-allocated data w/o copying it
2032
+ // 2) vector b = a means copying the header,
2033
+ // not the underlying data (use clone() to make a deep copy)
2034
+ template <typename _Tp> class CV_EXPORTS Vector
2035
+ {
2036
+ public:
2037
+ typedef _Tp value_type;
2038
+ typedef _Tp* iterator;
2039
+ typedef const _Tp* const_iterator;
2040
+ typedef _Tp& reference;
2041
+ typedef const _Tp& const_reference;
2042
+
2043
+ struct CV_EXPORTS Hdr
2044
+ {
2045
+ Hdr() : data(0), datastart(0), refcount(0), size(0), capacity(0) {};
2046
+ _Tp* data;
2047
+ _Tp* datastart;
2048
+ int* refcount;
2049
+ size_t size;
2050
+ size_t capacity;
2051
+ };
2052
+
2053
+ Vector() {}
2054
+ Vector(size_t _size) { resize(_size); }
2055
+ Vector(size_t _size, const _Tp& val)
2056
+ {
2057
+ resize(_size);
2058
+ for(size_t i = 0; i < _size; i++)
2059
+ hdr.data[i] = val;
2060
+ }
2061
+ Vector(_Tp* _data, size_t _size, bool _copyData=false)
2062
+ { set(_data, _size, _copyData); }
2063
+
2064
+ template<int n> Vector(const Vec<_Tp, n>& vec)
2065
+ { set((_Tp*)&vec.val[0], n, true); }
2066
+
2067
+ Vector(const std::vector<_Tp>& vec, bool _copyData=false)
2068
+ { set((_Tp*)&vec[0], vec.size(), _copyData); }
2069
+
2070
+ Vector(const Vector& d) { *this = d; }
2071
+
2072
+ Vector(const Vector& d, const Range& r_)
2073
+ {
2074
+ Range r = r_ == Range::all() ? Range(0, d.size()) : r_;
2075
+ /*if( r == Range::all() )
2076
+ r = Range(0, d.size());*/
2077
+ if( r.size() > 0 && r.start >= 0 && r.end <= d.size() )
2078
+ {
2079
+ if( d.hdr.refcount )
2080
+ CV_XADD(d.hdr.refcount, 1);
2081
+ hdr.refcount = d.hdr.refcount;
2082
+ hdr.datastart = d.hdr.datastart;
2083
+ hdr.data = d.hdr.data + r.start;
2084
+ hdr.capacity = hdr.size = r.size();
2085
+ }
2086
+ }
2087
+
2088
+ Vector<_Tp>& operator = (const Vector& d)
2089
+ {
2090
+ if( this != &d )
2091
+ {
2092
+ if( d.hdr.refcount )
2093
+ CV_XADD(d.hdr.refcount, 1);
2094
+ release();
2095
+ hdr = d.hdr;
2096
+ }
2097
+ return *this;
2098
+ }
2099
+
2100
+ ~Vector() { release(); }
2101
+
2102
+ Vector<_Tp> clone() const
2103
+ { return hdr.data ? Vector<_Tp>(hdr.data, hdr.size, true) : Vector<_Tp>(); }
2104
+
2105
+ void copyTo(Vector<_Tp>& vec) const
2106
+ {
2107
+ size_t i, sz = size();
2108
+ vec.resize(sz);
2109
+ const _Tp* src = hdr.data;
2110
+ _Tp* dst = vec.hdr.data;
2111
+ for( i = 0; i < sz; i++ )
2112
+ dst[i] = src[i];
2113
+ }
2114
+
2115
+ void copyTo(std::vector<_Tp>& vec) const
2116
+ {
2117
+ size_t i, sz = size();
2118
+ vec.resize(sz);
2119
+ const _Tp* src = hdr.data;
2120
+ _Tp* dst = sz ? &vec[0] : 0;
2121
+ for( i = 0; i < sz; i++ )
2122
+ dst[i] = src[i];
2123
+ }
2124
+
2125
+ operator CvMat() const
2126
+ { return cvMat((int)size(), 1, type(), (void*)hdr.data); }
2127
+
2128
+ _Tp& operator [] (size_t i) { CV_DbgAssert( i < size() ); return hdr.data[i]; }
2129
+ const _Tp& operator [] (size_t i) const { CV_DbgAssert( i < size() ); return hdr.data[i]; }
2130
+ Vector operator() (const Range& r) const { return Vector(*this, r); }
2131
+ _Tp& back() { CV_DbgAssert(!empty()); return hdr.data[hdr.size-1]; }
2132
+ const _Tp& back() const { CV_DbgAssert(!empty()); return hdr.data[hdr.size-1]; }
2133
+ _Tp& front() { CV_DbgAssert(!empty()); return hdr.data[0]; }
2134
+ const _Tp& front() const { CV_DbgAssert(!empty()); return hdr.data[0]; }
2135
+
2136
+ _Tp* begin() { return hdr.data; }
2137
+ _Tp* end() { return hdr.data + hdr.size; }
2138
+ const _Tp* begin() const { return hdr.data; }
2139
+ const _Tp* end() const { return hdr.data + hdr.size; }
2140
+
2141
+ void addref() { if( hdr.refcount ) CV_XADD(hdr.refcount, 1); }
2142
+ void release()
2143
+ {
2144
+ if( hdr.refcount && CV_XADD(hdr.refcount, -1) == 1 )
2145
+ {
2146
+ delete[] hdr.datastart;
2147
+ delete hdr.refcount;
2148
+ }
2149
+ hdr = Hdr();
2150
+ }
2151
+
2152
+ void set(_Tp* _data, size_t _size, bool _copyData=false)
2153
+ {
2154
+ if( !_copyData )
2155
+ {
2156
+ release();
2157
+ hdr.data = hdr.datastart = _data;
2158
+ hdr.size = hdr.capacity = _size;
2159
+ hdr.refcount = 0;
2160
+ }
2161
+ else
2162
+ {
2163
+ reserve(_size);
2164
+ for( size_t i = 0; i < _size; i++ )
2165
+ hdr.data[i] = _data[i];
2166
+ hdr.size = _size;
2167
+ }
2168
+ }
2169
+
2170
+ void reserve(size_t newCapacity)
2171
+ {
2172
+ _Tp* newData;
2173
+ int* newRefcount;
2174
+ size_t i, oldSize = hdr.size;
2175
+ if( (!hdr.refcount || *hdr.refcount == 1) && hdr.capacity >= newCapacity )
2176
+ return;
2177
+ newCapacity = std::max(newCapacity, oldSize);
2178
+ newData = new _Tp[newCapacity];
2179
+ newRefcount = new int(1);
2180
+ for( i = 0; i < oldSize; i++ )
2181
+ newData[i] = hdr.data[i];
2182
+ release();
2183
+ hdr.data = hdr.datastart = newData;
2184
+ hdr.capacity = newCapacity;
2185
+ hdr.size = oldSize;
2186
+ hdr.refcount = newRefcount;
2187
+ }
2188
+
2189
+ void resize(size_t newSize)
2190
+ {
2191
+ size_t i;
2192
+ newSize = std::max(newSize, (size_t)0);
2193
+ if( (!hdr.refcount || *hdr.refcount == 1) && hdr.size == newSize )
2194
+ return;
2195
+ if( newSize > hdr.capacity )
2196
+ reserve(std::max(newSize, std::max((size_t)4, hdr.capacity*2)));
2197
+ for( i = hdr.size; i < newSize; i++ )
2198
+ hdr.data[i] = _Tp();
2199
+ hdr.size = newSize;
2200
+ }
2201
+
2202
+ Vector<_Tp>& push_back(const _Tp& elem)
2203
+ {
2204
+ if( hdr.size == hdr.capacity )
2205
+ reserve( std::max((size_t)4, hdr.capacity*2) );
2206
+ hdr.data[hdr.size++] = elem;
2207
+ return *this;
2208
+ }
2209
+
2210
+ Vector<_Tp>& pop_back()
2211
+ {
2212
+ if( hdr.size > 0 )
2213
+ --hdr.size;
2214
+ return *this;
2215
+ }
2216
+
2217
+ size_t size() const { return hdr.size; }
2218
+ size_t capacity() const { return hdr.capacity; }
2219
+ bool empty() const { return hdr.size == 0; }
2220
+ void clear() { resize(0); }
2221
+ int type() const { return DataType<_Tp>::type; }
2222
+
2223
+ protected:
2224
+ Hdr hdr;
2225
+ };
2226
+
2227
+
2228
+ template<typename _Tp> inline typename DataType<_Tp>::work_type
2229
+ dot(const Vector<_Tp>& v1, const Vector<_Tp>& v2)
2230
+ {
2231
+ typedef typename DataType<_Tp>::work_type _Tw;
2232
+ size_t i, n = v1.size();
2233
+ assert(v1.size() == v2.size());
2234
+
2235
+ _Tw s = 0;
2236
+ const _Tp *ptr1 = &v1[0], *ptr2 = &v2[0];
2237
+ for( i = 0; i <= n - 4; i += 4 )
2238
+ s += (_Tw)ptr1[i]*ptr2[i] + (_Tw)ptr1[i+1]*ptr2[i+1] +
2239
+ (_Tw)ptr1[i+2]*ptr2[i+2] + (_Tw)ptr1[i+3]*ptr2[i+3];
2240
+ for( ; i < n; i++ )
2241
+ s += (_Tw)ptr1[i]*ptr2[i];
2242
+ return s;
2243
+ }
2244
+
2245
+ // Multiply-with-Carry RNG
2246
+ inline RNG::RNG() { state = 0xffffffff; }
2247
+ inline RNG::RNG(uint64 _state) { state = _state ? _state : 0xffffffff; }
2248
+ inline unsigned RNG::next()
2249
+ {
2250
+ state = (uint64)(unsigned)state*CV_RNG_COEFF + (unsigned)(state >> 32);
2251
+ return (unsigned)state;
2252
+ }
2253
+
2254
+ inline RNG::operator uchar() { return (uchar)next(); }
2255
+ inline RNG::operator schar() { return (schar)next(); }
2256
+ inline RNG::operator ushort() { return (ushort)next(); }
2257
+ inline RNG::operator short() { return (short)next(); }
2258
+ inline RNG::operator unsigned() { return next(); }
2259
+ inline unsigned RNG::operator ()(unsigned N) {return (unsigned)uniform(0,N);}
2260
+ inline unsigned RNG::operator ()() {return next();}
2261
+ inline RNG::operator int() { return (int)next(); }
2262
+ // * (2^32-1)^-1
2263
+ inline RNG::operator float() { return next()*2.3283064365386962890625e-10f; }
2264
+ inline RNG::operator double()
2265
+ {
2266
+ unsigned t = next();
2267
+ return (((uint64)t << 32) | next())*5.4210108624275221700372640043497e-20;
2268
+ }
2269
+ inline int RNG::uniform(int a, int b) { return a == b ? a : next()%(b - a) + a; }
2270
+ inline float RNG::uniform(float a, float b) { return ((float)*this)*(b - a) + a; }
2271
+ inline double RNG::uniform(double a, double b) { return ((double)*this)*(b - a) + a; }
2272
+
2273
+ inline TermCriteria::TermCriteria() : type(0), maxCount(0), epsilon(0) {}
2274
+ inline TermCriteria::TermCriteria(int _type, int _maxCount, double _epsilon)
2275
+ : type(_type), maxCount(_maxCount), epsilon(_epsilon) {}
2276
+ inline TermCriteria::TermCriteria(const CvTermCriteria& criteria)
2277
+ : type(criteria.type), maxCount(criteria.max_iter), epsilon(criteria.epsilon) {}
2278
+ inline TermCriteria::operator CvTermCriteria() const
2279
+ { return cvTermCriteria(type, maxCount, epsilon); }
2280
+
2281
+ inline uchar* LineIterator::operator *() { return ptr; }
2282
+ inline LineIterator& LineIterator::operator ++()
2283
+ {
2284
+ int mask = err < 0 ? -1 : 0;
2285
+ err += minusDelta + (plusDelta & mask);
2286
+ ptr += minusStep + (plusStep & mask);
2287
+ return *this;
2288
+ }
2289
+ inline LineIterator LineIterator::operator ++(int)
2290
+ {
2291
+ LineIterator it = *this;
2292
+ ++(*this);
2293
+ return it;
2294
+ }
2295
+ inline Point LineIterator::pos() const
2296
+ {
2297
+ Point p;
2298
+ p.y = (int)((ptr - ptr0)/step);
2299
+ p.x = (int)(((ptr - ptr0) - p.y*step)/elemSize);
2300
+ return p;
2301
+ }
2302
+
2303
+ /////////////////////////////// AutoBuffer ////////////////////////////////////////
2304
+
2305
+ template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::AutoBuffer()
2306
+ {
2307
+ ptr = buf;
2308
+ size = fixed_size;
2309
+ }
2310
+
2311
+ template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::AutoBuffer(size_t _size)
2312
+ {
2313
+ ptr = buf;
2314
+ size = fixed_size;
2315
+ allocate(_size);
2316
+ }
2317
+
2318
+ template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::~AutoBuffer()
2319
+ { deallocate(); }
2320
+
2321
+ template<typename _Tp, size_t fixed_size> inline void AutoBuffer<_Tp, fixed_size>::allocate(size_t _size)
2322
+ {
2323
+ if(_size <= size)
2324
+ return;
2325
+ deallocate();
2326
+ if(_size > fixed_size)
2327
+ {
2328
+ ptr = cv::allocate<_Tp>(_size);
2329
+ size = _size;
2330
+ }
2331
+ }
2332
+
2333
+ template<typename _Tp, size_t fixed_size> inline void AutoBuffer<_Tp, fixed_size>::deallocate()
2334
+ {
2335
+ if( ptr != buf )
2336
+ {
2337
+ cv::deallocate<_Tp>(ptr, size);
2338
+ ptr = buf;
2339
+ size = fixed_size;
2340
+ }
2341
+ }
2342
+
2343
+ template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::operator _Tp* ()
2344
+ { return ptr; }
2345
+
2346
+ template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::operator const _Tp* () const
2347
+ { return ptr; }
2348
+
2349
+
2350
+ /////////////////////////////////// Ptr ////////////////////////////////////////
2351
+
2352
+ template<typename _Tp> inline Ptr<_Tp>::Ptr() : obj(0), refcount(0) {}
2353
+ template<typename _Tp> inline Ptr<_Tp>::Ptr(_Tp* _obj) : obj(_obj)
2354
+ {
2355
+ if(obj)
2356
+ {
2357
+ refcount = (int*)fastMalloc(sizeof(*refcount));
2358
+ *refcount = 1;
2359
+ }
2360
+ else
2361
+ refcount = 0;
2362
+ }
2363
+
2364
+ template<typename _Tp> inline void Ptr<_Tp>::addref()
2365
+ { if( refcount ) CV_XADD(refcount, 1); }
2366
+
2367
+ template<typename _Tp> inline void Ptr<_Tp>::release()
2368
+ {
2369
+ if( refcount && CV_XADD(refcount, -1) == 1 )
2370
+ {
2371
+ delete_obj();
2372
+ fastFree(refcount);
2373
+ }
2374
+ refcount = 0;
2375
+ obj = 0;
2376
+ }
2377
+
2378
+ template<typename _Tp> inline void Ptr<_Tp>::delete_obj()
2379
+ {
2380
+ if( obj ) delete obj;
2381
+ }
2382
+
2383
+ template<typename _Tp> inline Ptr<_Tp>::~Ptr() { release(); }
2384
+
2385
+ template<typename _Tp> inline Ptr<_Tp>::Ptr(const Ptr<_Tp>& ptr)
2386
+ {
2387
+ obj = ptr.obj;
2388
+ refcount = ptr.refcount;
2389
+ addref();
2390
+ }
2391
+
2392
+ template<typename _Tp> inline Ptr<_Tp>& Ptr<_Tp>::operator = (const Ptr<_Tp>& ptr)
2393
+ {
2394
+ int* _refcount = ptr.refcount;
2395
+ if( _refcount )
2396
+ CV_XADD(_refcount, 1);
2397
+ release();
2398
+ obj = ptr.obj;
2399
+ refcount = _refcount;
2400
+ return *this;
2401
+ }
2402
+
2403
+ template<typename _Tp> inline _Tp* Ptr<_Tp>::operator -> () { return obj; }
2404
+ template<typename _Tp> inline const _Tp* Ptr<_Tp>::operator -> () const { return obj; }
2405
+
2406
+ template<typename _Tp> inline Ptr<_Tp>::operator _Tp* () { return obj; }
2407
+ template<typename _Tp> inline Ptr<_Tp>::operator const _Tp*() const { return obj; }
2408
+
2409
+ template<typename _Tp> inline bool Ptr<_Tp>::empty() const { return obj == 0; }
2410
+
2411
+ //// specializied implementations of Ptr::delete_obj() for classic OpenCV types
2412
+
2413
+ template<> CV_EXPORTS void Ptr<CvMat>::delete_obj();
2414
+ template<> CV_EXPORTS void Ptr<IplImage>::delete_obj();
2415
+ template<> CV_EXPORTS void Ptr<CvMatND>::delete_obj();
2416
+ template<> CV_EXPORTS void Ptr<CvSparseMat>::delete_obj();
2417
+ template<> CV_EXPORTS void Ptr<CvMemStorage>::delete_obj();
2418
+ template<> CV_EXPORTS void Ptr<CvFileStorage>::delete_obj();
2419
+
2420
+ //////////////////////////////////////// XML & YAML I/O ////////////////////////////////////
2421
+
2422
+ CV_EXPORTS_W void write( FileStorage& fs, const string& name, int value );
2423
+ CV_EXPORTS_W void write( FileStorage& fs, const string& name, float value );
2424
+ CV_EXPORTS_W void write( FileStorage& fs, const string& name, double value );
2425
+ CV_EXPORTS_W void write( FileStorage& fs, const string& name, const string& value );
2426
+
2427
+ template<typename _Tp> inline void write(FileStorage& fs, const _Tp& value)
2428
+ { write(fs, string(), value); }
2429
+
2430
+ CV_EXPORTS void writeScalar( FileStorage& fs, int value );
2431
+ CV_EXPORTS void writeScalar( FileStorage& fs, float value );
2432
+ CV_EXPORTS void writeScalar( FileStorage& fs, double value );
2433
+ CV_EXPORTS void writeScalar( FileStorage& fs, const string& value );
2434
+
2435
+ template<> inline void write( FileStorage& fs, const int& value )
2436
+ {
2437
+ writeScalar(fs, value);
2438
+ }
2439
+
2440
+ template<> inline void write( FileStorage& fs, const float& value )
2441
+ {
2442
+ writeScalar(fs, value);
2443
+ }
2444
+
2445
+ template<> inline void write( FileStorage& fs, const double& value )
2446
+ {
2447
+ writeScalar(fs, value);
2448
+ }
2449
+
2450
+ template<> inline void write( FileStorage& fs, const string& value )
2451
+ {
2452
+ writeScalar(fs, value);
2453
+ }
2454
+
2455
+ template<typename _Tp> inline void write(FileStorage& fs, const Point_<_Tp>& pt )
2456
+ {
2457
+ write(fs, pt.x);
2458
+ write(fs, pt.y);
2459
+ }
2460
+
2461
+ template<typename _Tp> inline void write(FileStorage& fs, const Point3_<_Tp>& pt )
2462
+ {
2463
+ write(fs, pt.x);
2464
+ write(fs, pt.y);
2465
+ write(fs, pt.z);
2466
+ }
2467
+
2468
+ template<typename _Tp> inline void write(FileStorage& fs, const Size_<_Tp>& sz )
2469
+ {
2470
+ write(fs, sz.width);
2471
+ write(fs, sz.height);
2472
+ }
2473
+
2474
+ template<typename _Tp> inline void write(FileStorage& fs, const Complex<_Tp>& c )
2475
+ {
2476
+ write(fs, c.re);
2477
+ write(fs, c.im);
2478
+ }
2479
+
2480
+ template<typename _Tp> inline void write(FileStorage& fs, const Rect_<_Tp>& r )
2481
+ {
2482
+ write(fs, r.x);
2483
+ write(fs, r.y);
2484
+ write(fs, r.width);
2485
+ write(fs, r.height);
2486
+ }
2487
+
2488
+ template<typename _Tp, int cn> inline void write(FileStorage& fs, const Vec<_Tp, cn>& v )
2489
+ {
2490
+ for(int i = 0; i < cn; i++)
2491
+ write(fs, v.val[i]);
2492
+ }
2493
+
2494
+ template<typename _Tp> inline void write(FileStorage& fs, const Scalar_<_Tp>& s )
2495
+ {
2496
+ write(fs, s.val[0]);
2497
+ write(fs, s.val[1]);
2498
+ write(fs, s.val[2]);
2499
+ write(fs, s.val[3]);
2500
+ }
2501
+
2502
+ inline void write(FileStorage& fs, const Range& r )
2503
+ {
2504
+ write(fs, r.start);
2505
+ write(fs, r.end);
2506
+ }
2507
+
2508
+ class CV_EXPORTS WriteStructContext
2509
+ {
2510
+ public:
2511
+ WriteStructContext(FileStorage& _fs, const string& name,
2512
+ int flags, const string& typeName=string());
2513
+ ~WriteStructContext();
2514
+ FileStorage* fs;
2515
+ };
2516
+
2517
+ template<typename _Tp> inline void write(FileStorage& fs, const string& name, const Point_<_Tp>& pt )
2518
+ {
2519
+ WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
2520
+ write(fs, pt.x);
2521
+ write(fs, pt.y);
2522
+ }
2523
+
2524
+ template<typename _Tp> inline void write(FileStorage& fs, const string& name, const Point3_<_Tp>& pt )
2525
+ {
2526
+ WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
2527
+ write(fs, pt.x);
2528
+ write(fs, pt.y);
2529
+ write(fs, pt.z);
2530
+ }
2531
+
2532
+ template<typename _Tp> inline void write(FileStorage& fs, const string& name, const Size_<_Tp>& sz )
2533
+ {
2534
+ WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
2535
+ write(fs, sz.width);
2536
+ write(fs, sz.height);
2537
+ }
2538
+
2539
+ template<typename _Tp> inline void write(FileStorage& fs, const string& name, const Complex<_Tp>& c )
2540
+ {
2541
+ WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
2542
+ write(fs, c.re);
2543
+ write(fs, c.im);
2544
+ }
2545
+
2546
+ template<typename _Tp> inline void write(FileStorage& fs, const string& name, const Rect_<_Tp>& r )
2547
+ {
2548
+ WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
2549
+ write(fs, r.x);
2550
+ write(fs, r.y);
2551
+ write(fs, r.width);
2552
+ write(fs, r.height);
2553
+ }
2554
+
2555
+ template<typename _Tp, int cn> inline void write(FileStorage& fs, const string& name, const Vec<_Tp, cn>& v )
2556
+ {
2557
+ WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
2558
+ for(int i = 0; i < cn; i++)
2559
+ write(fs, v.val[i]);
2560
+ }
2561
+
2562
+ template<typename _Tp> inline void write(FileStorage& fs, const string& name, const Scalar_<_Tp>& s )
2563
+ {
2564
+ WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
2565
+ write(fs, s.val[0]);
2566
+ write(fs, s.val[1]);
2567
+ write(fs, s.val[2]);
2568
+ write(fs, s.val[3]);
2569
+ }
2570
+
2571
+ inline void write(FileStorage& fs, const string& name, const Range& r )
2572
+ {
2573
+ WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
2574
+ write(fs, r.start);
2575
+ write(fs, r.end);
2576
+ }
2577
+
2578
+ template<typename _Tp, int numflag> class CV_EXPORTS VecWriterProxy
2579
+ {
2580
+ public:
2581
+ VecWriterProxy( FileStorage* _fs ) : fs(_fs) {}
2582
+ void operator()(const vector<_Tp>& vec) const
2583
+ {
2584
+ size_t i, count = vec.size();
2585
+ for( i = 0; i < count; i++ )
2586
+ write( *fs, vec[i] );
2587
+ }
2588
+ FileStorage* fs;
2589
+ };
2590
+
2591
+ template<typename _Tp> class CV_EXPORTS VecWriterProxy<_Tp,1>
2592
+ {
2593
+ public:
2594
+ VecWriterProxy( FileStorage* _fs ) : fs(_fs) {}
2595
+ void operator()(const vector<_Tp>& vec) const
2596
+ {
2597
+ int _fmt = DataType<_Tp>::fmt;
2598
+ char fmt[] = { (char)((_fmt>>8)+'1'), (char)_fmt, '\0' };
2599
+ fs->writeRaw( string(fmt), (uchar*)&vec[0], vec.size()*sizeof(_Tp) );
2600
+ }
2601
+ FileStorage* fs;
2602
+ };
2603
+
2604
+
2605
+ template<typename _Tp> static inline void write( FileStorage& fs, const vector<_Tp>& vec )
2606
+ {
2607
+ VecWriterProxy<_Tp, DataType<_Tp>::fmt != 0> w(&fs);
2608
+ w(vec);
2609
+ }
2610
+
2611
+ template<typename _Tp> static inline FileStorage&
2612
+ operator << ( FileStorage& fs, const vector<_Tp>& vec )
2613
+ {
2614
+ VecWriterProxy<_Tp, DataType<_Tp>::generic_type == 0> w(&fs);
2615
+ w(vec);
2616
+ return fs;
2617
+ }
2618
+
2619
+ CV_EXPORTS_W void write( FileStorage& fs, const string& name, const Mat& value );
2620
+ CV_EXPORTS void write( FileStorage& fs, const string& name, const SparseMat& value );
2621
+
2622
+ template<typename _Tp> static inline FileStorage& operator << (FileStorage& fs, const _Tp& value)
2623
+ {
2624
+ if( !fs.isOpened() )
2625
+ return fs;
2626
+ if( fs.state == FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP )
2627
+ CV_Error( CV_StsError, "No element name has been given" );
2628
+ write( fs, fs.elname, value );
2629
+ if( fs.state & FileStorage::INSIDE_MAP )
2630
+ fs.state = FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP;
2631
+ return fs;
2632
+ }
2633
+
2634
+ CV_EXPORTS FileStorage& operator << (FileStorage& fs, const string& str);
2635
+
2636
+ static inline FileStorage& operator << (FileStorage& fs, const char* str)
2637
+ { return (fs << string(str)); }
2638
+
2639
+ inline FileNode::FileNode() : fs(0), node(0) {}
2640
+ inline FileNode::FileNode(const CvFileStorage* _fs, const CvFileNode* _node)
2641
+ : fs(_fs), node(_node) {}
2642
+
2643
+ inline FileNode::FileNode(const FileNode& _node) : fs(_node.fs), node(_node.node) {}
2644
+
2645
+ inline int FileNode::type() const { return !node ? NONE : (node->tag & TYPE_MASK); }
2646
+ inline bool FileNode::empty() const { return node == 0; }
2647
+ inline bool FileNode::isNone() const { return type() == NONE; }
2648
+ inline bool FileNode::isSeq() const { return type() == SEQ; }
2649
+ inline bool FileNode::isMap() const { return type() == MAP; }
2650
+ inline bool FileNode::isInt() const { return type() == INT; }
2651
+ inline bool FileNode::isReal() const { return type() == REAL; }
2652
+ inline bool FileNode::isString() const { return type() == STR; }
2653
+ inline bool FileNode::isNamed() const { return !node ? false : (node->tag & NAMED) != 0; }
2654
+ inline size_t FileNode::size() const
2655
+ {
2656
+ int t = type();
2657
+ return t == MAP ? ((CvSet*)node->data.map)->active_count :
2658
+ t == SEQ ? node->data.seq->total : node != 0;
2659
+ }
2660
+
2661
+ inline CvFileNode* FileNode::operator *() { return (CvFileNode*)node; }
2662
+ inline const CvFileNode* FileNode::operator* () const { return node; }
2663
+
2664
+ static inline void read(const FileNode& node, int& value, int default_value)
2665
+ {
2666
+ value = !node.node ? default_value :
2667
+ CV_NODE_IS_INT(node.node->tag) ? node.node->data.i :
2668
+ CV_NODE_IS_REAL(node.node->tag) ? cvRound(node.node->data.f) : 0x7fffffff;
2669
+ }
2670
+
2671
+ static inline void read(const FileNode& node, bool& value, bool default_value)
2672
+ {
2673
+ int temp; read(node, temp, (int)default_value);
2674
+ value = temp != 0;
2675
+ }
2676
+
2677
+ static inline void read(const FileNode& node, uchar& value, uchar default_value)
2678
+ {
2679
+ int temp; read(node, temp, (int)default_value);
2680
+ value = saturate_cast<uchar>(temp);
2681
+ }
2682
+
2683
+ static inline void read(const FileNode& node, schar& value, schar default_value)
2684
+ {
2685
+ int temp; read(node, temp, (int)default_value);
2686
+ value = saturate_cast<schar>(temp);
2687
+ }
2688
+
2689
+ static inline void read(const FileNode& node, ushort& value, ushort default_value)
2690
+ {
2691
+ int temp; read(node, temp, (int)default_value);
2692
+ value = saturate_cast<ushort>(temp);
2693
+ }
2694
+
2695
+ static inline void read(const FileNode& node, short& value, short default_value)
2696
+ {
2697
+ int temp; read(node, temp, (int)default_value);
2698
+ value = saturate_cast<short>(temp);
2699
+ }
2700
+
2701
+ static inline void read(const FileNode& node, float& value, float default_value)
2702
+ {
2703
+ value = !node.node ? default_value :
2704
+ CV_NODE_IS_INT(node.node->tag) ? (float)node.node->data.i :
2705
+ CV_NODE_IS_REAL(node.node->tag) ? (float)node.node->data.f : 1e30f;
2706
+ }
2707
+
2708
+ static inline void read(const FileNode& node, double& value, double default_value)
2709
+ {
2710
+ value = !node.node ? default_value :
2711
+ CV_NODE_IS_INT(node.node->tag) ? (double)node.node->data.i :
2712
+ CV_NODE_IS_REAL(node.node->tag) ? node.node->data.f : 1e300;
2713
+ }
2714
+
2715
+ static inline void read(const FileNode& node, string& value, const string& default_value)
2716
+ {
2717
+ value = !node.node ? default_value : CV_NODE_IS_STRING(node.node->tag) ? string(node.node->data.str.ptr) : string("");
2718
+ }
2719
+
2720
+ CV_EXPORTS_W void read(const FileNode& node, Mat& mat, const Mat& default_mat=Mat() );
2721
+ CV_EXPORTS void read(const FileNode& node, SparseMat& mat, const SparseMat& default_mat=SparseMat() );
2722
+
2723
+ inline FileNode::operator int() const
2724
+ {
2725
+ int value;
2726
+ read(*this, value, 0);
2727
+ return value;
2728
+ }
2729
+ inline FileNode::operator float() const
2730
+ {
2731
+ float value;
2732
+ read(*this, value, 0.f);
2733
+ return value;
2734
+ }
2735
+ inline FileNode::operator double() const
2736
+ {
2737
+ double value;
2738
+ read(*this, value, 0.);
2739
+ return value;
2740
+ }
2741
+ inline FileNode::operator string() const
2742
+ {
2743
+ string value;
2744
+ read(*this, value, value);
2745
+ return value;
2746
+ }
2747
+
2748
+ inline void FileNode::readRaw( const string& fmt, uchar* vec, size_t len ) const
2749
+ {
2750
+ begin().readRaw( fmt, vec, len );
2751
+ }
2752
+
2753
+ template<typename _Tp, int numflag> class CV_EXPORTS VecReaderProxy
2754
+ {
2755
+ public:
2756
+ VecReaderProxy( FileNodeIterator* _it ) : it(_it) {}
2757
+ void operator()(vector<_Tp>& vec, size_t count) const
2758
+ {
2759
+ count = std::min(count, it->remaining);
2760
+ vec.resize(count);
2761
+ for( size_t i = 0; i < count; i++, ++(*it) )
2762
+ read(**it, vec[i], _Tp());
2763
+ }
2764
+ FileNodeIterator* it;
2765
+ };
2766
+
2767
+ template<typename _Tp> class CV_EXPORTS VecReaderProxy<_Tp,1>
2768
+ {
2769
+ public:
2770
+ VecReaderProxy( FileNodeIterator* _it ) : it(_it) {}
2771
+ void operator()(vector<_Tp>& vec, size_t count) const
2772
+ {
2773
+ size_t remaining = it->remaining, cn = DataType<_Tp>::channels;
2774
+ int _fmt = DataType<_Tp>::fmt;
2775
+ char fmt[] = { (char)((_fmt>>8)+'1'), (char)_fmt, '\0' };
2776
+ size_t remaining1 = remaining/cn;
2777
+ count = count < remaining1 ? count : remaining1;
2778
+ vec.resize(count);
2779
+ it->readRaw( string(fmt), (uchar*)&vec[0], count*sizeof(_Tp) );
2780
+ }
2781
+ FileNodeIterator* it;
2782
+ };
2783
+
2784
+ template<typename _Tp> static inline void
2785
+ read( FileNodeIterator& it, vector<_Tp>& vec, size_t maxCount=(size_t)INT_MAX )
2786
+ {
2787
+ VecReaderProxy<_Tp, DataType<_Tp>::fmt != 0> r(&it);
2788
+ r(vec, maxCount);
2789
+ }
2790
+
2791
+ template<typename _Tp> static inline void
2792
+ read( FileNode& node, vector<_Tp>& vec, const vector<_Tp>& default_value=vector<_Tp>() )
2793
+ {
2794
+ read( node.begin(), vec );
2795
+ }
2796
+
2797
+ inline FileNodeIterator FileNode::begin() const
2798
+ {
2799
+ return FileNodeIterator(fs, node);
2800
+ }
2801
+
2802
+ inline FileNodeIterator FileNode::end() const
2803
+ {
2804
+ return FileNodeIterator(fs, node, size());
2805
+ }
2806
+
2807
+ inline FileNode FileNodeIterator::operator *() const
2808
+ { return FileNode(fs, (const CvFileNode*)reader.ptr); }
2809
+
2810
+ inline FileNode FileNodeIterator::operator ->() const
2811
+ { return FileNode(fs, (const CvFileNode*)reader.ptr); }
2812
+
2813
+ template<typename _Tp> static inline FileNodeIterator& operator >> (FileNodeIterator& it, _Tp& value)
2814
+ { read( *it, value, _Tp()); return ++it; }
2815
+
2816
+ template<typename _Tp> static inline
2817
+ FileNodeIterator& operator >> (FileNodeIterator& it, vector<_Tp>& vec)
2818
+ {
2819
+ VecReaderProxy<_Tp, DataType<_Tp>::fmt != 0> r(&it);
2820
+ r(vec, (size_t)INT_MAX);
2821
+ return it;
2822
+ }
2823
+
2824
+ template<typename _Tp> static inline void operator >> (const FileNode& n, _Tp& value)
2825
+ { read( n, value, _Tp()); }
2826
+
2827
+ template<typename _Tp> static inline void operator >> (const FileNode& n, vector<_Tp>& vec)
2828
+ { FileNodeIterator it = n.begin(); it >> vec; }
2829
+
2830
+ static inline bool operator == (const FileNodeIterator& it1, const FileNodeIterator& it2)
2831
+ {
2832
+ return it1.fs == it2.fs && it1.container == it2.container &&
2833
+ it1.reader.ptr == it2.reader.ptr && it1.remaining == it2.remaining;
2834
+ }
2835
+
2836
+ static inline bool operator != (const FileNodeIterator& it1, const FileNodeIterator& it2)
2837
+ {
2838
+ return !(it1 == it2);
2839
+ }
2840
+
2841
+ static inline ptrdiff_t operator - (const FileNodeIterator& it1, const FileNodeIterator& it2)
2842
+ {
2843
+ return it2.remaining - it1.remaining;
2844
+ }
2845
+
2846
+ static inline bool operator < (const FileNodeIterator& it1, const FileNodeIterator& it2)
2847
+ {
2848
+ return it1.remaining > it2.remaining;
2849
+ }
2850
+
2851
+ inline FileNode FileStorage::getFirstTopLevelNode() const
2852
+ {
2853
+ FileNode r = root();
2854
+ FileNodeIterator it = r.begin();
2855
+ return it != r.end() ? *it : FileNode();
2856
+ }
2857
+
2858
+ //////////////////////////////////////// Various algorithms ////////////////////////////////////
2859
+
2860
+ template<typename _Tp> static inline _Tp gcd(_Tp a, _Tp b)
2861
+ {
2862
+ if( a < b )
2863
+ std::swap(a, b);
2864
+ while( b > 0 )
2865
+ {
2866
+ _Tp r = a % b;
2867
+ a = b;
2868
+ b = r;
2869
+ }
2870
+ return a;
2871
+ }
2872
+
2873
+ /****************************************************************************************\
2874
+
2875
+ Generic implementation of QuickSort algorithm
2876
+ Use it as: vector<_Tp> a; ... sort(a,<less_than_predictor>);
2877
+
2878
+ The current implementation was derived from *BSD system qsort():
2879
+
2880
+ * Copyright (c) 1992, 1993
2881
+ * The Regents of the University of California. All rights reserved.
2882
+ *
2883
+ * Redistribution and use in source and binary forms, with or without
2884
+ * modification, are permitted provided that the following conditions
2885
+ * are met:
2886
+ * 1. Redistributions of source code must retain the above copyright
2887
+ * notice, this list of conditions and the following disclaimer.
2888
+ * 2. Redistributions in binary form must reproduce the above copyright
2889
+ * notice, this list of conditions and the following disclaimer in the
2890
+ * documentation and/or other materials provided with the distribution.
2891
+ * 3. All advertising materials mentioning features or use of this software
2892
+ * must display the following acknowledgement:
2893
+ * This product includes software developed by the University of
2894
+ * California, Berkeley and its contributors.
2895
+ * 4. Neither the name of the University nor the names of its contributors
2896
+ * may be used to endorse or promote products derived from this software
2897
+ * without specific prior written permission.
2898
+ *
2899
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2900
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2901
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2902
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2903
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2904
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2905
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2906
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2907
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2908
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2909
+ * SUCH DAMAGE.
2910
+
2911
+ \****************************************************************************************/
2912
+
2913
+ template<typename _Tp, class _LT> void sort( vector<_Tp>& vec, _LT LT=_LT() )
2914
+ {
2915
+ int isort_thresh = 7;
2916
+ int sp = 0;
2917
+
2918
+ struct
2919
+ {
2920
+ _Tp *lb;
2921
+ _Tp *ub;
2922
+ } stack[48];
2923
+
2924
+ size_t total = vec.size();
2925
+
2926
+ if( total <= 1 )
2927
+ return;
2928
+
2929
+ _Tp* arr = &vec[0];
2930
+ stack[0].lb = arr;
2931
+ stack[0].ub = arr + (total - 1);
2932
+
2933
+ while( sp >= 0 )
2934
+ {
2935
+ _Tp* left = stack[sp].lb;
2936
+ _Tp* right = stack[sp--].ub;
2937
+
2938
+ for(;;)
2939
+ {
2940
+ int i, n = (int)(right - left) + 1, m;
2941
+ _Tp* ptr;
2942
+ _Tp* ptr2;
2943
+
2944
+ if( n <= isort_thresh )
2945
+ {
2946
+ insert_sort:
2947
+ for( ptr = left + 1; ptr <= right; ptr++ )
2948
+ {
2949
+ for( ptr2 = ptr; ptr2 > left && LT(ptr2[0],ptr2[-1]); ptr2--)
2950
+ std::swap( ptr2[0], ptr2[-1] );
2951
+ }
2952
+ break;
2953
+ }
2954
+ else
2955
+ {
2956
+ _Tp* left0;
2957
+ _Tp* left1;
2958
+ _Tp* right0;
2959
+ _Tp* right1;
2960
+ _Tp* pivot;
2961
+ _Tp* a;
2962
+ _Tp* b;
2963
+ _Tp* c;
2964
+ int swap_cnt = 0;
2965
+
2966
+ left0 = left;
2967
+ right0 = right;
2968
+ pivot = left + (n/2);
2969
+
2970
+ if( n > 40 )
2971
+ {
2972
+ int d = n / 8;
2973
+ a = left, b = left + d, c = left + 2*d;
2974
+ left = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))
2975
+ : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));
2976
+
2977
+ a = pivot - d, b = pivot, c = pivot + d;
2978
+ pivot = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))
2979
+ : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));
2980
+
2981
+ a = right - 2*d, b = right - d, c = right;
2982
+ right = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))
2983
+ : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));
2984
+ }
2985
+
2986
+ a = left, b = pivot, c = right;
2987
+ pivot = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))
2988
+ : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));
2989
+ if( pivot != left0 )
2990
+ {
2991
+ std::swap( *pivot, *left0 );
2992
+ pivot = left0;
2993
+ }
2994
+ left = left1 = left0 + 1;
2995
+ right = right1 = right0;
2996
+
2997
+ for(;;)
2998
+ {
2999
+ while( left <= right && !LT(*pivot, *left) )
3000
+ {
3001
+ if( !LT(*left, *pivot) )
3002
+ {
3003
+ if( left > left1 )
3004
+ std::swap( *left1, *left );
3005
+ swap_cnt = 1;
3006
+ left1++;
3007
+ }
3008
+ left++;
3009
+ }
3010
+
3011
+ while( left <= right && !LT(*right, *pivot) )
3012
+ {
3013
+ if( !LT(*pivot, *right) )
3014
+ {
3015
+ if( right < right1 )
3016
+ std::swap( *right1, *right );
3017
+ swap_cnt = 1;
3018
+ right1--;
3019
+ }
3020
+ right--;
3021
+ }
3022
+
3023
+ if( left > right )
3024
+ break;
3025
+ std::swap( *left, *right );
3026
+ swap_cnt = 1;
3027
+ left++;
3028
+ right--;
3029
+ }
3030
+
3031
+ if( swap_cnt == 0 )
3032
+ {
3033
+ left = left0, right = right0;
3034
+ goto insert_sort;
3035
+ }
3036
+
3037
+ n = std::min( (int)(left1 - left0), (int)(left - left1) );
3038
+ for( i = 0; i < n; i++ )
3039
+ std::swap( left0[i], left[i-n] );
3040
+
3041
+ n = std::min( (int)(right0 - right1), (int)(right1 - right) );
3042
+ for( i = 0; i < n; i++ )
3043
+ std::swap( left[i], right0[i-n+1] );
3044
+ n = (int)(left - left1);
3045
+ m = (int)(right1 - right);
3046
+ if( n > 1 )
3047
+ {
3048
+ if( m > 1 )
3049
+ {
3050
+ if( n > m )
3051
+ {
3052
+ stack[++sp].lb = left0;
3053
+ stack[sp].ub = left0 + n - 1;
3054
+ left = right0 - m + 1, right = right0;
3055
+ }
3056
+ else
3057
+ {
3058
+ stack[++sp].lb = right0 - m + 1;
3059
+ stack[sp].ub = right0;
3060
+ left = left0, right = left0 + n - 1;
3061
+ }
3062
+ }
3063
+ else
3064
+ left = left0, right = left0 + n - 1;
3065
+ }
3066
+ else if( m > 1 )
3067
+ left = right0 - m + 1, right = right0;
3068
+ else
3069
+ break;
3070
+ }
3071
+ }
3072
+ }
3073
+ }
3074
+
3075
+ template<typename _Tp> class CV_EXPORTS LessThan
3076
+ {
3077
+ public:
3078
+ bool operator()(const _Tp& a, const _Tp& b) const { return a < b; }
3079
+ };
3080
+
3081
+ template<typename _Tp> class CV_EXPORTS GreaterEq
3082
+ {
3083
+ public:
3084
+ bool operator()(const _Tp& a, const _Tp& b) const { return a >= b; }
3085
+ };
3086
+
3087
+ template<typename _Tp> class CV_EXPORTS LessThanIdx
3088
+ {
3089
+ public:
3090
+ LessThanIdx( const _Tp* _arr ) : arr(_arr) {}
3091
+ bool operator()(int a, int b) const { return arr[a] < arr[b]; }
3092
+ const _Tp* arr;
3093
+ };
3094
+
3095
+ template<typename _Tp> class CV_EXPORTS GreaterEqIdx
3096
+ {
3097
+ public:
3098
+ GreaterEqIdx( const _Tp* _arr ) : arr(_arr) {}
3099
+ bool operator()(int a, int b) const { return arr[a] >= arr[b]; }
3100
+ const _Tp* arr;
3101
+ };
3102
+
3103
+
3104
+ // This function splits the input sequence or set into one or more equivalence classes and
3105
+ // returns the vector of labels - 0-based class indexes for each element.
3106
+ // predicate(a,b) returns true if the two sequence elements certainly belong to the same class.
3107
+ //
3108
+ // The algorithm is described in "Introduction to Algorithms"
3109
+ // by Cormen, Leiserson and Rivest, the chapter "Data structures for disjoint sets"
3110
+ template<typename _Tp, class _EqPredicate> int
3111
+ partition( const vector<_Tp>& _vec, vector<int>& labels,
3112
+ _EqPredicate predicate=_EqPredicate())
3113
+ {
3114
+ int i, j, N = (int)_vec.size();
3115
+ const _Tp* vec = &_vec[0];
3116
+
3117
+ const int PARENT=0;
3118
+ const int RANK=1;
3119
+
3120
+ vector<int> _nodes(N*2);
3121
+ int (*nodes)[2] = (int(*)[2])&_nodes[0];
3122
+
3123
+ // The first O(N) pass: create N single-vertex trees
3124
+ for(i = 0; i < N; i++)
3125
+ {
3126
+ nodes[i][PARENT]=-1;
3127
+ nodes[i][RANK] = 0;
3128
+ }
3129
+
3130
+ // The main O(N^2) pass: merge connected components
3131
+ for( i = 0; i < N; i++ )
3132
+ {
3133
+ int root = i;
3134
+
3135
+ // find root
3136
+ while( nodes[root][PARENT] >= 0 )
3137
+ root = nodes[root][PARENT];
3138
+
3139
+ for( j = 0; j < N; j++ )
3140
+ {
3141
+ if( i == j || !predicate(vec[i], vec[j]))
3142
+ continue;
3143
+ int root2 = j;
3144
+
3145
+ while( nodes[root2][PARENT] >= 0 )
3146
+ root2 = nodes[root2][PARENT];
3147
+
3148
+ if( root2 != root )
3149
+ {
3150
+ // unite both trees
3151
+ int rank = nodes[root][RANK], rank2 = nodes[root2][RANK];
3152
+ if( rank > rank2 )
3153
+ nodes[root2][PARENT] = root;
3154
+ else
3155
+ {
3156
+ nodes[root][PARENT] = root2;
3157
+ nodes[root2][RANK] += rank == rank2;
3158
+ root = root2;
3159
+ }
3160
+ assert( nodes[root][PARENT] < 0 );
3161
+
3162
+ int k = j, parent;
3163
+
3164
+ // compress the path from node2 to root
3165
+ while( (parent = nodes[k][PARENT]) >= 0 )
3166
+ {
3167
+ nodes[k][PARENT] = root;
3168
+ k = parent;
3169
+ }
3170
+
3171
+ // compress the path from node to root
3172
+ k = i;
3173
+ while( (parent = nodes[k][PARENT]) >= 0 )
3174
+ {
3175
+ nodes[k][PARENT] = root;
3176
+ k = parent;
3177
+ }
3178
+ }
3179
+ }
3180
+ }
3181
+
3182
+ // Final O(N) pass: enumerate classes
3183
+ labels.resize(N);
3184
+ int nclasses = 0;
3185
+
3186
+ for( i = 0; i < N; i++ )
3187
+ {
3188
+ int root = i;
3189
+ while( nodes[root][PARENT] >= 0 )
3190
+ root = nodes[root][PARENT];
3191
+ // re-use the rank as the class label
3192
+ if( nodes[root][RANK] >= 0 )
3193
+ nodes[root][RANK] = ~nclasses++;
3194
+ labels[i] = ~nodes[root][RANK];
3195
+ }
3196
+
3197
+ return nclasses;
3198
+ }
3199
+
3200
+
3201
+ //////////////////////////////////////////////////////////////////////////////
3202
+
3203
+ // bridge C++ => C Seq API
3204
+ CV_EXPORTS schar* seqPush( CvSeq* seq, const void* element=0);
3205
+ CV_EXPORTS schar* seqPushFront( CvSeq* seq, const void* element=0);
3206
+ CV_EXPORTS void seqPop( CvSeq* seq, void* element=0);
3207
+ CV_EXPORTS void seqPopFront( CvSeq* seq, void* element=0);
3208
+ CV_EXPORTS void seqPopMulti( CvSeq* seq, void* elements,
3209
+ int count, int in_front=0 );
3210
+ CV_EXPORTS void seqRemove( CvSeq* seq, int index );
3211
+ CV_EXPORTS void clearSeq( CvSeq* seq );
3212
+ CV_EXPORTS schar* getSeqElem( const CvSeq* seq, int index );
3213
+ CV_EXPORTS void seqRemoveSlice( CvSeq* seq, CvSlice slice );
3214
+ CV_EXPORTS void seqInsertSlice( CvSeq* seq, int before_index, const CvArr* from_arr );
3215
+
3216
+ template<typename _Tp> inline Seq<_Tp>::Seq() : seq(0) {}
3217
+ template<typename _Tp> inline Seq<_Tp>::Seq( const CvSeq* _seq ) : seq((CvSeq*)_seq)
3218
+ {
3219
+ CV_Assert(!_seq || _seq->elem_size == sizeof(_Tp));
3220
+ }
3221
+
3222
+ template<typename _Tp> inline Seq<_Tp>::Seq( MemStorage& storage,
3223
+ int headerSize )
3224
+ {
3225
+ CV_Assert(headerSize >= (int)sizeof(CvSeq));
3226
+ seq = cvCreateSeq(DataType<_Tp>::type, headerSize, sizeof(_Tp), storage);
3227
+ }
3228
+
3229
+ template<typename _Tp> inline _Tp& Seq<_Tp>::operator [](int idx)
3230
+ { return *(_Tp*)getSeqElem(seq, idx); }
3231
+
3232
+ template<typename _Tp> inline const _Tp& Seq<_Tp>::operator [](int idx) const
3233
+ { return *(_Tp*)getSeqElem(seq, idx); }
3234
+
3235
+ template<typename _Tp> inline SeqIterator<_Tp> Seq<_Tp>::begin() const
3236
+ { return SeqIterator<_Tp>(*this); }
3237
+
3238
+ template<typename _Tp> inline SeqIterator<_Tp> Seq<_Tp>::end() const
3239
+ { return SeqIterator<_Tp>(*this, true); }
3240
+
3241
+ template<typename _Tp> inline size_t Seq<_Tp>::size() const
3242
+ { return seq ? seq->total : 0; }
3243
+
3244
+ template<typename _Tp> inline int Seq<_Tp>::type() const
3245
+ { return seq ? CV_MAT_TYPE(seq->flags) : 0; }
3246
+
3247
+ template<typename _Tp> inline int Seq<_Tp>::depth() const
3248
+ { return seq ? CV_MAT_DEPTH(seq->flags) : 0; }
3249
+
3250
+ template<typename _Tp> inline int Seq<_Tp>::channels() const
3251
+ { return seq ? CV_MAT_CN(seq->flags) : 0; }
3252
+
3253
+ template<typename _Tp> inline size_t Seq<_Tp>::elemSize() const
3254
+ { return seq ? seq->elem_size : 0; }
3255
+
3256
+ template<typename _Tp> inline size_t Seq<_Tp>::index(const _Tp& elem) const
3257
+ { return cvSeqElemIdx(seq, &elem); }
3258
+
3259
+ template<typename _Tp> inline void Seq<_Tp>::push_back(const _Tp& elem)
3260
+ { cvSeqPush(seq, &elem); }
3261
+
3262
+ template<typename _Tp> inline void Seq<_Tp>::push_front(const _Tp& elem)
3263
+ { cvSeqPushFront(seq, &elem); }
3264
+
3265
+ template<typename _Tp> inline void Seq<_Tp>::push_back(const _Tp* elem, size_t count)
3266
+ { cvSeqPushMulti(seq, elem, (int)count, 0); }
3267
+
3268
+ template<typename _Tp> inline void Seq<_Tp>::push_front(const _Tp* elem, size_t count)
3269
+ { cvSeqPushMulti(seq, elem, (int)count, 1); }
3270
+
3271
+ template<typename _Tp> inline _Tp& Seq<_Tp>::back()
3272
+ { return *(_Tp*)getSeqElem(seq, -1); }
3273
+
3274
+ template<typename _Tp> inline const _Tp& Seq<_Tp>::back() const
3275
+ { return *(const _Tp*)getSeqElem(seq, -1); }
3276
+
3277
+ template<typename _Tp> inline _Tp& Seq<_Tp>::front()
3278
+ { return *(_Tp*)getSeqElem(seq, 0); }
3279
+
3280
+ template<typename _Tp> inline const _Tp& Seq<_Tp>::front() const
3281
+ { return *(const _Tp*)getSeqElem(seq, 0); }
3282
+
3283
+ template<typename _Tp> inline bool Seq<_Tp>::empty() const
3284
+ { return !seq || seq->total == 0; }
3285
+
3286
+ template<typename _Tp> inline void Seq<_Tp>::clear()
3287
+ { if(seq) clearSeq(seq); }
3288
+
3289
+ template<typename _Tp> inline void Seq<_Tp>::pop_back()
3290
+ { seqPop(seq); }
3291
+
3292
+ template<typename _Tp> inline void Seq<_Tp>::pop_front()
3293
+ { seqPopFront(seq); }
3294
+
3295
+ template<typename _Tp> inline void Seq<_Tp>::pop_back(_Tp* elem, size_t count)
3296
+ { seqPopMulti(seq, elem, (int)count, 0); }
3297
+
3298
+ template<typename _Tp> inline void Seq<_Tp>::pop_front(_Tp* elem, size_t count)
3299
+ { seqPopMulti(seq, elem, (int)count, 1); }
3300
+
3301
+ template<typename _Tp> inline void Seq<_Tp>::insert(int idx, const _Tp& elem)
3302
+ { seqInsert(seq, idx, &elem); }
3303
+
3304
+ template<typename _Tp> inline void Seq<_Tp>::insert(int idx, const _Tp* elems, size_t count)
3305
+ {
3306
+ CvMat m = cvMat(1, count, DataType<_Tp>::type, elems);
3307
+ seqInsertSlice(seq, idx, &m);
3308
+ }
3309
+
3310
+ template<typename _Tp> inline void Seq<_Tp>::remove(int idx)
3311
+ { seqRemove(seq, idx); }
3312
+
3313
+ template<typename _Tp> inline void Seq<_Tp>::remove(const Range& r)
3314
+ { seqRemoveSlice(seq, r); }
3315
+
3316
+ template<typename _Tp> inline void Seq<_Tp>::copyTo(vector<_Tp>& vec, const Range& range) const
3317
+ {
3318
+ size_t len = !seq ? 0 : range == Range::all() ? seq->total : range.end - range.start;
3319
+ vec.resize(len);
3320
+ if( seq && len )
3321
+ cvCvtSeqToArray(seq, &vec[0], range);
3322
+ }
3323
+
3324
+ template<typename _Tp> inline Seq<_Tp>::operator vector<_Tp>() const
3325
+ {
3326
+ vector<_Tp> vec;
3327
+ copyTo(vec);
3328
+ return vec;
3329
+ }
3330
+
3331
+ template<typename _Tp> inline SeqIterator<_Tp>::SeqIterator()
3332
+ { memset(this, 0, sizeof(*this)); }
3333
+
3334
+ template<typename _Tp> inline SeqIterator<_Tp>::SeqIterator(const Seq<_Tp>& seq, bool seekEnd)
3335
+ {
3336
+ cvStartReadSeq(seq.seq, this);
3337
+ index = seekEnd ? seq.seq->total : 0;
3338
+ }
3339
+
3340
+ template<typename _Tp> inline void SeqIterator<_Tp>::seek(size_t pos)
3341
+ {
3342
+ cvSetSeqReaderPos(this, (int)pos, false);
3343
+ index = pos;
3344
+ }
3345
+
3346
+ template<typename _Tp> inline size_t SeqIterator<_Tp>::tell() const
3347
+ { return index; }
3348
+
3349
+ template<typename _Tp> inline _Tp& SeqIterator<_Tp>::operator *()
3350
+ { return *(_Tp*)ptr; }
3351
+
3352
+ template<typename _Tp> inline const _Tp& SeqIterator<_Tp>::operator *() const
3353
+ { return *(const _Tp*)ptr; }
3354
+
3355
+ template<typename _Tp> inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator ++()
3356
+ {
3357
+ CV_NEXT_SEQ_ELEM(sizeof(_Tp), *this);
3358
+ if( ++index >= seq->total*2 )
3359
+ index = 0;
3360
+ return *this;
3361
+ }
3362
+
3363
+ template<typename _Tp> inline SeqIterator<_Tp> SeqIterator<_Tp>::operator ++(int) const
3364
+ {
3365
+ SeqIterator<_Tp> it = *this;
3366
+ ++*this;
3367
+ return it;
3368
+ }
3369
+
3370
+ template<typename _Tp> inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator --()
3371
+ {
3372
+ CV_PREV_SEQ_ELEM(sizeof(_Tp), *this);
3373
+ if( --index < 0 )
3374
+ index = seq->total*2-1;
3375
+ return *this;
3376
+ }
3377
+
3378
+ template<typename _Tp> inline SeqIterator<_Tp> SeqIterator<_Tp>::operator --(int) const
3379
+ {
3380
+ SeqIterator<_Tp> it = *this;
3381
+ --*this;
3382
+ return it;
3383
+ }
3384
+
3385
+ template<typename _Tp> inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator +=(int delta)
3386
+ {
3387
+ cvSetSeqReaderPos(this, delta, 1);
3388
+ index += delta;
3389
+ int n = seq->total*2;
3390
+ if( index < 0 )
3391
+ index += n;
3392
+ if( index >= n )
3393
+ index -= n;
3394
+ return *this;
3395
+ }
3396
+
3397
+ template<typename _Tp> inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator -=(int delta)
3398
+ {
3399
+ return (*this += -delta);
3400
+ }
3401
+
3402
+ template<typename _Tp> inline ptrdiff_t operator - (const SeqIterator<_Tp>& a,
3403
+ const SeqIterator<_Tp>& b)
3404
+ {
3405
+ ptrdiff_t delta = a.index - b.index, n = a.seq->total;
3406
+ if( std::abs(static_cast<long>(delta)) > n )
3407
+ delta += delta < 0 ? n : -n;
3408
+ return delta;
3409
+ }
3410
+
3411
+ template<typename _Tp> inline bool operator == (const SeqIterator<_Tp>& a,
3412
+ const SeqIterator<_Tp>& b)
3413
+ {
3414
+ return a.seq == b.seq && a.index == b.index;
3415
+ }
3416
+
3417
+ template<typename _Tp> inline bool operator != (const SeqIterator<_Tp>& a,
3418
+ const SeqIterator<_Tp>& b)
3419
+ {
3420
+ return !(a == b);
3421
+ }
3422
+
3423
+
3424
+ template<typename _ClsName> struct CV_EXPORTS RTTIImpl
3425
+ {
3426
+ public:
3427
+ static int isInstance(const void* ptr)
3428
+ {
3429
+ static _ClsName dummy;
3430
+ union
3431
+ {
3432
+ const void* p;
3433
+ const void** pp;
3434
+ } a, b;
3435
+ a.p = &dummy;
3436
+ b.p = ptr;
3437
+ return *a.pp == *b.pp;
3438
+ }
3439
+ static void release(void** dbptr)
3440
+ {
3441
+ if(dbptr && *dbptr)
3442
+ {
3443
+ delete (_ClsName*)*dbptr;
3444
+ *dbptr = 0;
3445
+ }
3446
+ }
3447
+ static void* read(CvFileStorage* fs, CvFileNode* n)
3448
+ {
3449
+ FileNode fn(fs, n);
3450
+ _ClsName* obj = new _ClsName;
3451
+ if(obj->read(fn))
3452
+ return obj;
3453
+ delete obj;
3454
+ return 0;
3455
+ }
3456
+
3457
+ static void write(CvFileStorage* _fs, const char* name, const void* ptr, CvAttrList)
3458
+ {
3459
+ if(ptr && _fs)
3460
+ {
3461
+ FileStorage fs(_fs);
3462
+ fs.fs.addref();
3463
+ ((const _ClsName*)ptr)->write(fs, string(name));
3464
+ }
3465
+ }
3466
+
3467
+ static void* clone(const void* ptr)
3468
+ {
3469
+ if(!ptr)
3470
+ return 0;
3471
+ return new _ClsName(*(const _ClsName*)ptr);
3472
+ }
3473
+ };
3474
+
3475
+
3476
+ class CV_EXPORTS Formatter
3477
+ {
3478
+ public:
3479
+ virtual ~Formatter() {}
3480
+ virtual void write(std::ostream& out, const Mat& m, const int* params=0, int nparams=0) const = 0;
3481
+ virtual void write(std::ostream& out, const void* data, int nelems, int type,
3482
+ const int* params=0, int nparams=0) const = 0;
3483
+ static const Formatter* get(const char* fmt="");
3484
+ static const Formatter* setDefault(const Formatter* fmt);
3485
+ };
3486
+
3487
+
3488
+ struct CV_EXPORTS Formatted
3489
+ {
3490
+ Formatted(const Mat& m, const Formatter* fmt,
3491
+ const vector<int>& params);
3492
+ Formatted(const Mat& m, const Formatter* fmt,
3493
+ const int* params=0);
3494
+ Mat mtx;
3495
+ const Formatter* fmt;
3496
+ vector<int> params;
3497
+ };
3498
+
3499
+
3500
+ /** Writes a point to an output stream in Matlab notation
3501
+ */
3502
+ template<typename _Tp> inline std::ostream& operator<<(std::ostream& out, const Point_<_Tp>& p)
3503
+ {
3504
+ out << "[" << p.x << ", " << p.y << "]";
3505
+ return out;
3506
+ }
3507
+
3508
+ /** Writes a point to an output stream in Matlab notation
3509
+ */
3510
+ template<typename _Tp> inline std::ostream& operator<<(std::ostream& out, const Point3_<_Tp>& p)
3511
+ {
3512
+ out << "[" << p.x << ", " << p.y << ", " << p.z << "]";
3513
+ return out;
3514
+ }
3515
+
3516
+ static inline Formatted format(const Mat& mtx, const char* fmt,
3517
+ const vector<int>& params=vector<int>())
3518
+ {
3519
+ return Formatted(mtx, Formatter::get(fmt), params);
3520
+ }
3521
+
3522
+ template<typename _Tp> static inline Formatted format(const vector<Point_<_Tp> >& vec,
3523
+ const char* fmt, const vector<int>& params=vector<int>())
3524
+ {
3525
+ return Formatted(Mat(vec), Formatter::get(fmt), params);
3526
+ }
3527
+
3528
+ template<typename _Tp> static inline Formatted format(const vector<Point3_<_Tp> >& vec,
3529
+ const char* fmt, const vector<int>& params=vector<int>())
3530
+ {
3531
+ return Formatted(Mat(vec), Formatter::get(fmt), params);
3532
+ }
3533
+
3534
+ /** \brief prints Mat to the output stream in Matlab notation
3535
+ * use like
3536
+ @verbatim
3537
+ Mat my_mat = Mat::eye(3,3,CV_32F);
3538
+ std::cout << my_mat;
3539
+ @endverbatim
3540
+ */
3541
+ static inline std::ostream& operator << (std::ostream& out, const Mat& mtx)
3542
+ {
3543
+ Formatter::get()->write(out, mtx);
3544
+ return out;
3545
+ }
3546
+
3547
+ /** \brief prints Mat to the output stream allows in the specified notation (see format)
3548
+ * use like
3549
+ @verbatim
3550
+ Mat my_mat = Mat::eye(3,3,CV_32F);
3551
+ std::cout << my_mat;
3552
+ @endverbatim
3553
+ */
3554
+ static inline std::ostream& operator << (std::ostream& out, const Formatted& fmtd)
3555
+ {
3556
+ fmtd.fmt->write(out, fmtd.mtx);
3557
+ return out;
3558
+ }
3559
+
3560
+
3561
+ template<typename _Tp> static inline std::ostream& operator << (std::ostream& out,
3562
+ const vector<Point_<_Tp> >& vec)
3563
+ {
3564
+ Formatter::get()->write(out, Mat(vec));
3565
+ return out;
3566
+ }
3567
+
3568
+
3569
+ template<typename _Tp> static inline std::ostream& operator << (std::ostream& out,
3570
+ const vector<Point3_<_Tp> >& vec)
3571
+ {
3572
+ Formatter::get()->write(out, Mat(vec));
3573
+ return out;
3574
+ }
3575
+
3576
+ /*template<typename _Tp> struct AlgorithmParamType {};
3577
+ template<> struct AlgorithmParamType<int> { enum { type = CV_PARAM_TYPE_INT }; };
3578
+ template<> struct AlgorithmParamType<double> { enum { type = CV_PARAM_TYPE_REAL }; };
3579
+ template<> struct AlgorithmParamType<string> { enum { type = CV_PARAM_TYPE_STRING }; };
3580
+ template<> struct AlgorithmParamType<Mat> { enum { type = CV_PARAM_TYPE_MAT }; };
3581
+
3582
+ template<typename _Tp> _Tp Algorithm::get(int paramId) const
3583
+ {
3584
+ _Tp value = _Tp();
3585
+ get_(paramId, AlgorithmParamType<_Tp>::type, &value);
3586
+ return value;
3587
+ }
3588
+
3589
+ template<typename _Tp> bool Algorithm::set(int paramId, const _Tp& value)
3590
+ {
3591
+ set_(paramId, AlgorithmParamType<_Tp>::type, &value);
3592
+ return value;
3593
+ }
3594
+
3595
+ template<typename _Tp> _Tp Algorithm::paramDefaultValue(int paramId) const
3596
+ {
3597
+ _Tp value = _Tp();
3598
+ paramDefaultValue_(paramId, AlgorithmParamType<_Tp>::type, &value);
3599
+ return value;
3600
+ }
3601
+
3602
+ template<typename _Tp> bool Algorithm::paramRange(int paramId, _Tp& minVal, _Tp& maxVal) const
3603
+ {
3604
+ return paramRange_(paramId, AlgorithmParamType<_Tp>::type, &minVal, &maxVal);
3605
+ }
3606
+
3607
+ template<typename _Tp> void Algorithm::addParam(int propId, _Tp& value, bool readOnly, const string& name,
3608
+ const string& help, const _Tp& defaultValue,
3609
+ _Tp (Algorithm::*getter)(), bool (Algorithm::*setter)(const _Tp&))
3610
+ {
3611
+ addParam_(propId, AlgorithmParamType<_Tp>::type, &value, readOnly, name, help, &defaultValue,
3612
+ (void*)getter, (void*)setter);
3613
+ }
3614
+
3615
+ template<typename _Tp> void Algorithm::setParamRange(int propId, const _Tp& minVal, const _Tp& maxVal)
3616
+ {
3617
+ setParamRange_(propId, AlgorithmParamType<_Tp>::type, &minVal, &maxVal);
3618
+ }*/
3619
+
3620
+ }
3621
+
3622
+ #endif // __cplusplus
3623
+ #endif