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.
- data/.gitignore +24 -0
- data/Gemfile +4 -0
- data/Rakefile +2 -0
- data/ext/imagecore/analyze_image.cxx +58 -0
- data/ext/imagecore/analyze_image.h +6 -0
- data/ext/imagecore/extconf.rb +9 -0
- data/ext/imagecore/imagecore.cxx +34 -0
- data/ext/opencv/core/___.c +3 -0
- data/ext/opencv/core/alloc.cpp +697 -0
- data/ext/opencv/core/array.cpp +3206 -0
- data/ext/opencv/core/datastructs.cpp +4064 -0
- data/ext/opencv/core/extconf.rb +22 -0
- data/ext/opencv/core/matrix.cpp +3777 -0
- data/ext/opencv/core/precomp.hpp +216 -0
- data/ext/opencv/core/system.cpp +832 -0
- data/ext/opencv/core/tables.cpp +3512 -0
- data/ext/opencv/highgui/___.c +3 -0
- data/ext/opencv/highgui/bitstrm.cpp +582 -0
- data/ext/opencv/highgui/bitstrm.hpp +182 -0
- data/ext/opencv/highgui/extconf.rb +28 -0
- data/ext/opencv/highgui/grfmt_base.cpp +128 -0
- data/ext/opencv/highgui/grfmt_base.hpp +113 -0
- data/ext/opencv/highgui/grfmt_bmp.cpp +564 -0
- data/ext/opencv/highgui/grfmt_bmp.hpp +99 -0
- data/ext/opencv/highgui/grfmt_exr.hpp +113 -0
- data/ext/opencv/highgui/grfmt_imageio.hpp +56 -0
- data/ext/opencv/highgui/grfmt_jpeg.cpp +622 -0
- data/ext/opencv/highgui/grfmt_jpeg.hpp +90 -0
- data/ext/opencv/highgui/grfmt_jpeg2000.cpp +529 -0
- data/ext/opencv/highgui/grfmt_jpeg2000.hpp +95 -0
- data/ext/opencv/highgui/grfmt_png.cpp +406 -0
- data/ext/opencv/highgui/grfmt_png.hpp +101 -0
- data/ext/opencv/highgui/grfmt_pxm.cpp +513 -0
- data/ext/opencv/highgui/grfmt_pxm.hpp +92 -0
- data/ext/opencv/highgui/grfmt_sunras.cpp +425 -0
- data/ext/opencv/highgui/grfmt_sunras.hpp +105 -0
- data/ext/opencv/highgui/grfmt_tiff.cpp +718 -0
- data/ext/opencv/highgui/grfmt_tiff.hpp +136 -0
- data/ext/opencv/highgui/grfmts.hpp +56 -0
- data/ext/opencv/highgui/loadsave.cpp +535 -0
- data/ext/opencv/highgui/precomp.hpp +223 -0
- data/ext/opencv/highgui/utils.cpp +689 -0
- data/ext/opencv/highgui/utils.hpp +128 -0
- data/ext/opencv/imgproc/___.c +3 -0
- data/ext/opencv/imgproc/_geom.h +72 -0
- data/ext/opencv/imgproc/color.cpp +3179 -0
- data/ext/opencv/imgproc/contours.cpp +1780 -0
- data/ext/opencv/imgproc/extconf.rb +11 -0
- data/ext/opencv/imgproc/filter.cpp +3063 -0
- data/ext/opencv/imgproc/precomp.hpp +159 -0
- data/ext/opencv/imgproc/shapedescr.cpp +1306 -0
- data/ext/opencv/imgproc/smooth.cpp +1566 -0
- data/ext/opencv/imgproc/tables.cpp +214 -0
- data/ext/opencv/imgproc/thresh.cpp +636 -0
- data/ext/opencv/imgproc/utils.cpp +242 -0
- data/ext/opencv/include/opencv2/core/core.hpp +4344 -0
- data/ext/opencv/include/opencv2/core/core_c.h +1885 -0
- data/ext/opencv/include/opencv2/core/internal.hpp +710 -0
- data/ext/opencv/include/opencv2/core/mat.hpp +2557 -0
- data/ext/opencv/include/opencv2/core/operations.hpp +3623 -0
- data/ext/opencv/include/opencv2/core/types_c.h +1875 -0
- data/ext/opencv/include/opencv2/core/version.hpp +58 -0
- data/ext/opencv/include/opencv2/highgui/highgui.hpp +198 -0
- data/ext/opencv/include/opencv2/highgui/highgui_c.h +506 -0
- data/ext/opencv/include/opencv2/imgproc/imgproc.hpp +1139 -0
- data/ext/opencv/include/opencv2/imgproc/imgproc_c.h +783 -0
- data/ext/opencv/include/opencv2/imgproc/types_c.h +538 -0
- data/imagecore.gemspec +20 -0
- data/lib/imagecore.rb +16 -0
- data/lib/imagecore/version.rb +3 -0
- 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
|