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,3206 @@
|
|
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
|
+
// Intel License Agreement
|
11
|
+
// For Open Source Computer Vision Library
|
12
|
+
//
|
13
|
+
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
14
|
+
// Third party copyrights are property of their respective owners.
|
15
|
+
//
|
16
|
+
// Redistribution and use in source and binary forms, with or without modification,
|
17
|
+
// are permitted provided that the following conditions are met:
|
18
|
+
//
|
19
|
+
// * Redistribution's of source code must retain the above copyright notice,
|
20
|
+
// this list of conditions and the following disclaimer.
|
21
|
+
//
|
22
|
+
// * Redistribution's in binary form must reproduce the above copyright notice,
|
23
|
+
// this list of conditions and the following disclaimer in the documentation
|
24
|
+
// and/or other materials provided with the distribution.
|
25
|
+
//
|
26
|
+
// * The name of Intel Corporation may not be used to endorse or promote products
|
27
|
+
// derived from this software without specific prior written permission.
|
28
|
+
//
|
29
|
+
// This software is provided by the copyright holders and contributors "as is" and
|
30
|
+
// any express or implied warranties, including, but not limited to, the implied
|
31
|
+
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
32
|
+
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
33
|
+
// indirect, incidental, special, exemplary, or consequential damages
|
34
|
+
// (including, but not limited to, procurement of substitute goods or services;
|
35
|
+
// loss of use, data, or profits; or business interruption) however caused
|
36
|
+
// and on any theory of liability, whether in contract, strict liability,
|
37
|
+
// or tort (including negligence or otherwise) arising in any way out of
|
38
|
+
// the use of this software, even if advised of the possibility of such damage.
|
39
|
+
//
|
40
|
+
//M*/
|
41
|
+
|
42
|
+
/* ////////////////////////////////////////////////////////////////////
|
43
|
+
//
|
44
|
+
// CvMat, CvMatND, CvSparceMat and IplImage support functions
|
45
|
+
// (creation, deletion, copying, retrieving and setting elements etc.)
|
46
|
+
//
|
47
|
+
// */
|
48
|
+
|
49
|
+
#include "precomp.hpp"
|
50
|
+
|
51
|
+
|
52
|
+
static struct
|
53
|
+
{
|
54
|
+
Cv_iplCreateImageHeader createHeader;
|
55
|
+
Cv_iplAllocateImageData allocateData;
|
56
|
+
Cv_iplDeallocate deallocate;
|
57
|
+
Cv_iplCreateROI createROI;
|
58
|
+
Cv_iplCloneImage cloneImage;
|
59
|
+
}
|
60
|
+
CvIPL;
|
61
|
+
|
62
|
+
// Makes the library use native IPL image allocators
|
63
|
+
CV_IMPL void
|
64
|
+
cvSetIPLAllocators( Cv_iplCreateImageHeader createHeader,
|
65
|
+
Cv_iplAllocateImageData allocateData,
|
66
|
+
Cv_iplDeallocate deallocate,
|
67
|
+
Cv_iplCreateROI createROI,
|
68
|
+
Cv_iplCloneImage cloneImage )
|
69
|
+
{
|
70
|
+
int count = (createHeader != 0) + (allocateData != 0) + (deallocate != 0) +
|
71
|
+
(createROI != 0) + (cloneImage != 0);
|
72
|
+
|
73
|
+
if( count != 0 && count != 5 )
|
74
|
+
CV_Error( CV_StsBadArg, "Either all the pointers should be null or "
|
75
|
+
"they all should be non-null" );
|
76
|
+
|
77
|
+
CvIPL.createHeader = createHeader;
|
78
|
+
CvIPL.allocateData = allocateData;
|
79
|
+
CvIPL.deallocate = deallocate;
|
80
|
+
CvIPL.createROI = createROI;
|
81
|
+
CvIPL.cloneImage = cloneImage;
|
82
|
+
}
|
83
|
+
|
84
|
+
|
85
|
+
/****************************************************************************************\
|
86
|
+
* CvMat creation and basic operations *
|
87
|
+
\****************************************************************************************/
|
88
|
+
|
89
|
+
// Creates CvMat and underlying data
|
90
|
+
CV_IMPL CvMat*
|
91
|
+
cvCreateMat( int height, int width, int type )
|
92
|
+
{
|
93
|
+
CvMat* arr = cvCreateMatHeader( height, width, type );
|
94
|
+
cvCreateData( arr );
|
95
|
+
|
96
|
+
return arr;
|
97
|
+
}
|
98
|
+
|
99
|
+
|
100
|
+
static void icvCheckHuge( CvMat* arr )
|
101
|
+
{
|
102
|
+
if( (int64)arr->step*arr->rows > INT_MAX )
|
103
|
+
arr->type &= ~CV_MAT_CONT_FLAG;
|
104
|
+
}
|
105
|
+
|
106
|
+
// Creates CvMat header only
|
107
|
+
CV_IMPL CvMat*
|
108
|
+
cvCreateMatHeader( int rows, int cols, int type )
|
109
|
+
{
|
110
|
+
type = CV_MAT_TYPE(type);
|
111
|
+
|
112
|
+
if( rows < 0 || cols <= 0 )
|
113
|
+
CV_Error( CV_StsBadSize, "Non-positive width or height" );
|
114
|
+
|
115
|
+
int min_step = CV_ELEM_SIZE(type)*cols;
|
116
|
+
if( min_step <= 0 )
|
117
|
+
CV_Error( CV_StsUnsupportedFormat, "Invalid matrix type" );
|
118
|
+
|
119
|
+
CvMat* arr = (CvMat*)cvAlloc( sizeof(*arr));
|
120
|
+
|
121
|
+
arr->step = min_step;
|
122
|
+
arr->type = CV_MAT_MAGIC_VAL | type | CV_MAT_CONT_FLAG;
|
123
|
+
arr->rows = rows;
|
124
|
+
arr->cols = cols;
|
125
|
+
arr->data.ptr = 0;
|
126
|
+
arr->refcount = 0;
|
127
|
+
arr->hdr_refcount = 1;
|
128
|
+
|
129
|
+
icvCheckHuge( arr );
|
130
|
+
return arr;
|
131
|
+
}
|
132
|
+
|
133
|
+
|
134
|
+
// Initializes CvMat header, allocated by the user
|
135
|
+
CV_IMPL CvMat*
|
136
|
+
cvInitMatHeader( CvMat* arr, int rows, int cols,
|
137
|
+
int type, void* data, int step )
|
138
|
+
{
|
139
|
+
if( !arr )
|
140
|
+
CV_Error( CV_StsNullPtr, "" );
|
141
|
+
|
142
|
+
if( (unsigned)CV_MAT_DEPTH(type) > CV_DEPTH_MAX )
|
143
|
+
CV_Error( CV_BadNumChannels, "" );
|
144
|
+
|
145
|
+
if( rows < 0 || cols <= 0 )
|
146
|
+
CV_Error( CV_StsBadSize, "Non-positive cols or rows" );
|
147
|
+
|
148
|
+
type = CV_MAT_TYPE( type );
|
149
|
+
arr->type = type | CV_MAT_MAGIC_VAL;
|
150
|
+
arr->rows = rows;
|
151
|
+
arr->cols = cols;
|
152
|
+
arr->data.ptr = (uchar*)data;
|
153
|
+
arr->refcount = 0;
|
154
|
+
arr->hdr_refcount = 0;
|
155
|
+
|
156
|
+
int pix_size = CV_ELEM_SIZE(type);
|
157
|
+
int min_step = arr->cols*pix_size;
|
158
|
+
|
159
|
+
if( step != CV_AUTOSTEP && step != 0 )
|
160
|
+
{
|
161
|
+
if( step < min_step )
|
162
|
+
CV_Error( CV_BadStep, "" );
|
163
|
+
arr->step = step;
|
164
|
+
}
|
165
|
+
else
|
166
|
+
{
|
167
|
+
arr->step = min_step;
|
168
|
+
}
|
169
|
+
|
170
|
+
arr->type = CV_MAT_MAGIC_VAL | type |
|
171
|
+
(arr->rows == 1 || arr->step == min_step ? CV_MAT_CONT_FLAG : 0);
|
172
|
+
|
173
|
+
icvCheckHuge( arr );
|
174
|
+
return arr;
|
175
|
+
}
|
176
|
+
|
177
|
+
|
178
|
+
// Deallocates the CvMat structure and underlying data
|
179
|
+
CV_IMPL void
|
180
|
+
cvReleaseMat( CvMat** array )
|
181
|
+
{
|
182
|
+
if( !array )
|
183
|
+
CV_Error( CV_HeaderIsNull, "" );
|
184
|
+
|
185
|
+
if( *array )
|
186
|
+
{
|
187
|
+
CvMat* arr = *array;
|
188
|
+
|
189
|
+
if( !CV_IS_MAT_HDR_Z(arr) && !CV_IS_MATND_HDR(arr) )
|
190
|
+
CV_Error( CV_StsBadFlag, "" );
|
191
|
+
|
192
|
+
*array = 0;
|
193
|
+
|
194
|
+
cvDecRefData( arr );
|
195
|
+
cvFree( &arr );
|
196
|
+
}
|
197
|
+
}
|
198
|
+
|
199
|
+
|
200
|
+
// Creates a copy of matrix
|
201
|
+
CV_IMPL CvMat*
|
202
|
+
cvCloneMat( const CvMat* src )
|
203
|
+
{
|
204
|
+
if( !CV_IS_MAT_HDR( src ))
|
205
|
+
CV_Error( CV_StsBadArg, "Bad CvMat header" );
|
206
|
+
|
207
|
+
CvMat* dst = cvCreateMatHeader( src->rows, src->cols, src->type );
|
208
|
+
|
209
|
+
if( src->data.ptr )
|
210
|
+
{
|
211
|
+
cvCreateData( dst );
|
212
|
+
cvCopy( src, dst );
|
213
|
+
}
|
214
|
+
|
215
|
+
return dst;
|
216
|
+
}
|
217
|
+
|
218
|
+
|
219
|
+
/****************************************************************************************\
|
220
|
+
* CvMatND creation and basic operations *
|
221
|
+
\****************************************************************************************/
|
222
|
+
|
223
|
+
CV_IMPL CvMatND*
|
224
|
+
cvInitMatNDHeader( CvMatND* mat, int dims, const int* sizes,
|
225
|
+
int type, void* data )
|
226
|
+
{
|
227
|
+
type = CV_MAT_TYPE(type);
|
228
|
+
int64 step = CV_ELEM_SIZE(type);
|
229
|
+
|
230
|
+
if( !mat )
|
231
|
+
CV_Error( CV_StsNullPtr, "NULL matrix header pointer" );
|
232
|
+
|
233
|
+
if( step == 0 )
|
234
|
+
CV_Error( CV_StsUnsupportedFormat, "invalid array data type" );
|
235
|
+
|
236
|
+
if( !sizes )
|
237
|
+
CV_Error( CV_StsNullPtr, "NULL <sizes> pointer" );
|
238
|
+
|
239
|
+
if( dims <= 0 || dims > CV_MAX_DIM )
|
240
|
+
CV_Error( CV_StsOutOfRange,
|
241
|
+
"non-positive or too large number of dimensions" );
|
242
|
+
|
243
|
+
for( int i = dims - 1; i >= 0; i-- )
|
244
|
+
{
|
245
|
+
if( sizes[i] < 0 )
|
246
|
+
CV_Error( CV_StsBadSize, "one of dimesion sizes is non-positive" );
|
247
|
+
mat->dim[i].size = sizes[i];
|
248
|
+
if( step > INT_MAX )
|
249
|
+
CV_Error( CV_StsOutOfRange, "The array is too big" );
|
250
|
+
mat->dim[i].step = (int)step;
|
251
|
+
step *= sizes[i];
|
252
|
+
}
|
253
|
+
|
254
|
+
mat->type = CV_MATND_MAGIC_VAL | (step <= INT_MAX ? CV_MAT_CONT_FLAG : 0) | type;
|
255
|
+
mat->dims = dims;
|
256
|
+
mat->data.ptr = (uchar*)data;
|
257
|
+
mat->refcount = 0;
|
258
|
+
mat->hdr_refcount = 0;
|
259
|
+
return mat;
|
260
|
+
}
|
261
|
+
|
262
|
+
|
263
|
+
// Creates CvMatND and underlying data
|
264
|
+
CV_IMPL CvMatND*
|
265
|
+
cvCreateMatND( int dims, const int* sizes, int type )
|
266
|
+
{
|
267
|
+
CvMatND* arr = cvCreateMatNDHeader( dims, sizes, type );
|
268
|
+
cvCreateData( arr );
|
269
|
+
|
270
|
+
return arr;
|
271
|
+
}
|
272
|
+
|
273
|
+
|
274
|
+
// Creates CvMatND header only
|
275
|
+
CV_IMPL CvMatND*
|
276
|
+
cvCreateMatNDHeader( int dims, const int* sizes, int type )
|
277
|
+
{
|
278
|
+
if( dims <= 0 || dims > CV_MAX_DIM )
|
279
|
+
CV_Error( CV_StsOutOfRange,
|
280
|
+
"non-positive or too large number of dimensions" );
|
281
|
+
|
282
|
+
CvMatND* arr = (CvMatND*)cvAlloc( sizeof(*arr) );
|
283
|
+
|
284
|
+
cvInitMatNDHeader( arr, dims, sizes, type, 0 );
|
285
|
+
arr->hdr_refcount = 1;
|
286
|
+
return arr;
|
287
|
+
}
|
288
|
+
|
289
|
+
|
290
|
+
// Creates a copy of nD array
|
291
|
+
CV_IMPL CvMatND*
|
292
|
+
cvCloneMatND( const CvMatND* src )
|
293
|
+
{
|
294
|
+
if( !CV_IS_MATND_HDR( src ))
|
295
|
+
CV_Error( CV_StsBadArg, "Bad CvMatND header" );
|
296
|
+
|
297
|
+
CV_Assert( src->dims <= CV_MAX_DIM );
|
298
|
+
int sizes[CV_MAX_DIM];
|
299
|
+
|
300
|
+
for( int i = 0; i < src->dims; i++ )
|
301
|
+
sizes[i] = src->dim[i].size;
|
302
|
+
|
303
|
+
CvMatND* dst = cvCreateMatNDHeader( src->dims, sizes, src->type );
|
304
|
+
|
305
|
+
if( src->data.ptr )
|
306
|
+
{
|
307
|
+
cvCreateData( dst );
|
308
|
+
cv::Mat _src(src), _dst(dst);
|
309
|
+
uchar* data0 = dst->data.ptr;
|
310
|
+
_src.copyTo(_dst);
|
311
|
+
CV_Assert(_dst.data == data0);
|
312
|
+
//cvCopy( src, dst );
|
313
|
+
}
|
314
|
+
|
315
|
+
return dst;
|
316
|
+
}
|
317
|
+
|
318
|
+
|
319
|
+
static CvMatND*
|
320
|
+
cvGetMatND( const CvArr* arr, CvMatND* matnd, int* coi )
|
321
|
+
{
|
322
|
+
CvMatND* result = 0;
|
323
|
+
|
324
|
+
if( coi )
|
325
|
+
*coi = 0;
|
326
|
+
|
327
|
+
if( !matnd || !arr )
|
328
|
+
CV_Error( CV_StsNullPtr, "NULL array pointer is passed" );
|
329
|
+
|
330
|
+
if( CV_IS_MATND_HDR(arr))
|
331
|
+
{
|
332
|
+
if( !((CvMatND*)arr)->data.ptr )
|
333
|
+
CV_Error( CV_StsNullPtr, "The matrix has NULL data pointer" );
|
334
|
+
|
335
|
+
result = (CvMatND*)arr;
|
336
|
+
}
|
337
|
+
else
|
338
|
+
{
|
339
|
+
CvMat stub, *mat = (CvMat*)arr;
|
340
|
+
|
341
|
+
if( CV_IS_IMAGE_HDR( mat ))
|
342
|
+
mat = cvGetMat( mat, &stub, coi );
|
343
|
+
|
344
|
+
if( !CV_IS_MAT_HDR( mat ))
|
345
|
+
CV_Error( CV_StsBadArg, "Unrecognized or unsupported array type" );
|
346
|
+
|
347
|
+
if( !mat->data.ptr )
|
348
|
+
CV_Error( CV_StsNullPtr, "Input array has NULL data pointer" );
|
349
|
+
|
350
|
+
matnd->data.ptr = mat->data.ptr;
|
351
|
+
matnd->refcount = 0;
|
352
|
+
matnd->hdr_refcount = 0;
|
353
|
+
matnd->type = mat->type;
|
354
|
+
matnd->dims = 2;
|
355
|
+
matnd->dim[0].size = mat->rows;
|
356
|
+
matnd->dim[0].step = mat->step;
|
357
|
+
matnd->dim[1].size = mat->cols;
|
358
|
+
matnd->dim[1].step = CV_ELEM_SIZE(mat->type);
|
359
|
+
result = matnd;
|
360
|
+
}
|
361
|
+
|
362
|
+
return result;
|
363
|
+
}
|
364
|
+
|
365
|
+
|
366
|
+
// returns number of dimensions to iterate.
|
367
|
+
/*
|
368
|
+
Checks whether <count> arrays have equal type, sizes (mask is optional array
|
369
|
+
that needs to have the same size, but 8uC1 or 8sC1 type).
|
370
|
+
Returns number of dimensions to iterate through:
|
371
|
+
0 means that all arrays are continuous,
|
372
|
+
1 means that all arrays are vectors of continuous arrays etc.
|
373
|
+
and the size of largest common continuous part of the arrays
|
374
|
+
*/
|
375
|
+
CV_IMPL int
|
376
|
+
cvInitNArrayIterator( int count, CvArr** arrs,
|
377
|
+
const CvArr* mask, CvMatND* stubs,
|
378
|
+
CvNArrayIterator* iterator, int flags )
|
379
|
+
{
|
380
|
+
int dims = -1;
|
381
|
+
int i, j, size, dim0 = -1;
|
382
|
+
int64 step;
|
383
|
+
CvMatND* hdr0 = 0;
|
384
|
+
|
385
|
+
if( count < 1 || count > CV_MAX_ARR )
|
386
|
+
CV_Error( CV_StsOutOfRange, "Incorrect number of arrays" );
|
387
|
+
|
388
|
+
if( !arrs || !stubs )
|
389
|
+
CV_Error( CV_StsNullPtr, "Some of required array pointers is NULL" );
|
390
|
+
|
391
|
+
if( !iterator )
|
392
|
+
CV_Error( CV_StsNullPtr, "Iterator pointer is NULL" );
|
393
|
+
|
394
|
+
for( i = 0; i <= count; i++ )
|
395
|
+
{
|
396
|
+
const CvArr* arr = i < count ? arrs[i] : mask;
|
397
|
+
CvMatND* hdr;
|
398
|
+
|
399
|
+
if( !arr )
|
400
|
+
{
|
401
|
+
if( i < count )
|
402
|
+
CV_Error( CV_StsNullPtr, "Some of required array pointers is NULL" );
|
403
|
+
break;
|
404
|
+
}
|
405
|
+
|
406
|
+
if( CV_IS_MATND( arr ))
|
407
|
+
hdr = (CvMatND*)arr;
|
408
|
+
else
|
409
|
+
{
|
410
|
+
int coi = 0;
|
411
|
+
hdr = cvGetMatND( arr, stubs + i, &coi );
|
412
|
+
if( coi != 0 )
|
413
|
+
CV_Error( CV_BadCOI, "COI set is not allowed here" );
|
414
|
+
}
|
415
|
+
|
416
|
+
iterator->hdr[i] = hdr;
|
417
|
+
|
418
|
+
if( i > 0 )
|
419
|
+
{
|
420
|
+
if( hdr->dims != hdr0->dims )
|
421
|
+
CV_Error( CV_StsUnmatchedSizes,
|
422
|
+
"Number of dimensions is the same for all arrays" );
|
423
|
+
|
424
|
+
if( i < count )
|
425
|
+
{
|
426
|
+
switch( flags & (CV_NO_DEPTH_CHECK|CV_NO_CN_CHECK))
|
427
|
+
{
|
428
|
+
case 0:
|
429
|
+
if( !CV_ARE_TYPES_EQ( hdr, hdr0 ))
|
430
|
+
CV_Error( CV_StsUnmatchedFormats,
|
431
|
+
"Data type is not the same for all arrays" );
|
432
|
+
break;
|
433
|
+
case CV_NO_DEPTH_CHECK:
|
434
|
+
if( !CV_ARE_CNS_EQ( hdr, hdr0 ))
|
435
|
+
CV_Error( CV_StsUnmatchedFormats,
|
436
|
+
"Number of channels is not the same for all arrays" );
|
437
|
+
break;
|
438
|
+
case CV_NO_CN_CHECK:
|
439
|
+
if( !CV_ARE_CNS_EQ( hdr, hdr0 ))
|
440
|
+
CV_Error( CV_StsUnmatchedFormats,
|
441
|
+
"Depth is not the same for all arrays" );
|
442
|
+
break;
|
443
|
+
}
|
444
|
+
}
|
445
|
+
else
|
446
|
+
{
|
447
|
+
if( !CV_IS_MASK_ARR( hdr ))
|
448
|
+
CV_Error( CV_StsBadMask, "Mask should have 8uC1 or 8sC1 data type" );
|
449
|
+
}
|
450
|
+
|
451
|
+
if( !(flags & CV_NO_SIZE_CHECK) )
|
452
|
+
{
|
453
|
+
for( j = 0; j < hdr->dims; j++ )
|
454
|
+
if( hdr->dim[j].size != hdr0->dim[j].size )
|
455
|
+
CV_Error( CV_StsUnmatchedSizes,
|
456
|
+
"Dimension sizes are the same for all arrays" );
|
457
|
+
}
|
458
|
+
}
|
459
|
+
else
|
460
|
+
hdr0 = hdr;
|
461
|
+
|
462
|
+
step = CV_ELEM_SIZE(hdr->type);
|
463
|
+
for( j = hdr->dims - 1; j > dim0; j-- )
|
464
|
+
{
|
465
|
+
if( step != hdr->dim[j].step )
|
466
|
+
break;
|
467
|
+
step *= hdr->dim[j].size;
|
468
|
+
}
|
469
|
+
|
470
|
+
if( j == dim0 && step > INT_MAX )
|
471
|
+
j++;
|
472
|
+
|
473
|
+
if( j > dim0 )
|
474
|
+
dim0 = j;
|
475
|
+
|
476
|
+
iterator->hdr[i] = (CvMatND*)hdr;
|
477
|
+
iterator->ptr[i] = (uchar*)hdr->data.ptr;
|
478
|
+
}
|
479
|
+
|
480
|
+
size = 1;
|
481
|
+
for( j = hdr0->dims - 1; j > dim0; j-- )
|
482
|
+
size *= hdr0->dim[j].size;
|
483
|
+
|
484
|
+
dims = dim0 + 1;
|
485
|
+
iterator->dims = dims;
|
486
|
+
iterator->count = count;
|
487
|
+
iterator->size = cvSize(size,1);
|
488
|
+
|
489
|
+
for( i = 0; i < dims; i++ )
|
490
|
+
iterator->stack[i] = hdr0->dim[i].size;
|
491
|
+
|
492
|
+
return dims;
|
493
|
+
}
|
494
|
+
|
495
|
+
|
496
|
+
// returns zero value if iteration is finished, non-zero otherwise
|
497
|
+
CV_IMPL int cvNextNArraySlice( CvNArrayIterator* iterator )
|
498
|
+
{
|
499
|
+
assert( iterator != 0 );
|
500
|
+
int i, dims, size = 0;
|
501
|
+
|
502
|
+
for( dims = iterator->dims; dims > 0; dims-- )
|
503
|
+
{
|
504
|
+
for( i = 0; i < iterator->count; i++ )
|
505
|
+
iterator->ptr[i] += iterator->hdr[i]->dim[dims-1].step;
|
506
|
+
|
507
|
+
if( --iterator->stack[dims-1] > 0 )
|
508
|
+
break;
|
509
|
+
|
510
|
+
size = iterator->hdr[0]->dim[dims-1].size;
|
511
|
+
|
512
|
+
for( i = 0; i < iterator->count; i++ )
|
513
|
+
iterator->ptr[i] -= (size_t)size*iterator->hdr[i]->dim[dims-1].step;
|
514
|
+
|
515
|
+
iterator->stack[dims-1] = size;
|
516
|
+
}
|
517
|
+
|
518
|
+
return dims > 0;
|
519
|
+
}
|
520
|
+
|
521
|
+
|
522
|
+
/****************************************************************************************\
|
523
|
+
* CvSparseMat creation and basic operations *
|
524
|
+
\****************************************************************************************/
|
525
|
+
|
526
|
+
|
527
|
+
// Creates CvMatND and underlying data
|
528
|
+
CV_IMPL CvSparseMat*
|
529
|
+
cvCreateSparseMat( int dims, const int* sizes, int type )
|
530
|
+
{
|
531
|
+
type = CV_MAT_TYPE( type );
|
532
|
+
int pix_size1 = CV_ELEM_SIZE1(type);
|
533
|
+
int pix_size = pix_size1*CV_MAT_CN(type);
|
534
|
+
int i, size;
|
535
|
+
CvMemStorage* storage;
|
536
|
+
|
537
|
+
if( pix_size == 0 )
|
538
|
+
CV_Error( CV_StsUnsupportedFormat, "invalid array data type" );
|
539
|
+
|
540
|
+
if( dims <= 0 || dims > CV_MAX_DIM_HEAP )
|
541
|
+
CV_Error( CV_StsOutOfRange, "bad number of dimensions" );
|
542
|
+
|
543
|
+
if( !sizes )
|
544
|
+
CV_Error( CV_StsNullPtr, "NULL <sizes> pointer" );
|
545
|
+
|
546
|
+
for( i = 0; i < dims; i++ )
|
547
|
+
{
|
548
|
+
if( sizes[i] <= 0 )
|
549
|
+
CV_Error( CV_StsBadSize, "one of dimesion sizes is non-positive" );
|
550
|
+
}
|
551
|
+
|
552
|
+
CvSparseMat* arr = (CvSparseMat*)cvAlloc(sizeof(*arr)+MAX(0,dims-CV_MAX_DIM)*sizeof(arr->size[0]));
|
553
|
+
|
554
|
+
arr->type = CV_SPARSE_MAT_MAGIC_VAL | type;
|
555
|
+
arr->dims = dims;
|
556
|
+
arr->refcount = 0;
|
557
|
+
arr->hdr_refcount = 1;
|
558
|
+
memcpy( arr->size, sizes, dims*sizeof(sizes[0]));
|
559
|
+
|
560
|
+
arr->valoffset = (int)cvAlign(sizeof(CvSparseNode), pix_size1);
|
561
|
+
arr->idxoffset = (int)cvAlign(arr->valoffset + pix_size, sizeof(int));
|
562
|
+
size = (int)cvAlign(arr->idxoffset + dims*sizeof(int), sizeof(CvSetElem));
|
563
|
+
|
564
|
+
storage = cvCreateMemStorage( CV_SPARSE_MAT_BLOCK );
|
565
|
+
arr->heap = cvCreateSet( 0, sizeof(CvSet), size, storage );
|
566
|
+
|
567
|
+
arr->hashsize = CV_SPARSE_HASH_SIZE0;
|
568
|
+
size = arr->hashsize*sizeof(arr->hashtable[0]);
|
569
|
+
|
570
|
+
arr->hashtable = (void**)cvAlloc( size );
|
571
|
+
memset( arr->hashtable, 0, size );
|
572
|
+
|
573
|
+
return arr;
|
574
|
+
}
|
575
|
+
|
576
|
+
|
577
|
+
// Creates CvMatND and underlying data
|
578
|
+
CV_IMPL void
|
579
|
+
cvReleaseSparseMat( CvSparseMat** array )
|
580
|
+
{
|
581
|
+
if( !array )
|
582
|
+
CV_Error( CV_HeaderIsNull, "" );
|
583
|
+
|
584
|
+
if( *array )
|
585
|
+
{
|
586
|
+
CvSparseMat* arr = *array;
|
587
|
+
|
588
|
+
if( !CV_IS_SPARSE_MAT_HDR(arr) )
|
589
|
+
CV_Error( CV_StsBadFlag, "" );
|
590
|
+
|
591
|
+
*array = 0;
|
592
|
+
|
593
|
+
CvMemStorage* storage = arr->heap->storage;
|
594
|
+
cvReleaseMemStorage( &storage );
|
595
|
+
cvFree( &arr->hashtable );
|
596
|
+
cvFree( &arr );
|
597
|
+
}
|
598
|
+
}
|
599
|
+
|
600
|
+
|
601
|
+
// Creates CvMatND and underlying data
|
602
|
+
CV_IMPL CvSparseMat*
|
603
|
+
cvCloneSparseMat( const CvSparseMat* src )
|
604
|
+
{
|
605
|
+
if( !CV_IS_SPARSE_MAT_HDR(src) )
|
606
|
+
CV_Error( CV_StsBadArg, "Invalid sparse array header" );
|
607
|
+
|
608
|
+
CvSparseMat* dst = cvCreateSparseMat( src->dims, src->size, src->type );
|
609
|
+
cvCopy( src, dst );
|
610
|
+
return dst;
|
611
|
+
}
|
612
|
+
|
613
|
+
|
614
|
+
CvSparseNode*
|
615
|
+
cvInitSparseMatIterator( const CvSparseMat* mat, CvSparseMatIterator* iterator )
|
616
|
+
{
|
617
|
+
CvSparseNode* node = 0;
|
618
|
+
int idx;
|
619
|
+
|
620
|
+
if( !CV_IS_SPARSE_MAT( mat ))
|
621
|
+
CV_Error( CV_StsBadArg, "Invalid sparse matrix header" );
|
622
|
+
|
623
|
+
if( !iterator )
|
624
|
+
CV_Error( CV_StsNullPtr, "NULL iterator pointer" );
|
625
|
+
|
626
|
+
iterator->mat = (CvSparseMat*)mat;
|
627
|
+
iterator->node = 0;
|
628
|
+
|
629
|
+
for( idx = 0; idx < mat->hashsize; idx++ )
|
630
|
+
if( mat->hashtable[idx] )
|
631
|
+
{
|
632
|
+
node = iterator->node = (CvSparseNode*)mat->hashtable[idx];
|
633
|
+
break;
|
634
|
+
}
|
635
|
+
|
636
|
+
iterator->curidx = idx;
|
637
|
+
return node;
|
638
|
+
}
|
639
|
+
|
640
|
+
#define ICV_SPARSE_MAT_HASH_MULTIPLIER cv::SparseMat::HASH_SCALE
|
641
|
+
|
642
|
+
static uchar*
|
643
|
+
icvGetNodePtr( CvSparseMat* mat, const int* idx, int* _type,
|
644
|
+
int create_node, unsigned* precalc_hashval )
|
645
|
+
{
|
646
|
+
uchar* ptr = 0;
|
647
|
+
int i, tabidx;
|
648
|
+
unsigned hashval = 0;
|
649
|
+
CvSparseNode *node;
|
650
|
+
assert( CV_IS_SPARSE_MAT( mat ));
|
651
|
+
|
652
|
+
if( !precalc_hashval )
|
653
|
+
{
|
654
|
+
for( i = 0; i < mat->dims; i++ )
|
655
|
+
{
|
656
|
+
int t = idx[i];
|
657
|
+
if( (unsigned)t >= (unsigned)mat->size[i] )
|
658
|
+
CV_Error( CV_StsOutOfRange, "One of indices is out of range" );
|
659
|
+
hashval = hashval*ICV_SPARSE_MAT_HASH_MULTIPLIER + t;
|
660
|
+
}
|
661
|
+
}
|
662
|
+
else
|
663
|
+
{
|
664
|
+
hashval = *precalc_hashval;
|
665
|
+
}
|
666
|
+
|
667
|
+
tabidx = hashval & (mat->hashsize - 1);
|
668
|
+
hashval &= INT_MAX;
|
669
|
+
|
670
|
+
if( create_node >= -1 )
|
671
|
+
{
|
672
|
+
for( node = (CvSparseNode*)mat->hashtable[tabidx];
|
673
|
+
node != 0; node = node->next )
|
674
|
+
{
|
675
|
+
if( node->hashval == hashval )
|
676
|
+
{
|
677
|
+
int* nodeidx = CV_NODE_IDX(mat,node);
|
678
|
+
for( i = 0; i < mat->dims; i++ )
|
679
|
+
if( idx[i] != nodeidx[i] )
|
680
|
+
break;
|
681
|
+
if( i == mat->dims )
|
682
|
+
{
|
683
|
+
ptr = (uchar*)CV_NODE_VAL(mat,node);
|
684
|
+
break;
|
685
|
+
}
|
686
|
+
}
|
687
|
+
}
|
688
|
+
}
|
689
|
+
|
690
|
+
if( !ptr && create_node )
|
691
|
+
{
|
692
|
+
if( mat->heap->active_count >= mat->hashsize*CV_SPARSE_HASH_RATIO )
|
693
|
+
{
|
694
|
+
void** newtable;
|
695
|
+
int newsize = MAX( mat->hashsize*2, CV_SPARSE_HASH_SIZE0);
|
696
|
+
int newrawsize = newsize*sizeof(newtable[0]);
|
697
|
+
|
698
|
+
CvSparseMatIterator iterator;
|
699
|
+
assert( (newsize & (newsize - 1)) == 0 );
|
700
|
+
|
701
|
+
// resize hash table
|
702
|
+
newtable = (void**)cvAlloc( newrawsize );
|
703
|
+
memset( newtable, 0, newrawsize );
|
704
|
+
|
705
|
+
node = cvInitSparseMatIterator( mat, &iterator );
|
706
|
+
while( node )
|
707
|
+
{
|
708
|
+
CvSparseNode* next = cvGetNextSparseNode( &iterator );
|
709
|
+
int newidx = node->hashval & (newsize - 1);
|
710
|
+
node->next = (CvSparseNode*)newtable[newidx];
|
711
|
+
newtable[newidx] = node;
|
712
|
+
node = next;
|
713
|
+
}
|
714
|
+
|
715
|
+
cvFree( &mat->hashtable );
|
716
|
+
mat->hashtable = newtable;
|
717
|
+
mat->hashsize = newsize;
|
718
|
+
tabidx = hashval & (newsize - 1);
|
719
|
+
}
|
720
|
+
|
721
|
+
node = (CvSparseNode*)cvSetNew( mat->heap );
|
722
|
+
node->hashval = hashval;
|
723
|
+
node->next = (CvSparseNode*)mat->hashtable[tabidx];
|
724
|
+
mat->hashtable[tabidx] = node;
|
725
|
+
memcpy(CV_NODE_IDX(mat,node), idx, mat->dims*sizeof(idx[0]));
|
726
|
+
ptr = (uchar*)CV_NODE_VAL(mat,node);
|
727
|
+
if( create_node > 0 )
|
728
|
+
memset( ptr, 0, CV_ELEM_SIZE(mat->type));
|
729
|
+
}
|
730
|
+
|
731
|
+
if( _type )
|
732
|
+
*_type = CV_MAT_TYPE(mat->type);
|
733
|
+
|
734
|
+
return ptr;
|
735
|
+
}
|
736
|
+
|
737
|
+
|
738
|
+
static void
|
739
|
+
icvDeleteNode( CvSparseMat* mat, const int* idx, unsigned* precalc_hashval )
|
740
|
+
{
|
741
|
+
int i, tabidx;
|
742
|
+
unsigned hashval = 0;
|
743
|
+
CvSparseNode *node, *prev = 0;
|
744
|
+
assert( CV_IS_SPARSE_MAT( mat ));
|
745
|
+
|
746
|
+
if( !precalc_hashval )
|
747
|
+
{
|
748
|
+
for( i = 0; i < mat->dims; i++ )
|
749
|
+
{
|
750
|
+
int t = idx[i];
|
751
|
+
if( (unsigned)t >= (unsigned)mat->size[i] )
|
752
|
+
CV_Error( CV_StsOutOfRange, "One of indices is out of range" );
|
753
|
+
hashval = hashval*ICV_SPARSE_MAT_HASH_MULTIPLIER + t;
|
754
|
+
}
|
755
|
+
}
|
756
|
+
else
|
757
|
+
{
|
758
|
+
hashval = *precalc_hashval;
|
759
|
+
}
|
760
|
+
|
761
|
+
tabidx = hashval & (mat->hashsize - 1);
|
762
|
+
hashval &= INT_MAX;
|
763
|
+
|
764
|
+
for( node = (CvSparseNode*)mat->hashtable[tabidx];
|
765
|
+
node != 0; prev = node, node = node->next )
|
766
|
+
{
|
767
|
+
if( node->hashval == hashval )
|
768
|
+
{
|
769
|
+
int* nodeidx = CV_NODE_IDX(mat,node);
|
770
|
+
for( i = 0; i < mat->dims; i++ )
|
771
|
+
if( idx[i] != nodeidx[i] )
|
772
|
+
break;
|
773
|
+
if( i == mat->dims )
|
774
|
+
break;
|
775
|
+
}
|
776
|
+
}
|
777
|
+
|
778
|
+
if( node )
|
779
|
+
{
|
780
|
+
if( prev )
|
781
|
+
prev->next = node->next;
|
782
|
+
else
|
783
|
+
mat->hashtable[tabidx] = node->next;
|
784
|
+
cvSetRemoveByPtr( mat->heap, node );
|
785
|
+
}
|
786
|
+
}
|
787
|
+
|
788
|
+
|
789
|
+
/****************************************************************************************\
|
790
|
+
* Common for multiple array types operations *
|
791
|
+
\****************************************************************************************/
|
792
|
+
|
793
|
+
// Allocates underlying array data
|
794
|
+
CV_IMPL void
|
795
|
+
cvCreateData( CvArr* arr )
|
796
|
+
{
|
797
|
+
if( CV_IS_MAT_HDR_Z( arr ))
|
798
|
+
{
|
799
|
+
size_t step, total_size;
|
800
|
+
CvMat* mat = (CvMat*)arr;
|
801
|
+
step = mat->step;
|
802
|
+
|
803
|
+
if( mat->rows == 0 || mat->cols == 0 )
|
804
|
+
return;
|
805
|
+
|
806
|
+
if( mat->data.ptr != 0 )
|
807
|
+
CV_Error( CV_StsError, "Data is already allocated" );
|
808
|
+
|
809
|
+
if( step == 0 )
|
810
|
+
step = CV_ELEM_SIZE(mat->type)*mat->cols;
|
811
|
+
|
812
|
+
int64 _total_size = (int64)step*mat->rows + sizeof(int) + CV_MALLOC_ALIGN;
|
813
|
+
total_size = (size_t)_total_size;
|
814
|
+
if(_total_size != (int64)total_size)
|
815
|
+
CV_Error(CV_StsNoMem, "Too big buffer is allocated" );
|
816
|
+
mat->refcount = (int*)cvAlloc( (size_t)total_size );
|
817
|
+
mat->data.ptr = (uchar*)cvAlignPtr( mat->refcount + 1, CV_MALLOC_ALIGN );
|
818
|
+
*mat->refcount = 1;
|
819
|
+
}
|
820
|
+
else if( CV_IS_IMAGE_HDR(arr))
|
821
|
+
{
|
822
|
+
IplImage* img = (IplImage*)arr;
|
823
|
+
|
824
|
+
if( img->imageData != 0 )
|
825
|
+
CV_Error( CV_StsError, "Data is already allocated" );
|
826
|
+
|
827
|
+
if( !CvIPL.allocateData )
|
828
|
+
{
|
829
|
+
img->imageData = img->imageDataOrigin =
|
830
|
+
(char*)cvAlloc( (size_t)img->imageSize );
|
831
|
+
}
|
832
|
+
else
|
833
|
+
{
|
834
|
+
int depth = img->depth;
|
835
|
+
int width = img->width;
|
836
|
+
|
837
|
+
if( img->depth == IPL_DEPTH_32F || img->depth == IPL_DEPTH_64F )
|
838
|
+
{
|
839
|
+
img->width *= img->depth == IPL_DEPTH_32F ? sizeof(float) : sizeof(double);
|
840
|
+
img->depth = IPL_DEPTH_8U;
|
841
|
+
}
|
842
|
+
|
843
|
+
CvIPL.allocateData( img, 0, 0 );
|
844
|
+
|
845
|
+
img->width = width;
|
846
|
+
img->depth = depth;
|
847
|
+
}
|
848
|
+
}
|
849
|
+
else if( CV_IS_MATND_HDR( arr ))
|
850
|
+
{
|
851
|
+
CvMatND* mat = (CvMatND*)arr;
|
852
|
+
int i;
|
853
|
+
size_t total_size = CV_ELEM_SIZE(mat->type);
|
854
|
+
|
855
|
+
if( mat->dim[0].size == 0 )
|
856
|
+
return;
|
857
|
+
|
858
|
+
if( mat->data.ptr != 0 )
|
859
|
+
CV_Error( CV_StsError, "Data is already allocated" );
|
860
|
+
|
861
|
+
if( CV_IS_MAT_CONT( mat->type ))
|
862
|
+
{
|
863
|
+
total_size = (size_t)mat->dim[0].size*(mat->dim[0].step != 0 ?
|
864
|
+
mat->dim[0].step : total_size);
|
865
|
+
}
|
866
|
+
else
|
867
|
+
{
|
868
|
+
for( i = mat->dims - 1; i >= 0; i-- )
|
869
|
+
{
|
870
|
+
size_t size = (size_t)mat->dim[i].step*mat->dim[i].size;
|
871
|
+
|
872
|
+
if( total_size < size )
|
873
|
+
total_size = size;
|
874
|
+
}
|
875
|
+
}
|
876
|
+
|
877
|
+
mat->refcount = (int*)cvAlloc( total_size +
|
878
|
+
sizeof(int) + CV_MALLOC_ALIGN );
|
879
|
+
mat->data.ptr = (uchar*)cvAlignPtr( mat->refcount + 1, CV_MALLOC_ALIGN );
|
880
|
+
*mat->refcount = 1;
|
881
|
+
}
|
882
|
+
else
|
883
|
+
CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
|
884
|
+
}
|
885
|
+
|
886
|
+
|
887
|
+
// Assigns external data to array
|
888
|
+
CV_IMPL void
|
889
|
+
cvSetData( CvArr* arr, void* data, int step )
|
890
|
+
{
|
891
|
+
int pix_size, min_step;
|
892
|
+
|
893
|
+
if( CV_IS_MAT_HDR(arr) || CV_IS_MATND_HDR(arr) )
|
894
|
+
cvReleaseData( arr );
|
895
|
+
|
896
|
+
if( CV_IS_MAT_HDR( arr ))
|
897
|
+
{
|
898
|
+
CvMat* mat = (CvMat*)arr;
|
899
|
+
|
900
|
+
int type = CV_MAT_TYPE(mat->type);
|
901
|
+
pix_size = CV_ELEM_SIZE(type);
|
902
|
+
min_step = mat->cols*pix_size;
|
903
|
+
|
904
|
+
if( step != CV_AUTOSTEP && step != 0 )
|
905
|
+
{
|
906
|
+
if( step < min_step && data != 0 )
|
907
|
+
CV_Error( CV_BadStep, "" );
|
908
|
+
mat->step = step;
|
909
|
+
}
|
910
|
+
else
|
911
|
+
mat->step = min_step;
|
912
|
+
|
913
|
+
mat->data.ptr = (uchar*)data;
|
914
|
+
mat->type = CV_MAT_MAGIC_VAL | type |
|
915
|
+
(mat->rows == 1 || mat->step == min_step ? CV_MAT_CONT_FLAG : 0);
|
916
|
+
icvCheckHuge( mat );
|
917
|
+
}
|
918
|
+
else if( CV_IS_IMAGE_HDR( arr ))
|
919
|
+
{
|
920
|
+
IplImage* img = (IplImage*)arr;
|
921
|
+
|
922
|
+
pix_size = ((img->depth & 255) >> 3)*img->nChannels;
|
923
|
+
min_step = img->width*pix_size;
|
924
|
+
|
925
|
+
if( step != CV_AUTOSTEP && img->height > 1 )
|
926
|
+
{
|
927
|
+
if( step < min_step && data != 0 )
|
928
|
+
CV_Error( CV_BadStep, "" );
|
929
|
+
img->widthStep = step;
|
930
|
+
}
|
931
|
+
else
|
932
|
+
{
|
933
|
+
img->widthStep = min_step;
|
934
|
+
}
|
935
|
+
|
936
|
+
img->imageSize = img->widthStep * img->height;
|
937
|
+
img->imageData = img->imageDataOrigin = (char*)data;
|
938
|
+
|
939
|
+
if( (((int)(size_t)data | step) & 7) == 0 &&
|
940
|
+
cvAlign(img->width * pix_size, 8) == step )
|
941
|
+
img->align = 8;
|
942
|
+
else
|
943
|
+
img->align = 4;
|
944
|
+
}
|
945
|
+
else if( CV_IS_MATND_HDR( arr ))
|
946
|
+
{
|
947
|
+
CvMatND* mat = (CvMatND*)arr;
|
948
|
+
int i;
|
949
|
+
int64 cur_step;
|
950
|
+
|
951
|
+
if( step != CV_AUTOSTEP )
|
952
|
+
CV_Error( CV_BadStep,
|
953
|
+
"For multidimensional array only CV_AUTOSTEP is allowed here" );
|
954
|
+
|
955
|
+
mat->data.ptr = (uchar*)data;
|
956
|
+
cur_step = CV_ELEM_SIZE(mat->type);
|
957
|
+
|
958
|
+
for( i = mat->dims - 1; i >= 0; i-- )
|
959
|
+
{
|
960
|
+
if( cur_step > INT_MAX )
|
961
|
+
CV_Error( CV_StsOutOfRange, "The array is too big" );
|
962
|
+
mat->dim[i].step = (int)cur_step;
|
963
|
+
cur_step *= mat->dim[i].size;
|
964
|
+
}
|
965
|
+
}
|
966
|
+
else
|
967
|
+
CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
|
968
|
+
}
|
969
|
+
|
970
|
+
|
971
|
+
// Deallocates array's data
|
972
|
+
CV_IMPL void
|
973
|
+
cvReleaseData( CvArr* arr )
|
974
|
+
{
|
975
|
+
if( CV_IS_MAT_HDR( arr ) || CV_IS_MATND_HDR( arr ))
|
976
|
+
{
|
977
|
+
CvMat* mat = (CvMat*)arr;
|
978
|
+
cvDecRefData( mat );
|
979
|
+
}
|
980
|
+
else if( CV_IS_IMAGE_HDR( arr ))
|
981
|
+
{
|
982
|
+
IplImage* img = (IplImage*)arr;
|
983
|
+
|
984
|
+
if( !CvIPL.deallocate )
|
985
|
+
{
|
986
|
+
char* ptr = img->imageDataOrigin;
|
987
|
+
img->imageData = img->imageDataOrigin = 0;
|
988
|
+
cvFree( &ptr );
|
989
|
+
}
|
990
|
+
else
|
991
|
+
{
|
992
|
+
CvIPL.deallocate( img, IPL_IMAGE_DATA );
|
993
|
+
}
|
994
|
+
}
|
995
|
+
else
|
996
|
+
CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
|
997
|
+
}
|
998
|
+
|
999
|
+
|
1000
|
+
// Retrieves essential information about image ROI or CvMat data
|
1001
|
+
CV_IMPL void
|
1002
|
+
cvGetRawData( const CvArr* arr, uchar** data, int* step, CvSize* roi_size )
|
1003
|
+
{
|
1004
|
+
if( CV_IS_MAT( arr ))
|
1005
|
+
{
|
1006
|
+
CvMat *mat = (CvMat*)arr;
|
1007
|
+
|
1008
|
+
if( step )
|
1009
|
+
*step = mat->step;
|
1010
|
+
|
1011
|
+
if( data )
|
1012
|
+
*data = mat->data.ptr;
|
1013
|
+
|
1014
|
+
if( roi_size )
|
1015
|
+
*roi_size = cvGetMatSize( mat );
|
1016
|
+
}
|
1017
|
+
else if( CV_IS_IMAGE( arr ))
|
1018
|
+
{
|
1019
|
+
IplImage* img = (IplImage*)arr;
|
1020
|
+
|
1021
|
+
if( step )
|
1022
|
+
*step = img->widthStep;
|
1023
|
+
|
1024
|
+
if( data )
|
1025
|
+
*data = cvPtr2D( img, 0, 0 );
|
1026
|
+
|
1027
|
+
if( roi_size )
|
1028
|
+
{
|
1029
|
+
if( img->roi )
|
1030
|
+
{
|
1031
|
+
*roi_size = cvSize( img->roi->width, img->roi->height );
|
1032
|
+
}
|
1033
|
+
else
|
1034
|
+
{
|
1035
|
+
*roi_size = cvSize( img->width, img->height );
|
1036
|
+
}
|
1037
|
+
}
|
1038
|
+
}
|
1039
|
+
else if( CV_IS_MATND( arr ))
|
1040
|
+
{
|
1041
|
+
CvMatND* mat = (CvMatND*)arr;
|
1042
|
+
|
1043
|
+
if( !CV_IS_MAT_CONT( mat->type ))
|
1044
|
+
CV_Error( CV_StsBadArg, "Only continuous nD arrays are supported here" );
|
1045
|
+
|
1046
|
+
if( data )
|
1047
|
+
*data = mat->data.ptr;
|
1048
|
+
|
1049
|
+
if( roi_size || step )
|
1050
|
+
{
|
1051
|
+
int i, size1 = mat->dim[0].size, size2 = 1;
|
1052
|
+
|
1053
|
+
if( mat->dims > 2 )
|
1054
|
+
for( i = 1; i < mat->dims; i++ )
|
1055
|
+
size1 *= mat->dim[i].size;
|
1056
|
+
else
|
1057
|
+
size2 = mat->dim[1].size;
|
1058
|
+
|
1059
|
+
if( roi_size )
|
1060
|
+
{
|
1061
|
+
roi_size->width = size2;
|
1062
|
+
roi_size->height = size1;
|
1063
|
+
}
|
1064
|
+
|
1065
|
+
if( step )
|
1066
|
+
*step = mat->dim[0].step;
|
1067
|
+
}
|
1068
|
+
}
|
1069
|
+
else
|
1070
|
+
CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
|
1071
|
+
}
|
1072
|
+
|
1073
|
+
|
1074
|
+
CV_IMPL int
|
1075
|
+
cvGetElemType( const CvArr* arr )
|
1076
|
+
{
|
1077
|
+
int type = -1;
|
1078
|
+
if( CV_IS_MAT_HDR(arr) || CV_IS_MATND_HDR(arr) || CV_IS_SPARSE_MAT_HDR(arr))
|
1079
|
+
type = CV_MAT_TYPE( ((CvMat*)arr)->type );
|
1080
|
+
else if( CV_IS_IMAGE(arr))
|
1081
|
+
{
|
1082
|
+
IplImage* img = (IplImage*)arr;
|
1083
|
+
type = CV_MAKETYPE( IPL2CV_DEPTH(img->depth), img->nChannels );
|
1084
|
+
}
|
1085
|
+
else
|
1086
|
+
CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
|
1087
|
+
|
1088
|
+
return type;
|
1089
|
+
}
|
1090
|
+
|
1091
|
+
|
1092
|
+
// Returns a number of array dimensions
|
1093
|
+
CV_IMPL int
|
1094
|
+
cvGetDims( const CvArr* arr, int* sizes )
|
1095
|
+
{
|
1096
|
+
int dims = -1;
|
1097
|
+
if( CV_IS_MAT_HDR( arr ))
|
1098
|
+
{
|
1099
|
+
CvMat* mat = (CvMat*)arr;
|
1100
|
+
|
1101
|
+
dims = 2;
|
1102
|
+
if( sizes )
|
1103
|
+
{
|
1104
|
+
sizes[0] = mat->rows;
|
1105
|
+
sizes[1] = mat->cols;
|
1106
|
+
}
|
1107
|
+
}
|
1108
|
+
else if( CV_IS_IMAGE( arr ))
|
1109
|
+
{
|
1110
|
+
IplImage* img = (IplImage*)arr;
|
1111
|
+
dims = 2;
|
1112
|
+
|
1113
|
+
if( sizes )
|
1114
|
+
{
|
1115
|
+
sizes[0] = img->height;
|
1116
|
+
sizes[1] = img->width;
|
1117
|
+
}
|
1118
|
+
}
|
1119
|
+
else if( CV_IS_MATND_HDR( arr ))
|
1120
|
+
{
|
1121
|
+
CvMatND* mat = (CvMatND*)arr;
|
1122
|
+
dims = mat->dims;
|
1123
|
+
|
1124
|
+
if( sizes )
|
1125
|
+
{
|
1126
|
+
int i;
|
1127
|
+
for( i = 0; i < dims; i++ )
|
1128
|
+
sizes[i] = mat->dim[i].size;
|
1129
|
+
}
|
1130
|
+
}
|
1131
|
+
else if( CV_IS_SPARSE_MAT_HDR( arr ))
|
1132
|
+
{
|
1133
|
+
CvSparseMat* mat = (CvSparseMat*)arr;
|
1134
|
+
dims = mat->dims;
|
1135
|
+
|
1136
|
+
if( sizes )
|
1137
|
+
memcpy( sizes, mat->size, dims*sizeof(sizes[0]));
|
1138
|
+
}
|
1139
|
+
else
|
1140
|
+
CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
|
1141
|
+
|
1142
|
+
return dims;
|
1143
|
+
}
|
1144
|
+
|
1145
|
+
|
1146
|
+
// Returns the size of particular array dimension
|
1147
|
+
CV_IMPL int
|
1148
|
+
cvGetDimSize( const CvArr* arr, int index )
|
1149
|
+
{
|
1150
|
+
int size = -1;
|
1151
|
+
|
1152
|
+
if( CV_IS_MAT( arr ))
|
1153
|
+
{
|
1154
|
+
CvMat *mat = (CvMat*)arr;
|
1155
|
+
|
1156
|
+
switch( index )
|
1157
|
+
{
|
1158
|
+
case 0:
|
1159
|
+
size = mat->rows;
|
1160
|
+
break;
|
1161
|
+
case 1:
|
1162
|
+
size = mat->cols;
|
1163
|
+
break;
|
1164
|
+
default:
|
1165
|
+
CV_Error( CV_StsOutOfRange, "bad dimension index" );
|
1166
|
+
}
|
1167
|
+
}
|
1168
|
+
else if( CV_IS_IMAGE( arr ))
|
1169
|
+
{
|
1170
|
+
IplImage* img = (IplImage*)arr;
|
1171
|
+
|
1172
|
+
switch( index )
|
1173
|
+
{
|
1174
|
+
case 0:
|
1175
|
+
size = !img->roi ? img->height : img->roi->height;
|
1176
|
+
break;
|
1177
|
+
case 1:
|
1178
|
+
size = !img->roi ? img->width : img->roi->width;
|
1179
|
+
break;
|
1180
|
+
default:
|
1181
|
+
CV_Error( CV_StsOutOfRange, "bad dimension index" );
|
1182
|
+
}
|
1183
|
+
}
|
1184
|
+
else if( CV_IS_MATND_HDR( arr ))
|
1185
|
+
{
|
1186
|
+
CvMatND* mat = (CvMatND*)arr;
|
1187
|
+
|
1188
|
+
if( (unsigned)index >= (unsigned)mat->dims )
|
1189
|
+
CV_Error( CV_StsOutOfRange, "bad dimension index" );
|
1190
|
+
|
1191
|
+
size = mat->dim[index].size;
|
1192
|
+
}
|
1193
|
+
else if( CV_IS_SPARSE_MAT_HDR( arr ))
|
1194
|
+
{
|
1195
|
+
CvSparseMat* mat = (CvSparseMat*)arr;
|
1196
|
+
|
1197
|
+
if( (unsigned)index >= (unsigned)mat->dims )
|
1198
|
+
CV_Error( CV_StsOutOfRange, "bad dimension index" );
|
1199
|
+
|
1200
|
+
size = mat->size[index];
|
1201
|
+
}
|
1202
|
+
else
|
1203
|
+
CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
|
1204
|
+
|
1205
|
+
return size;
|
1206
|
+
}
|
1207
|
+
|
1208
|
+
|
1209
|
+
// Returns the size of CvMat or IplImage
|
1210
|
+
CV_IMPL CvSize
|
1211
|
+
cvGetSize( const CvArr* arr )
|
1212
|
+
{
|
1213
|
+
CvSize size = { 0, 0 };
|
1214
|
+
|
1215
|
+
if( CV_IS_MAT_HDR_Z( arr ))
|
1216
|
+
{
|
1217
|
+
CvMat *mat = (CvMat*)arr;
|
1218
|
+
|
1219
|
+
size.width = mat->cols;
|
1220
|
+
size.height = mat->rows;
|
1221
|
+
}
|
1222
|
+
else if( CV_IS_IMAGE_HDR( arr ))
|
1223
|
+
{
|
1224
|
+
IplImage* img = (IplImage*)arr;
|
1225
|
+
|
1226
|
+
if( img->roi )
|
1227
|
+
{
|
1228
|
+
size.width = img->roi->width;
|
1229
|
+
size.height = img->roi->height;
|
1230
|
+
}
|
1231
|
+
else
|
1232
|
+
{
|
1233
|
+
size.width = img->width;
|
1234
|
+
size.height = img->height;
|
1235
|
+
}
|
1236
|
+
}
|
1237
|
+
else
|
1238
|
+
CV_Error( CV_StsBadArg, "Array should be CvMat or IplImage" );
|
1239
|
+
|
1240
|
+
return size;
|
1241
|
+
}
|
1242
|
+
|
1243
|
+
|
1244
|
+
// Selects sub-array (no data is copied)
|
1245
|
+
CV_IMPL CvMat*
|
1246
|
+
cvGetSubRect( const CvArr* arr, CvMat* submat, CvRect rect )
|
1247
|
+
{
|
1248
|
+
CvMat* res = 0;
|
1249
|
+
CvMat stub, *mat = (CvMat*)arr;
|
1250
|
+
|
1251
|
+
if( !CV_IS_MAT( mat ))
|
1252
|
+
mat = cvGetMat( mat, &stub );
|
1253
|
+
|
1254
|
+
if( !submat )
|
1255
|
+
CV_Error( CV_StsNullPtr, "" );
|
1256
|
+
|
1257
|
+
if( (rect.x|rect.y|rect.width|rect.height) < 0 )
|
1258
|
+
CV_Error( CV_StsBadSize, "" );
|
1259
|
+
|
1260
|
+
if( rect.x + rect.width > mat->cols ||
|
1261
|
+
rect.y + rect.height > mat->rows )
|
1262
|
+
CV_Error( CV_StsBadSize, "" );
|
1263
|
+
|
1264
|
+
{
|
1265
|
+
/*
|
1266
|
+
int* refcount = mat->refcount;
|
1267
|
+
|
1268
|
+
if( refcount )
|
1269
|
+
++*refcount;
|
1270
|
+
|
1271
|
+
cvDecRefData( submat );
|
1272
|
+
*/
|
1273
|
+
submat->data.ptr = mat->data.ptr + (size_t)rect.y*mat->step +
|
1274
|
+
rect.x*CV_ELEM_SIZE(mat->type);
|
1275
|
+
submat->step = mat->step;
|
1276
|
+
submat->type = (mat->type & (rect.width < mat->cols ? ~CV_MAT_CONT_FLAG : -1)) |
|
1277
|
+
(rect.height <= 1 ? CV_MAT_CONT_FLAG : 0);
|
1278
|
+
submat->rows = rect.height;
|
1279
|
+
submat->cols = rect.width;
|
1280
|
+
submat->refcount = 0;
|
1281
|
+
res = submat;
|
1282
|
+
}
|
1283
|
+
|
1284
|
+
return res;
|
1285
|
+
}
|
1286
|
+
|
1287
|
+
|
1288
|
+
// Selects array's row span.
|
1289
|
+
CV_IMPL CvMat*
|
1290
|
+
cvGetRows( const CvArr* arr, CvMat* submat,
|
1291
|
+
int start_row, int end_row, int delta_row )
|
1292
|
+
{
|
1293
|
+
CvMat* res = 0;
|
1294
|
+
CvMat stub, *mat = (CvMat*)arr;
|
1295
|
+
|
1296
|
+
if( !CV_IS_MAT( mat ))
|
1297
|
+
mat = cvGetMat( mat, &stub );
|
1298
|
+
|
1299
|
+
if( !submat )
|
1300
|
+
CV_Error( CV_StsNullPtr, "" );
|
1301
|
+
|
1302
|
+
if( (unsigned)start_row >= (unsigned)mat->rows ||
|
1303
|
+
(unsigned)end_row > (unsigned)mat->rows || delta_row <= 0 )
|
1304
|
+
CV_Error( CV_StsOutOfRange, "" );
|
1305
|
+
|
1306
|
+
{
|
1307
|
+
/*
|
1308
|
+
int* refcount = mat->refcount;
|
1309
|
+
|
1310
|
+
if( refcount )
|
1311
|
+
++*refcount;
|
1312
|
+
|
1313
|
+
cvDecRefData( submat );
|
1314
|
+
*/
|
1315
|
+
if( delta_row == 1 )
|
1316
|
+
{
|
1317
|
+
submat->rows = end_row - start_row;
|
1318
|
+
submat->step = mat->step;
|
1319
|
+
}
|
1320
|
+
else
|
1321
|
+
{
|
1322
|
+
submat->rows = (end_row - start_row + delta_row - 1)/delta_row;
|
1323
|
+
submat->step = mat->step * delta_row;
|
1324
|
+
}
|
1325
|
+
|
1326
|
+
submat->cols = mat->cols;
|
1327
|
+
submat->step &= submat->rows > 1 ? -1 : 0;
|
1328
|
+
submat->data.ptr = mat->data.ptr + (size_t)start_row*mat->step;
|
1329
|
+
submat->type = (mat->type | (submat->rows == 1 ? CV_MAT_CONT_FLAG : 0)) &
|
1330
|
+
(delta_row != 1 && submat->rows > 1 ? ~CV_MAT_CONT_FLAG : -1);
|
1331
|
+
submat->refcount = 0;
|
1332
|
+
submat->hdr_refcount = 0;
|
1333
|
+
res = submat;
|
1334
|
+
}
|
1335
|
+
|
1336
|
+
return res;
|
1337
|
+
}
|
1338
|
+
|
1339
|
+
|
1340
|
+
// Selects array's column span.
|
1341
|
+
CV_IMPL CvMat*
|
1342
|
+
cvGetCols( const CvArr* arr, CvMat* submat, int start_col, int end_col )
|
1343
|
+
{
|
1344
|
+
CvMat* res = 0;
|
1345
|
+
CvMat stub, *mat = (CvMat*)arr;
|
1346
|
+
int cols;
|
1347
|
+
|
1348
|
+
if( !CV_IS_MAT( mat ))
|
1349
|
+
mat = cvGetMat( mat, &stub );
|
1350
|
+
|
1351
|
+
if( !submat )
|
1352
|
+
CV_Error( CV_StsNullPtr, "" );
|
1353
|
+
|
1354
|
+
cols = mat->cols;
|
1355
|
+
if( (unsigned)start_col >= (unsigned)cols ||
|
1356
|
+
(unsigned)end_col > (unsigned)cols )
|
1357
|
+
CV_Error( CV_StsOutOfRange, "" );
|
1358
|
+
|
1359
|
+
{
|
1360
|
+
/*
|
1361
|
+
int* refcount = mat->refcount;
|
1362
|
+
|
1363
|
+
if( refcount )
|
1364
|
+
++*refcount;
|
1365
|
+
|
1366
|
+
cvDecRefData( submat );
|
1367
|
+
*/
|
1368
|
+
submat->rows = mat->rows;
|
1369
|
+
submat->cols = end_col - start_col;
|
1370
|
+
submat->step = mat->step;
|
1371
|
+
submat->data.ptr = mat->data.ptr + (size_t)start_col*CV_ELEM_SIZE(mat->type);
|
1372
|
+
submat->type = mat->type & (submat->rows > 1 && submat->cols < cols ? ~CV_MAT_CONT_FLAG : -1);
|
1373
|
+
submat->refcount = 0;
|
1374
|
+
submat->hdr_refcount = 0;
|
1375
|
+
res = submat;
|
1376
|
+
}
|
1377
|
+
|
1378
|
+
return res;
|
1379
|
+
}
|
1380
|
+
|
1381
|
+
|
1382
|
+
// Selects array diagonal
|
1383
|
+
CV_IMPL CvMat*
|
1384
|
+
cvGetDiag( const CvArr* arr, CvMat* submat, int diag )
|
1385
|
+
{
|
1386
|
+
CvMat* res = 0;
|
1387
|
+
CvMat stub, *mat = (CvMat*)arr;
|
1388
|
+
int len, pix_size;
|
1389
|
+
|
1390
|
+
if( !CV_IS_MAT( mat ))
|
1391
|
+
mat = cvGetMat( mat, &stub );
|
1392
|
+
|
1393
|
+
if( !submat )
|
1394
|
+
CV_Error( CV_StsNullPtr, "" );
|
1395
|
+
|
1396
|
+
pix_size = CV_ELEM_SIZE(mat->type);
|
1397
|
+
|
1398
|
+
/*{
|
1399
|
+
int* refcount = mat->refcount;
|
1400
|
+
|
1401
|
+
if( refcount )
|
1402
|
+
++*refcount;
|
1403
|
+
|
1404
|
+
cvDecRefData( submat );
|
1405
|
+
}*/
|
1406
|
+
|
1407
|
+
if( diag >= 0 )
|
1408
|
+
{
|
1409
|
+
len = mat->cols - diag;
|
1410
|
+
|
1411
|
+
if( len <= 0 )
|
1412
|
+
CV_Error( CV_StsOutOfRange, "" );
|
1413
|
+
|
1414
|
+
len = CV_IMIN( len, mat->rows );
|
1415
|
+
submat->data.ptr = mat->data.ptr + diag*pix_size;
|
1416
|
+
}
|
1417
|
+
else
|
1418
|
+
{
|
1419
|
+
len = mat->rows + diag;
|
1420
|
+
|
1421
|
+
if( len <= 0 )
|
1422
|
+
CV_Error( CV_StsOutOfRange, "" );
|
1423
|
+
|
1424
|
+
len = CV_IMIN( len, mat->cols );
|
1425
|
+
submat->data.ptr = mat->data.ptr - diag*mat->step;
|
1426
|
+
}
|
1427
|
+
|
1428
|
+
submat->rows = len;
|
1429
|
+
submat->cols = 1;
|
1430
|
+
submat->step = mat->step + (submat->rows > 1 ? pix_size : 0);
|
1431
|
+
submat->type = mat->type;
|
1432
|
+
if( submat->rows > 1 )
|
1433
|
+
submat->type &= ~CV_MAT_CONT_FLAG;
|
1434
|
+
else
|
1435
|
+
submat->type |= CV_MAT_CONT_FLAG;
|
1436
|
+
submat->refcount = 0;
|
1437
|
+
submat->hdr_refcount = 0;
|
1438
|
+
res = submat;
|
1439
|
+
|
1440
|
+
return res;
|
1441
|
+
}
|
1442
|
+
|
1443
|
+
|
1444
|
+
/****************************************************************************************\
|
1445
|
+
* Operations on CvScalar and accessing array elements *
|
1446
|
+
\****************************************************************************************/
|
1447
|
+
|
1448
|
+
// Converts CvScalar to specified type
|
1449
|
+
CV_IMPL void
|
1450
|
+
cvScalarToRawData( const CvScalar* scalar, void* data, int type, int extend_to_12 )
|
1451
|
+
{
|
1452
|
+
type = CV_MAT_TYPE(type);
|
1453
|
+
int cn = CV_MAT_CN( type );
|
1454
|
+
int depth = type & CV_MAT_DEPTH_MASK;
|
1455
|
+
|
1456
|
+
assert( scalar && data );
|
1457
|
+
if( (unsigned)(cn - 1) >= 4 )
|
1458
|
+
CV_Error( CV_StsOutOfRange, "The number of channels must be 1, 2, 3 or 4" );
|
1459
|
+
|
1460
|
+
switch( depth )
|
1461
|
+
{
|
1462
|
+
case CV_8UC1:
|
1463
|
+
while( cn-- )
|
1464
|
+
{
|
1465
|
+
int t = cvRound( scalar->val[cn] );
|
1466
|
+
((uchar*)data)[cn] = CV_CAST_8U(t);
|
1467
|
+
}
|
1468
|
+
break;
|
1469
|
+
case CV_8SC1:
|
1470
|
+
while( cn-- )
|
1471
|
+
{
|
1472
|
+
int t = cvRound( scalar->val[cn] );
|
1473
|
+
((char*)data)[cn] = CV_CAST_8S(t);
|
1474
|
+
}
|
1475
|
+
break;
|
1476
|
+
case CV_16UC1:
|
1477
|
+
while( cn-- )
|
1478
|
+
{
|
1479
|
+
int t = cvRound( scalar->val[cn] );
|
1480
|
+
((ushort*)data)[cn] = CV_CAST_16U(t);
|
1481
|
+
}
|
1482
|
+
break;
|
1483
|
+
case CV_16SC1:
|
1484
|
+
while( cn-- )
|
1485
|
+
{
|
1486
|
+
int t = cvRound( scalar->val[cn] );
|
1487
|
+
((short*)data)[cn] = CV_CAST_16S(t);
|
1488
|
+
}
|
1489
|
+
break;
|
1490
|
+
case CV_32SC1:
|
1491
|
+
while( cn-- )
|
1492
|
+
((int*)data)[cn] = cvRound( scalar->val[cn] );
|
1493
|
+
break;
|
1494
|
+
case CV_32FC1:
|
1495
|
+
while( cn-- )
|
1496
|
+
((float*)data)[cn] = (float)(scalar->val[cn]);
|
1497
|
+
break;
|
1498
|
+
case CV_64FC1:
|
1499
|
+
while( cn-- )
|
1500
|
+
((double*)data)[cn] = (double)(scalar->val[cn]);
|
1501
|
+
break;
|
1502
|
+
default:
|
1503
|
+
assert(0);
|
1504
|
+
CV_Error( CV_BadDepth, "" );
|
1505
|
+
}
|
1506
|
+
|
1507
|
+
if( extend_to_12 )
|
1508
|
+
{
|
1509
|
+
int pix_size = CV_ELEM_SIZE(type);
|
1510
|
+
int offset = CV_ELEM_SIZE1(depth)*12;
|
1511
|
+
|
1512
|
+
do
|
1513
|
+
{
|
1514
|
+
offset -= pix_size;
|
1515
|
+
memcpy((char*)data + offset, data, pix_size);
|
1516
|
+
}
|
1517
|
+
while( offset > pix_size );
|
1518
|
+
}
|
1519
|
+
}
|
1520
|
+
|
1521
|
+
|
1522
|
+
// Converts data of specified type to CvScalar
|
1523
|
+
CV_IMPL void
|
1524
|
+
cvRawDataToScalar( const void* data, int flags, CvScalar* scalar )
|
1525
|
+
{
|
1526
|
+
int cn = CV_MAT_CN( flags );
|
1527
|
+
|
1528
|
+
assert( scalar && data );
|
1529
|
+
|
1530
|
+
if( (unsigned)(cn - 1) >= 4 )
|
1531
|
+
CV_Error( CV_StsOutOfRange, "The number of channels must be 1, 2, 3 or 4" );
|
1532
|
+
|
1533
|
+
memset( scalar->val, 0, sizeof(scalar->val));
|
1534
|
+
|
1535
|
+
switch( CV_MAT_DEPTH( flags ))
|
1536
|
+
{
|
1537
|
+
case CV_8U:
|
1538
|
+
while( cn-- )
|
1539
|
+
scalar->val[cn] = CV_8TO32F(((uchar*)data)[cn]);
|
1540
|
+
break;
|
1541
|
+
case CV_8S:
|
1542
|
+
while( cn-- )
|
1543
|
+
scalar->val[cn] = CV_8TO32F(((char*)data)[cn]);
|
1544
|
+
break;
|
1545
|
+
case CV_16U:
|
1546
|
+
while( cn-- )
|
1547
|
+
scalar->val[cn] = ((ushort*)data)[cn];
|
1548
|
+
break;
|
1549
|
+
case CV_16S:
|
1550
|
+
while( cn-- )
|
1551
|
+
scalar->val[cn] = ((short*)data)[cn];
|
1552
|
+
break;
|
1553
|
+
case CV_32S:
|
1554
|
+
while( cn-- )
|
1555
|
+
scalar->val[cn] = ((int*)data)[cn];
|
1556
|
+
break;
|
1557
|
+
case CV_32F:
|
1558
|
+
while( cn-- )
|
1559
|
+
scalar->val[cn] = ((float*)data)[cn];
|
1560
|
+
break;
|
1561
|
+
case CV_64F:
|
1562
|
+
while( cn-- )
|
1563
|
+
scalar->val[cn] = ((double*)data)[cn];
|
1564
|
+
break;
|
1565
|
+
default:
|
1566
|
+
assert(0);
|
1567
|
+
CV_Error( CV_BadDepth, "" );
|
1568
|
+
}
|
1569
|
+
}
|
1570
|
+
|
1571
|
+
|
1572
|
+
static double icvGetReal( const void* data, int type )
|
1573
|
+
{
|
1574
|
+
switch( type )
|
1575
|
+
{
|
1576
|
+
case CV_8U:
|
1577
|
+
return *(uchar*)data;
|
1578
|
+
case CV_8S:
|
1579
|
+
return *(char*)data;
|
1580
|
+
case CV_16U:
|
1581
|
+
return *(ushort*)data;
|
1582
|
+
case CV_16S:
|
1583
|
+
return *(short*)data;
|
1584
|
+
case CV_32S:
|
1585
|
+
return *(int*)data;
|
1586
|
+
case CV_32F:
|
1587
|
+
return *(float*)data;
|
1588
|
+
case CV_64F:
|
1589
|
+
return *(double*)data;
|
1590
|
+
}
|
1591
|
+
|
1592
|
+
return 0;
|
1593
|
+
}
|
1594
|
+
|
1595
|
+
|
1596
|
+
static void icvSetReal( double value, const void* data, int type )
|
1597
|
+
{
|
1598
|
+
if( type < CV_32F )
|
1599
|
+
{
|
1600
|
+
int ivalue = cvRound(value);
|
1601
|
+
switch( type )
|
1602
|
+
{
|
1603
|
+
case CV_8U:
|
1604
|
+
*(uchar*)data = CV_CAST_8U(ivalue);
|
1605
|
+
break;
|
1606
|
+
case CV_8S:
|
1607
|
+
*(char*)data = CV_CAST_8S(ivalue);
|
1608
|
+
break;
|
1609
|
+
case CV_16U:
|
1610
|
+
*(ushort*)data = CV_CAST_16U(ivalue);
|
1611
|
+
break;
|
1612
|
+
case CV_16S:
|
1613
|
+
*(short*)data = CV_CAST_16S(ivalue);
|
1614
|
+
break;
|
1615
|
+
case CV_32S:
|
1616
|
+
*(int*)data = CV_CAST_32S(ivalue);
|
1617
|
+
break;
|
1618
|
+
}
|
1619
|
+
}
|
1620
|
+
else
|
1621
|
+
{
|
1622
|
+
switch( type )
|
1623
|
+
{
|
1624
|
+
case CV_32F:
|
1625
|
+
*(float*)data = (float)value;
|
1626
|
+
break;
|
1627
|
+
case CV_64F:
|
1628
|
+
*(double*)data = value;
|
1629
|
+
break;
|
1630
|
+
}
|
1631
|
+
}
|
1632
|
+
}
|
1633
|
+
|
1634
|
+
|
1635
|
+
// Returns pointer to specified element of array (linear index is used)
|
1636
|
+
CV_IMPL uchar*
|
1637
|
+
cvPtr1D( const CvArr* arr, int idx, int* _type )
|
1638
|
+
{
|
1639
|
+
uchar* ptr = 0;
|
1640
|
+
if( CV_IS_MAT( arr ))
|
1641
|
+
{
|
1642
|
+
CvMat* mat = (CvMat*)arr;
|
1643
|
+
|
1644
|
+
int type = CV_MAT_TYPE(mat->type);
|
1645
|
+
int pix_size = CV_ELEM_SIZE(type);
|
1646
|
+
|
1647
|
+
if( _type )
|
1648
|
+
*_type = type;
|
1649
|
+
|
1650
|
+
// the first part is mul-free sufficient check
|
1651
|
+
// that the index is within the matrix
|
1652
|
+
if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) &&
|
1653
|
+
(unsigned)idx >= (unsigned)(mat->rows*mat->cols))
|
1654
|
+
CV_Error( CV_StsOutOfRange, "index is out of range" );
|
1655
|
+
|
1656
|
+
if( CV_IS_MAT_CONT(mat->type))
|
1657
|
+
{
|
1658
|
+
ptr = mat->data.ptr + (size_t)idx*pix_size;
|
1659
|
+
}
|
1660
|
+
else
|
1661
|
+
{
|
1662
|
+
int row, col;
|
1663
|
+
if( mat->cols == 1 )
|
1664
|
+
row = idx, col = 0;
|
1665
|
+
else
|
1666
|
+
row = idx/mat->cols, col = idx - row*mat->cols;
|
1667
|
+
ptr = mat->data.ptr + (size_t)row*mat->step + col*pix_size;
|
1668
|
+
}
|
1669
|
+
}
|
1670
|
+
else if( CV_IS_IMAGE_HDR( arr ))
|
1671
|
+
{
|
1672
|
+
IplImage* img = (IplImage*)arr;
|
1673
|
+
int width = !img->roi ? img->width : img->roi->width;
|
1674
|
+
int y = idx/width, x = idx - y*width;
|
1675
|
+
|
1676
|
+
ptr = cvPtr2D( arr, y, x, _type );
|
1677
|
+
}
|
1678
|
+
else if( CV_IS_MATND( arr ))
|
1679
|
+
{
|
1680
|
+
CvMatND* mat = (CvMatND*)arr;
|
1681
|
+
int j, type = CV_MAT_TYPE(mat->type);
|
1682
|
+
size_t size = mat->dim[0].size;
|
1683
|
+
|
1684
|
+
if( _type )
|
1685
|
+
*_type = type;
|
1686
|
+
|
1687
|
+
for( j = 1; j < mat->dims; j++ )
|
1688
|
+
size *= mat->dim[j].size;
|
1689
|
+
|
1690
|
+
if((unsigned)idx >= (unsigned)size )
|
1691
|
+
CV_Error( CV_StsOutOfRange, "index is out of range" );
|
1692
|
+
|
1693
|
+
if( CV_IS_MAT_CONT(mat->type))
|
1694
|
+
{
|
1695
|
+
int pix_size = CV_ELEM_SIZE(type);
|
1696
|
+
ptr = mat->data.ptr + (size_t)idx*pix_size;
|
1697
|
+
}
|
1698
|
+
else
|
1699
|
+
{
|
1700
|
+
ptr = mat->data.ptr;
|
1701
|
+
for( j = mat->dims - 1; j >= 0; j-- )
|
1702
|
+
{
|
1703
|
+
int sz = mat->dim[j].size;
|
1704
|
+
if( sz )
|
1705
|
+
{
|
1706
|
+
int t = idx/sz;
|
1707
|
+
ptr += (idx - t*sz)*mat->dim[j].step;
|
1708
|
+
idx = t;
|
1709
|
+
}
|
1710
|
+
}
|
1711
|
+
}
|
1712
|
+
}
|
1713
|
+
else if( CV_IS_SPARSE_MAT( arr ))
|
1714
|
+
{
|
1715
|
+
CvSparseMat* m = (CvSparseMat*)arr;
|
1716
|
+
if( m->dims == 1 )
|
1717
|
+
ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, _type, 1, 0 );
|
1718
|
+
else
|
1719
|
+
{
|
1720
|
+
int i, n = m->dims;
|
1721
|
+
CV_DbgAssert( n <= CV_MAX_DIM_HEAP );
|
1722
|
+
int _idx[CV_MAX_DIM_HEAP];
|
1723
|
+
|
1724
|
+
for( i = n - 1; i >= 0; i-- )
|
1725
|
+
{
|
1726
|
+
int t = idx / m->size[i];
|
1727
|
+
_idx[i] = idx - t*m->size[i];
|
1728
|
+
idx = t;
|
1729
|
+
}
|
1730
|
+
ptr = icvGetNodePtr( (CvSparseMat*)arr, _idx, _type, 1, 0 );
|
1731
|
+
}
|
1732
|
+
}
|
1733
|
+
else
|
1734
|
+
{
|
1735
|
+
CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
|
1736
|
+
}
|
1737
|
+
|
1738
|
+
return ptr;
|
1739
|
+
}
|
1740
|
+
|
1741
|
+
|
1742
|
+
// Returns pointer to specified element of 2d array
|
1743
|
+
CV_IMPL uchar*
|
1744
|
+
cvPtr2D( const CvArr* arr, int y, int x, int* _type )
|
1745
|
+
{
|
1746
|
+
uchar* ptr = 0;
|
1747
|
+
if( CV_IS_MAT( arr ))
|
1748
|
+
{
|
1749
|
+
CvMat* mat = (CvMat*)arr;
|
1750
|
+
int type;
|
1751
|
+
|
1752
|
+
if( (unsigned)y >= (unsigned)(mat->rows) ||
|
1753
|
+
(unsigned)x >= (unsigned)(mat->cols) )
|
1754
|
+
CV_Error( CV_StsOutOfRange, "index is out of range" );
|
1755
|
+
|
1756
|
+
type = CV_MAT_TYPE(mat->type);
|
1757
|
+
if( _type )
|
1758
|
+
*_type = type;
|
1759
|
+
|
1760
|
+
ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type);
|
1761
|
+
}
|
1762
|
+
else if( CV_IS_IMAGE( arr ))
|
1763
|
+
{
|
1764
|
+
IplImage* img = (IplImage*)arr;
|
1765
|
+
int pix_size = (img->depth & 255) >> 3;
|
1766
|
+
int width, height;
|
1767
|
+
ptr = (uchar*)img->imageData;
|
1768
|
+
|
1769
|
+
if( img->dataOrder == 0 )
|
1770
|
+
pix_size *= img->nChannels;
|
1771
|
+
|
1772
|
+
if( img->roi )
|
1773
|
+
{
|
1774
|
+
width = img->roi->width;
|
1775
|
+
height = img->roi->height;
|
1776
|
+
|
1777
|
+
ptr += img->roi->yOffset*img->widthStep +
|
1778
|
+
img->roi->xOffset*pix_size;
|
1779
|
+
|
1780
|
+
if( img->dataOrder )
|
1781
|
+
{
|
1782
|
+
int coi = img->roi->coi;
|
1783
|
+
if( !coi )
|
1784
|
+
CV_Error( CV_BadCOI,
|
1785
|
+
"COI must be non-null in case of planar images" );
|
1786
|
+
ptr += (coi - 1)*img->imageSize;
|
1787
|
+
}
|
1788
|
+
}
|
1789
|
+
else
|
1790
|
+
{
|
1791
|
+
width = img->width;
|
1792
|
+
height = img->height;
|
1793
|
+
}
|
1794
|
+
|
1795
|
+
if( (unsigned)y >= (unsigned)height ||
|
1796
|
+
(unsigned)x >= (unsigned)width )
|
1797
|
+
CV_Error( CV_StsOutOfRange, "index is out of range" );
|
1798
|
+
|
1799
|
+
ptr += y*img->widthStep + x*pix_size;
|
1800
|
+
|
1801
|
+
if( _type )
|
1802
|
+
{
|
1803
|
+
int type = IPL2CV_DEPTH(img->depth);
|
1804
|
+
if( type < 0 || (unsigned)(img->nChannels - 1) > 3 )
|
1805
|
+
CV_Error( CV_StsUnsupportedFormat, "" );
|
1806
|
+
|
1807
|
+
*_type = CV_MAKETYPE( type, img->nChannels );
|
1808
|
+
}
|
1809
|
+
}
|
1810
|
+
else if( CV_IS_MATND( arr ))
|
1811
|
+
{
|
1812
|
+
CvMatND* mat = (CvMatND*)arr;
|
1813
|
+
|
1814
|
+
if( mat->dims != 2 ||
|
1815
|
+
(unsigned)y >= (unsigned)(mat->dim[0].size) ||
|
1816
|
+
(unsigned)x >= (unsigned)(mat->dim[1].size) )
|
1817
|
+
CV_Error( CV_StsOutOfRange, "index is out of range" );
|
1818
|
+
|
1819
|
+
ptr = mat->data.ptr + (size_t)y*mat->dim[0].step + x*mat->dim[1].step;
|
1820
|
+
if( _type )
|
1821
|
+
*_type = CV_MAT_TYPE(mat->type);
|
1822
|
+
}
|
1823
|
+
else if( CV_IS_SPARSE_MAT( arr ))
|
1824
|
+
{
|
1825
|
+
int idx[] = { y, x };
|
1826
|
+
ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, _type, 1, 0 );
|
1827
|
+
}
|
1828
|
+
else
|
1829
|
+
{
|
1830
|
+
CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
|
1831
|
+
}
|
1832
|
+
|
1833
|
+
return ptr;
|
1834
|
+
}
|
1835
|
+
|
1836
|
+
|
1837
|
+
// Returns pointer to specified element of 3d array
|
1838
|
+
CV_IMPL uchar*
|
1839
|
+
cvPtr3D( const CvArr* arr, int z, int y, int x, int* _type )
|
1840
|
+
{
|
1841
|
+
uchar* ptr = 0;
|
1842
|
+
if( CV_IS_MATND( arr ))
|
1843
|
+
{
|
1844
|
+
CvMatND* mat = (CvMatND*)arr;
|
1845
|
+
|
1846
|
+
if( mat->dims != 3 ||
|
1847
|
+
(unsigned)z >= (unsigned)(mat->dim[0].size) ||
|
1848
|
+
(unsigned)y >= (unsigned)(mat->dim[1].size) ||
|
1849
|
+
(unsigned)x >= (unsigned)(mat->dim[2].size) )
|
1850
|
+
CV_Error( CV_StsOutOfRange, "index is out of range" );
|
1851
|
+
|
1852
|
+
ptr = mat->data.ptr + (size_t)z*mat->dim[0].step +
|
1853
|
+
(size_t)y*mat->dim[1].step + x*mat->dim[2].step;
|
1854
|
+
|
1855
|
+
if( _type )
|
1856
|
+
*_type = CV_MAT_TYPE(mat->type);
|
1857
|
+
}
|
1858
|
+
else if( CV_IS_SPARSE_MAT( arr ))
|
1859
|
+
{
|
1860
|
+
int idx[] = { z, y, x };
|
1861
|
+
ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, _type, 1, 0 );
|
1862
|
+
}
|
1863
|
+
else
|
1864
|
+
{
|
1865
|
+
CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
|
1866
|
+
}
|
1867
|
+
|
1868
|
+
return ptr;
|
1869
|
+
}
|
1870
|
+
|
1871
|
+
|
1872
|
+
// Returns pointer to specified element of n-d array
|
1873
|
+
CV_IMPL uchar*
|
1874
|
+
cvPtrND( const CvArr* arr, const int* idx, int* _type,
|
1875
|
+
int create_node, unsigned* precalc_hashval )
|
1876
|
+
{
|
1877
|
+
uchar* ptr = 0;
|
1878
|
+
if( !idx )
|
1879
|
+
CV_Error( CV_StsNullPtr, "NULL pointer to indices" );
|
1880
|
+
|
1881
|
+
if( CV_IS_SPARSE_MAT( arr ))
|
1882
|
+
ptr = icvGetNodePtr( (CvSparseMat*)arr, idx,
|
1883
|
+
_type, create_node, precalc_hashval );
|
1884
|
+
else if( CV_IS_MATND( arr ))
|
1885
|
+
{
|
1886
|
+
CvMatND* mat = (CvMatND*)arr;
|
1887
|
+
int i;
|
1888
|
+
ptr = mat->data.ptr;
|
1889
|
+
|
1890
|
+
for( i = 0; i < mat->dims; i++ )
|
1891
|
+
{
|
1892
|
+
if( (unsigned)idx[i] >= (unsigned)(mat->dim[i].size) )
|
1893
|
+
CV_Error( CV_StsOutOfRange, "index is out of range" );
|
1894
|
+
ptr += (size_t)idx[i]*mat->dim[i].step;
|
1895
|
+
}
|
1896
|
+
|
1897
|
+
if( _type )
|
1898
|
+
*_type = CV_MAT_TYPE(mat->type);
|
1899
|
+
}
|
1900
|
+
else if( CV_IS_MAT_HDR(arr) || CV_IS_IMAGE_HDR(arr) )
|
1901
|
+
ptr = cvPtr2D( arr, idx[0], idx[1], _type );
|
1902
|
+
else
|
1903
|
+
CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
|
1904
|
+
|
1905
|
+
return ptr;
|
1906
|
+
}
|
1907
|
+
|
1908
|
+
|
1909
|
+
// Returns specifed element of n-D array given linear index
|
1910
|
+
CV_IMPL CvScalar
|
1911
|
+
cvGet1D( const CvArr* arr, int idx )
|
1912
|
+
{
|
1913
|
+
CvScalar scalar = {{0,0,0,0}};
|
1914
|
+
int type = 0;
|
1915
|
+
uchar* ptr;
|
1916
|
+
|
1917
|
+
if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type ))
|
1918
|
+
{
|
1919
|
+
CvMat* mat = (CvMat*)arr;
|
1920
|
+
|
1921
|
+
type = CV_MAT_TYPE(mat->type);
|
1922
|
+
int pix_size = CV_ELEM_SIZE(type);
|
1923
|
+
|
1924
|
+
// the first part is mul-free sufficient check
|
1925
|
+
// that the index is within the matrix
|
1926
|
+
if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) &&
|
1927
|
+
(unsigned)idx >= (unsigned)(mat->rows*mat->cols))
|
1928
|
+
CV_Error( CV_StsOutOfRange, "index is out of range" );
|
1929
|
+
|
1930
|
+
ptr = mat->data.ptr + (size_t)idx*pix_size;
|
1931
|
+
}
|
1932
|
+
else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 )
|
1933
|
+
ptr = cvPtr1D( arr, idx, &type );
|
1934
|
+
else
|
1935
|
+
ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, 0, 0 );
|
1936
|
+
|
1937
|
+
if( ptr )
|
1938
|
+
cvRawDataToScalar( ptr, type, &scalar );
|
1939
|
+
|
1940
|
+
return scalar;
|
1941
|
+
}
|
1942
|
+
|
1943
|
+
|
1944
|
+
// Returns specifed element of 2D array
|
1945
|
+
CV_IMPL CvScalar
|
1946
|
+
cvGet2D( const CvArr* arr, int y, int x )
|
1947
|
+
{
|
1948
|
+
CvScalar scalar = {{0,0,0,0}};
|
1949
|
+
int type = 0;
|
1950
|
+
uchar* ptr;
|
1951
|
+
|
1952
|
+
if( CV_IS_MAT( arr ))
|
1953
|
+
{
|
1954
|
+
CvMat* mat = (CvMat*)arr;
|
1955
|
+
|
1956
|
+
if( (unsigned)y >= (unsigned)(mat->rows) ||
|
1957
|
+
(unsigned)x >= (unsigned)(mat->cols) )
|
1958
|
+
CV_Error( CV_StsOutOfRange, "index is out of range" );
|
1959
|
+
|
1960
|
+
type = CV_MAT_TYPE(mat->type);
|
1961
|
+
ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type);
|
1962
|
+
}
|
1963
|
+
else if( !CV_IS_SPARSE_MAT( arr ))
|
1964
|
+
ptr = cvPtr2D( arr, y, x, &type );
|
1965
|
+
else
|
1966
|
+
{
|
1967
|
+
int idx[] = { y, x };
|
1968
|
+
ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
|
1969
|
+
}
|
1970
|
+
|
1971
|
+
if( ptr )
|
1972
|
+
cvRawDataToScalar( ptr, type, &scalar );
|
1973
|
+
|
1974
|
+
return scalar;
|
1975
|
+
}
|
1976
|
+
|
1977
|
+
|
1978
|
+
// Returns specifed element of 3D array
|
1979
|
+
CV_IMPL CvScalar
|
1980
|
+
cvGet3D( const CvArr* arr, int z, int y, int x )
|
1981
|
+
{
|
1982
|
+
CvScalar scalar = {{0,0,0,0}};
|
1983
|
+
int type = 0;
|
1984
|
+
uchar* ptr;
|
1985
|
+
|
1986
|
+
if( !CV_IS_SPARSE_MAT( arr ))
|
1987
|
+
ptr = cvPtr3D( arr, z, y, x, &type );
|
1988
|
+
else
|
1989
|
+
{
|
1990
|
+
int idx[] = { z, y, x };
|
1991
|
+
ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
|
1992
|
+
}
|
1993
|
+
|
1994
|
+
if( ptr )
|
1995
|
+
cvRawDataToScalar( ptr, type, &scalar );
|
1996
|
+
return scalar;
|
1997
|
+
}
|
1998
|
+
|
1999
|
+
|
2000
|
+
// Returns specifed element of nD array
|
2001
|
+
CV_IMPL CvScalar
|
2002
|
+
cvGetND( const CvArr* arr, const int* idx )
|
2003
|
+
{
|
2004
|
+
CvScalar scalar = {{0,0,0,0}};
|
2005
|
+
int type = 0;
|
2006
|
+
uchar* ptr;
|
2007
|
+
|
2008
|
+
if( !CV_IS_SPARSE_MAT( arr ))
|
2009
|
+
ptr = cvPtrND( arr, idx, &type );
|
2010
|
+
else
|
2011
|
+
ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
|
2012
|
+
|
2013
|
+
if( ptr )
|
2014
|
+
cvRawDataToScalar( ptr, type, &scalar );
|
2015
|
+
|
2016
|
+
return scalar;
|
2017
|
+
}
|
2018
|
+
|
2019
|
+
|
2020
|
+
// Returns specifed element of n-D array given linear index
|
2021
|
+
CV_IMPL double
|
2022
|
+
cvGetReal1D( const CvArr* arr, int idx )
|
2023
|
+
{
|
2024
|
+
double value = 0;
|
2025
|
+
int type = 0;
|
2026
|
+
uchar* ptr;
|
2027
|
+
|
2028
|
+
if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type ))
|
2029
|
+
{
|
2030
|
+
CvMat* mat = (CvMat*)arr;
|
2031
|
+
|
2032
|
+
type = CV_MAT_TYPE(mat->type);
|
2033
|
+
int pix_size = CV_ELEM_SIZE(type);
|
2034
|
+
|
2035
|
+
// the first part is mul-free sufficient check
|
2036
|
+
// that the index is within the matrix
|
2037
|
+
if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) &&
|
2038
|
+
(unsigned)idx >= (unsigned)(mat->rows*mat->cols))
|
2039
|
+
CV_Error( CV_StsOutOfRange, "index is out of range" );
|
2040
|
+
|
2041
|
+
ptr = mat->data.ptr + (size_t)idx*pix_size;
|
2042
|
+
}
|
2043
|
+
else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 )
|
2044
|
+
ptr = cvPtr1D( arr, idx, &type );
|
2045
|
+
else
|
2046
|
+
ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, 0, 0 );
|
2047
|
+
|
2048
|
+
if( ptr )
|
2049
|
+
{
|
2050
|
+
if( CV_MAT_CN( type ) > 1 )
|
2051
|
+
CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" );
|
2052
|
+
|
2053
|
+
value = icvGetReal( ptr, type );
|
2054
|
+
}
|
2055
|
+
return value;
|
2056
|
+
}
|
2057
|
+
|
2058
|
+
|
2059
|
+
// Returns specifed element of 2D array
|
2060
|
+
CV_IMPL double
|
2061
|
+
cvGetReal2D( const CvArr* arr, int y, int x )
|
2062
|
+
{
|
2063
|
+
double value = 0;
|
2064
|
+
int type = 0;
|
2065
|
+
uchar* ptr;
|
2066
|
+
|
2067
|
+
if( CV_IS_MAT( arr ))
|
2068
|
+
{
|
2069
|
+
CvMat* mat = (CvMat*)arr;
|
2070
|
+
|
2071
|
+
if( (unsigned)y >= (unsigned)(mat->rows) ||
|
2072
|
+
(unsigned)x >= (unsigned)(mat->cols) )
|
2073
|
+
CV_Error( CV_StsOutOfRange, "index is out of range" );
|
2074
|
+
|
2075
|
+
type = CV_MAT_TYPE(mat->type);
|
2076
|
+
ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type);
|
2077
|
+
}
|
2078
|
+
else if( !CV_IS_SPARSE_MAT( arr ))
|
2079
|
+
ptr = cvPtr2D( arr, y, x, &type );
|
2080
|
+
else
|
2081
|
+
{
|
2082
|
+
int idx[] = { y, x };
|
2083
|
+
ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
|
2084
|
+
}
|
2085
|
+
|
2086
|
+
if( ptr )
|
2087
|
+
{
|
2088
|
+
if( CV_MAT_CN( type ) > 1 )
|
2089
|
+
CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" );
|
2090
|
+
|
2091
|
+
value = icvGetReal( ptr, type );
|
2092
|
+
}
|
2093
|
+
|
2094
|
+
return value;
|
2095
|
+
}
|
2096
|
+
|
2097
|
+
|
2098
|
+
// Returns specifed element of 3D array
|
2099
|
+
CV_IMPL double
|
2100
|
+
cvGetReal3D( const CvArr* arr, int z, int y, int x )
|
2101
|
+
{
|
2102
|
+
double value = 0;
|
2103
|
+
int type = 0;
|
2104
|
+
uchar* ptr;
|
2105
|
+
|
2106
|
+
if( !CV_IS_SPARSE_MAT( arr ))
|
2107
|
+
ptr = cvPtr3D( arr, z, y, x, &type );
|
2108
|
+
else
|
2109
|
+
{
|
2110
|
+
int idx[] = { z, y, x };
|
2111
|
+
ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
|
2112
|
+
}
|
2113
|
+
|
2114
|
+
if( ptr )
|
2115
|
+
{
|
2116
|
+
if( CV_MAT_CN( type ) > 1 )
|
2117
|
+
CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" );
|
2118
|
+
|
2119
|
+
value = icvGetReal( ptr, type );
|
2120
|
+
}
|
2121
|
+
|
2122
|
+
return value;
|
2123
|
+
}
|
2124
|
+
|
2125
|
+
|
2126
|
+
// Returns specifed element of nD array
|
2127
|
+
CV_IMPL double
|
2128
|
+
cvGetRealND( const CvArr* arr, const int* idx )
|
2129
|
+
{
|
2130
|
+
double value = 0;
|
2131
|
+
int type = 0;
|
2132
|
+
uchar* ptr;
|
2133
|
+
|
2134
|
+
if( !CV_IS_SPARSE_MAT( arr ))
|
2135
|
+
ptr = cvPtrND( arr, idx, &type );
|
2136
|
+
else
|
2137
|
+
ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
|
2138
|
+
|
2139
|
+
if( ptr )
|
2140
|
+
{
|
2141
|
+
if( CV_MAT_CN( type ) > 1 )
|
2142
|
+
CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" );
|
2143
|
+
|
2144
|
+
value = icvGetReal( ptr, type );
|
2145
|
+
}
|
2146
|
+
|
2147
|
+
return value;
|
2148
|
+
}
|
2149
|
+
|
2150
|
+
|
2151
|
+
// Assigns new value to specifed element of nD array given linear index
|
2152
|
+
CV_IMPL void
|
2153
|
+
cvSet1D( CvArr* arr, int idx, CvScalar scalar )
|
2154
|
+
{
|
2155
|
+
int type = 0;
|
2156
|
+
uchar* ptr;
|
2157
|
+
|
2158
|
+
if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type ))
|
2159
|
+
{
|
2160
|
+
CvMat* mat = (CvMat*)arr;
|
2161
|
+
|
2162
|
+
type = CV_MAT_TYPE(mat->type);
|
2163
|
+
int pix_size = CV_ELEM_SIZE(type);
|
2164
|
+
|
2165
|
+
// the first part is mul-free sufficient check
|
2166
|
+
// that the index is within the matrix
|
2167
|
+
if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) &&
|
2168
|
+
(unsigned)idx >= (unsigned)(mat->rows*mat->cols))
|
2169
|
+
CV_Error( CV_StsOutOfRange, "index is out of range" );
|
2170
|
+
|
2171
|
+
ptr = mat->data.ptr + (size_t)idx*pix_size;
|
2172
|
+
}
|
2173
|
+
else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 )
|
2174
|
+
ptr = cvPtr1D( arr, idx, &type );
|
2175
|
+
else
|
2176
|
+
ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, -1, 0 );
|
2177
|
+
|
2178
|
+
cvScalarToRawData( &scalar, ptr, type );
|
2179
|
+
}
|
2180
|
+
|
2181
|
+
|
2182
|
+
// Assigns new value to specifed element of 2D array
|
2183
|
+
CV_IMPL void
|
2184
|
+
cvSet2D( CvArr* arr, int y, int x, CvScalar scalar )
|
2185
|
+
{
|
2186
|
+
int type = 0;
|
2187
|
+
uchar* ptr;
|
2188
|
+
|
2189
|
+
if( CV_IS_MAT( arr ))
|
2190
|
+
{
|
2191
|
+
CvMat* mat = (CvMat*)arr;
|
2192
|
+
|
2193
|
+
if( (unsigned)y >= (unsigned)(mat->rows) ||
|
2194
|
+
(unsigned)x >= (unsigned)(mat->cols) )
|
2195
|
+
CV_Error( CV_StsOutOfRange, "index is out of range" );
|
2196
|
+
|
2197
|
+
type = CV_MAT_TYPE(mat->type);
|
2198
|
+
ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type);
|
2199
|
+
}
|
2200
|
+
else if( !CV_IS_SPARSE_MAT( arr ))
|
2201
|
+
ptr = cvPtr2D( arr, y, x, &type );
|
2202
|
+
else
|
2203
|
+
{
|
2204
|
+
int idx[] = { y, x };
|
2205
|
+
ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
|
2206
|
+
}
|
2207
|
+
cvScalarToRawData( &scalar, ptr, type );
|
2208
|
+
}
|
2209
|
+
|
2210
|
+
|
2211
|
+
// Assigns new value to specifed element of 3D array
|
2212
|
+
CV_IMPL void
|
2213
|
+
cvSet3D( CvArr* arr, int z, int y, int x, CvScalar scalar )
|
2214
|
+
{
|
2215
|
+
int type = 0;
|
2216
|
+
uchar* ptr;
|
2217
|
+
|
2218
|
+
if( !CV_IS_SPARSE_MAT( arr ))
|
2219
|
+
ptr = cvPtr3D( arr, z, y, x, &type );
|
2220
|
+
else
|
2221
|
+
{
|
2222
|
+
int idx[] = { z, y, x };
|
2223
|
+
ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
|
2224
|
+
}
|
2225
|
+
cvScalarToRawData( &scalar, ptr, type );
|
2226
|
+
}
|
2227
|
+
|
2228
|
+
|
2229
|
+
// Assigns new value to specifed element of nD array
|
2230
|
+
CV_IMPL void
|
2231
|
+
cvSetND( CvArr* arr, const int* idx, CvScalar scalar )
|
2232
|
+
{
|
2233
|
+
int type = 0;
|
2234
|
+
uchar* ptr;
|
2235
|
+
|
2236
|
+
if( !CV_IS_SPARSE_MAT( arr ))
|
2237
|
+
ptr = cvPtrND( arr, idx, &type );
|
2238
|
+
else
|
2239
|
+
ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
|
2240
|
+
cvScalarToRawData( &scalar, ptr, type );
|
2241
|
+
}
|
2242
|
+
|
2243
|
+
|
2244
|
+
CV_IMPL void
|
2245
|
+
cvSetReal1D( CvArr* arr, int idx, double value )
|
2246
|
+
{
|
2247
|
+
int type = 0;
|
2248
|
+
uchar* ptr;
|
2249
|
+
|
2250
|
+
if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type ))
|
2251
|
+
{
|
2252
|
+
CvMat* mat = (CvMat*)arr;
|
2253
|
+
|
2254
|
+
type = CV_MAT_TYPE(mat->type);
|
2255
|
+
int pix_size = CV_ELEM_SIZE(type);
|
2256
|
+
|
2257
|
+
// the first part is mul-free sufficient check
|
2258
|
+
// that the index is within the matrix
|
2259
|
+
if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) &&
|
2260
|
+
(unsigned)idx >= (unsigned)(mat->rows*mat->cols))
|
2261
|
+
CV_Error( CV_StsOutOfRange, "index is out of range" );
|
2262
|
+
|
2263
|
+
ptr = mat->data.ptr + (size_t)idx*pix_size;
|
2264
|
+
}
|
2265
|
+
else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 )
|
2266
|
+
ptr = cvPtr1D( arr, idx, &type );
|
2267
|
+
else
|
2268
|
+
ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, -1, 0 );
|
2269
|
+
|
2270
|
+
if( CV_MAT_CN( type ) > 1 )
|
2271
|
+
CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" );
|
2272
|
+
|
2273
|
+
if( ptr )
|
2274
|
+
icvSetReal( value, ptr, type );
|
2275
|
+
}
|
2276
|
+
|
2277
|
+
|
2278
|
+
CV_IMPL void
|
2279
|
+
cvSetReal2D( CvArr* arr, int y, int x, double value )
|
2280
|
+
{
|
2281
|
+
int type = 0;
|
2282
|
+
uchar* ptr;
|
2283
|
+
|
2284
|
+
if( CV_IS_MAT( arr ))
|
2285
|
+
{
|
2286
|
+
CvMat* mat = (CvMat*)arr;
|
2287
|
+
|
2288
|
+
if( (unsigned)y >= (unsigned)(mat->rows) ||
|
2289
|
+
(unsigned)x >= (unsigned)(mat->cols) )
|
2290
|
+
CV_Error( CV_StsOutOfRange, "index is out of range" );
|
2291
|
+
|
2292
|
+
type = CV_MAT_TYPE(mat->type);
|
2293
|
+
ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type);
|
2294
|
+
}
|
2295
|
+
else if( !CV_IS_SPARSE_MAT( arr ))
|
2296
|
+
{
|
2297
|
+
ptr = cvPtr2D( arr, y, x, &type );
|
2298
|
+
}
|
2299
|
+
else
|
2300
|
+
{
|
2301
|
+
int idx[] = { y, x };
|
2302
|
+
ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
|
2303
|
+
}
|
2304
|
+
if( CV_MAT_CN( type ) > 1 )
|
2305
|
+
CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" );
|
2306
|
+
|
2307
|
+
if( ptr )
|
2308
|
+
icvSetReal( value, ptr, type );
|
2309
|
+
}
|
2310
|
+
|
2311
|
+
|
2312
|
+
CV_IMPL void
|
2313
|
+
cvSetReal3D( CvArr* arr, int z, int y, int x, double value )
|
2314
|
+
{
|
2315
|
+
int type = 0;
|
2316
|
+
uchar* ptr;
|
2317
|
+
|
2318
|
+
if( !CV_IS_SPARSE_MAT( arr ))
|
2319
|
+
ptr = cvPtr3D( arr, z, y, x, &type );
|
2320
|
+
else
|
2321
|
+
{
|
2322
|
+
int idx[] = { z, y, x };
|
2323
|
+
ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
|
2324
|
+
}
|
2325
|
+
if( CV_MAT_CN( type ) > 1 )
|
2326
|
+
CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" );
|
2327
|
+
|
2328
|
+
if( ptr )
|
2329
|
+
icvSetReal( value, ptr, type );
|
2330
|
+
}
|
2331
|
+
|
2332
|
+
|
2333
|
+
CV_IMPL void
|
2334
|
+
cvSetRealND( CvArr* arr, const int* idx, double value )
|
2335
|
+
{
|
2336
|
+
int type = 0;
|
2337
|
+
uchar* ptr;
|
2338
|
+
|
2339
|
+
if( !CV_IS_SPARSE_MAT( arr ))
|
2340
|
+
ptr = cvPtrND( arr, idx, &type );
|
2341
|
+
else
|
2342
|
+
ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
|
2343
|
+
|
2344
|
+
if( CV_MAT_CN( type ) > 1 )
|
2345
|
+
CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" );
|
2346
|
+
|
2347
|
+
if( ptr )
|
2348
|
+
icvSetReal( value, ptr, type );
|
2349
|
+
}
|
2350
|
+
|
2351
|
+
|
2352
|
+
CV_IMPL void
|
2353
|
+
cvClearND( CvArr* arr, const int* idx )
|
2354
|
+
{
|
2355
|
+
if( !CV_IS_SPARSE_MAT( arr ))
|
2356
|
+
{
|
2357
|
+
int type;
|
2358
|
+
uchar* ptr;
|
2359
|
+
ptr = cvPtrND( arr, idx, &type );
|
2360
|
+
if( ptr )
|
2361
|
+
memset( ptr, 0, CV_ELEM_SIZE(type) );
|
2362
|
+
}
|
2363
|
+
else
|
2364
|
+
icvDeleteNode( (CvSparseMat*)arr, idx, 0 );
|
2365
|
+
}
|
2366
|
+
|
2367
|
+
|
2368
|
+
/****************************************************************************************\
|
2369
|
+
* Conversion to CvMat or IplImage *
|
2370
|
+
\****************************************************************************************/
|
2371
|
+
|
2372
|
+
// convert array (CvMat or IplImage) to CvMat
|
2373
|
+
CV_IMPL CvMat*
|
2374
|
+
cvGetMat( const CvArr* array, CvMat* mat,
|
2375
|
+
int* pCOI, int allowND )
|
2376
|
+
{
|
2377
|
+
CvMat* result = 0;
|
2378
|
+
CvMat* src = (CvMat*)array;
|
2379
|
+
int coi = 0;
|
2380
|
+
|
2381
|
+
if( !mat || !src )
|
2382
|
+
CV_Error( CV_StsNullPtr, "NULL array pointer is passed" );
|
2383
|
+
|
2384
|
+
if( CV_IS_MAT_HDR(src))
|
2385
|
+
{
|
2386
|
+
if( !src->data.ptr )
|
2387
|
+
CV_Error( CV_StsNullPtr, "The matrix has NULL data pointer" );
|
2388
|
+
|
2389
|
+
result = (CvMat*)src;
|
2390
|
+
}
|
2391
|
+
else if( CV_IS_IMAGE_HDR(src) )
|
2392
|
+
{
|
2393
|
+
const IplImage* img = (const IplImage*)src;
|
2394
|
+
int depth, order;
|
2395
|
+
|
2396
|
+
if( img->imageData == 0 )
|
2397
|
+
CV_Error( CV_StsNullPtr, "The image has NULL data pointer" );
|
2398
|
+
|
2399
|
+
depth = IPL2CV_DEPTH( img->depth );
|
2400
|
+
if( depth < 0 )
|
2401
|
+
CV_Error( CV_BadDepth, "" );
|
2402
|
+
|
2403
|
+
order = img->dataOrder & (img->nChannels > 1 ? -1 : 0);
|
2404
|
+
|
2405
|
+
if( img->roi )
|
2406
|
+
{
|
2407
|
+
if( order == IPL_DATA_ORDER_PLANE )
|
2408
|
+
{
|
2409
|
+
int type = depth;
|
2410
|
+
|
2411
|
+
if( img->roi->coi == 0 )
|
2412
|
+
CV_Error( CV_StsBadFlag,
|
2413
|
+
"Images with planar data layout should be used with COI selected" );
|
2414
|
+
|
2415
|
+
cvInitMatHeader( mat, img->roi->height,
|
2416
|
+
img->roi->width, type,
|
2417
|
+
img->imageData + (img->roi->coi-1)*img->imageSize +
|
2418
|
+
img->roi->yOffset*img->widthStep +
|
2419
|
+
img->roi->xOffset*CV_ELEM_SIZE(type),
|
2420
|
+
img->widthStep );
|
2421
|
+
}
|
2422
|
+
else /* pixel order */
|
2423
|
+
{
|
2424
|
+
int type = CV_MAKETYPE( depth, img->nChannels );
|
2425
|
+
coi = img->roi->coi;
|
2426
|
+
|
2427
|
+
if( img->nChannels > CV_CN_MAX )
|
2428
|
+
CV_Error( CV_BadNumChannels,
|
2429
|
+
"The image is interleaved and has over CV_CN_MAX channels" );
|
2430
|
+
|
2431
|
+
cvInitMatHeader( mat, img->roi->height, img->roi->width,
|
2432
|
+
type, img->imageData +
|
2433
|
+
img->roi->yOffset*img->widthStep +
|
2434
|
+
img->roi->xOffset*CV_ELEM_SIZE(type),
|
2435
|
+
img->widthStep );
|
2436
|
+
}
|
2437
|
+
}
|
2438
|
+
else
|
2439
|
+
{
|
2440
|
+
int type = CV_MAKETYPE( depth, img->nChannels );
|
2441
|
+
|
2442
|
+
if( order != IPL_DATA_ORDER_PIXEL )
|
2443
|
+
CV_Error( CV_StsBadFlag, "Pixel order should be used with coi == 0" );
|
2444
|
+
|
2445
|
+
cvInitMatHeader( mat, img->height, img->width, type,
|
2446
|
+
img->imageData, img->widthStep );
|
2447
|
+
}
|
2448
|
+
|
2449
|
+
result = mat;
|
2450
|
+
}
|
2451
|
+
else if( allowND && CV_IS_MATND_HDR(src) )
|
2452
|
+
{
|
2453
|
+
CvMatND* matnd = (CvMatND*)src;
|
2454
|
+
int i;
|
2455
|
+
int size1 = matnd->dim[0].size, size2 = 1;
|
2456
|
+
|
2457
|
+
if( !src->data.ptr )
|
2458
|
+
CV_Error( CV_StsNullPtr, "Input array has NULL data pointer" );
|
2459
|
+
|
2460
|
+
if( !CV_IS_MAT_CONT( matnd->type ))
|
2461
|
+
CV_Error( CV_StsBadArg, "Only continuous nD arrays are supported here" );
|
2462
|
+
|
2463
|
+
if( matnd->dims > 2 )
|
2464
|
+
for( i = 1; i < matnd->dims; i++ )
|
2465
|
+
size2 *= matnd->dim[i].size;
|
2466
|
+
else
|
2467
|
+
size2 = matnd->dims == 1 ? 1 : matnd->dim[1].size;
|
2468
|
+
|
2469
|
+
mat->refcount = 0;
|
2470
|
+
mat->hdr_refcount = 0;
|
2471
|
+
mat->data.ptr = matnd->data.ptr;
|
2472
|
+
mat->rows = size1;
|
2473
|
+
mat->cols = size2;
|
2474
|
+
mat->type = CV_MAT_TYPE(matnd->type) | CV_MAT_MAGIC_VAL | CV_MAT_CONT_FLAG;
|
2475
|
+
mat->step = size2*CV_ELEM_SIZE(matnd->type);
|
2476
|
+
mat->step &= size1 > 1 ? -1 : 0;
|
2477
|
+
|
2478
|
+
icvCheckHuge( mat );
|
2479
|
+
result = mat;
|
2480
|
+
}
|
2481
|
+
else
|
2482
|
+
CV_Error( CV_StsBadFlag, "Unrecognized or unsupported array type" );
|
2483
|
+
|
2484
|
+
if( pCOI )
|
2485
|
+
*pCOI = coi;
|
2486
|
+
|
2487
|
+
return result;
|
2488
|
+
}
|
2489
|
+
|
2490
|
+
|
2491
|
+
CV_IMPL CvArr*
|
2492
|
+
cvReshapeMatND( const CvArr* arr,
|
2493
|
+
int sizeof_header, CvArr* _header,
|
2494
|
+
int new_cn, int new_dims, int* new_sizes )
|
2495
|
+
{
|
2496
|
+
CvArr* result = 0;
|
2497
|
+
int dims, coi = 0;
|
2498
|
+
|
2499
|
+
if( !arr || !_header )
|
2500
|
+
CV_Error( CV_StsNullPtr, "NULL pointer to array or destination header" );
|
2501
|
+
|
2502
|
+
if( new_cn == 0 && new_dims == 0 )
|
2503
|
+
CV_Error( CV_StsBadArg, "None of array parameters is changed: dummy call?" );
|
2504
|
+
|
2505
|
+
dims = cvGetDims( arr );
|
2506
|
+
|
2507
|
+
if( new_dims == 0 )
|
2508
|
+
{
|
2509
|
+
new_sizes = 0;
|
2510
|
+
new_dims = dims;
|
2511
|
+
}
|
2512
|
+
else if( new_dims == 1 )
|
2513
|
+
{
|
2514
|
+
new_sizes = 0;
|
2515
|
+
}
|
2516
|
+
else
|
2517
|
+
{
|
2518
|
+
if( new_dims <= 0 || new_dims > CV_MAX_DIM )
|
2519
|
+
CV_Error( CV_StsOutOfRange, "Non-positive or too large number of dimensions" );
|
2520
|
+
if( !new_sizes )
|
2521
|
+
CV_Error( CV_StsNullPtr, "New dimension sizes are not specified" );
|
2522
|
+
}
|
2523
|
+
|
2524
|
+
if( new_dims <= 2 )
|
2525
|
+
{
|
2526
|
+
CvMat* mat = (CvMat*)arr;
|
2527
|
+
CvMat header;
|
2528
|
+
int* refcount = 0;
|
2529
|
+
int hdr_refcount = 0;
|
2530
|
+
int total_width, new_rows, cn;
|
2531
|
+
|
2532
|
+
if( sizeof_header != sizeof(CvMat) && sizeof_header != sizeof(CvMatND) )
|
2533
|
+
CV_Error( CV_StsBadArg, "The output header should be CvMat or CvMatND" );
|
2534
|
+
|
2535
|
+
if( mat == (CvMat*)_header )
|
2536
|
+
{
|
2537
|
+
refcount = mat->refcount;
|
2538
|
+
hdr_refcount = mat->hdr_refcount;
|
2539
|
+
}
|
2540
|
+
|
2541
|
+
if( !CV_IS_MAT( mat ))
|
2542
|
+
mat = cvGetMat( mat, &header, &coi, 1 );
|
2543
|
+
|
2544
|
+
cn = CV_MAT_CN( mat->type );
|
2545
|
+
total_width = mat->cols * cn;
|
2546
|
+
|
2547
|
+
if( new_cn == 0 )
|
2548
|
+
new_cn = cn;
|
2549
|
+
|
2550
|
+
if( new_sizes )
|
2551
|
+
new_rows = new_sizes[0];
|
2552
|
+
else if( new_dims == 1 )
|
2553
|
+
new_rows = total_width*mat->rows/new_cn;
|
2554
|
+
else
|
2555
|
+
{
|
2556
|
+
new_rows = mat->rows;
|
2557
|
+
if( new_cn > total_width )
|
2558
|
+
new_rows = mat->rows * total_width / new_cn;
|
2559
|
+
}
|
2560
|
+
|
2561
|
+
if( new_rows != mat->rows )
|
2562
|
+
{
|
2563
|
+
int total_size = total_width * mat->rows;
|
2564
|
+
|
2565
|
+
if( !CV_IS_MAT_CONT( mat->type ))
|
2566
|
+
CV_Error( CV_BadStep,
|
2567
|
+
"The matrix is not continuous so the number of rows can not be changed" );
|
2568
|
+
|
2569
|
+
total_width = total_size / new_rows;
|
2570
|
+
|
2571
|
+
if( total_width * new_rows != total_size )
|
2572
|
+
CV_Error( CV_StsBadArg, "The total number of matrix elements "
|
2573
|
+
"is not divisible by the new number of rows" );
|
2574
|
+
}
|
2575
|
+
|
2576
|
+
header.rows = new_rows;
|
2577
|
+
header.cols = total_width / new_cn;
|
2578
|
+
|
2579
|
+
if( header.cols * new_cn != total_width ||
|
2580
|
+
(new_sizes && header.cols != new_sizes[1]) )
|
2581
|
+
CV_Error( CV_StsBadArg, "The total matrix width is not "
|
2582
|
+
"divisible by the new number of columns" );
|
2583
|
+
|
2584
|
+
header.type = (mat->type & ~CV_MAT_TYPE_MASK) | CV_MAKETYPE(mat->type, new_cn);
|
2585
|
+
header.step = header.cols * CV_ELEM_SIZE(mat->type);
|
2586
|
+
header.step &= new_rows > 1 ? -1 : 0;
|
2587
|
+
header.refcount = refcount;
|
2588
|
+
header.hdr_refcount = hdr_refcount;
|
2589
|
+
|
2590
|
+
if( sizeof_header == sizeof(CvMat) )
|
2591
|
+
*(CvMat*)_header = header;
|
2592
|
+
else
|
2593
|
+
{
|
2594
|
+
CvMatND* __header = (CvMatND*)_header;
|
2595
|
+
cvGetMatND(&header, __header, 0);
|
2596
|
+
if( new_dims > 0 )
|
2597
|
+
__header->dims = new_dims;
|
2598
|
+
}
|
2599
|
+
}
|
2600
|
+
else
|
2601
|
+
{
|
2602
|
+
CvMatND* header = (CvMatND*)_header;
|
2603
|
+
|
2604
|
+
if( sizeof_header != sizeof(CvMatND))
|
2605
|
+
CV_Error( CV_StsBadSize, "The output header should be CvMatND" );
|
2606
|
+
|
2607
|
+
if( !new_sizes )
|
2608
|
+
{
|
2609
|
+
if( !CV_IS_MATND( arr ))
|
2610
|
+
CV_Error( CV_StsBadArg, "The input array must be CvMatND" );
|
2611
|
+
|
2612
|
+
{
|
2613
|
+
CvMatND* mat = (CvMatND*)arr;
|
2614
|
+
assert( new_cn > 0 );
|
2615
|
+
int last_dim_size = mat->dim[mat->dims-1].size*CV_MAT_CN(mat->type);
|
2616
|
+
int new_size = last_dim_size/new_cn;
|
2617
|
+
|
2618
|
+
if( new_size*new_cn != last_dim_size )
|
2619
|
+
CV_Error( CV_StsBadArg,
|
2620
|
+
"The last dimension full size is not divisible by new number of channels");
|
2621
|
+
|
2622
|
+
if( mat != header )
|
2623
|
+
{
|
2624
|
+
memcpy( header, mat, sizeof(*header));
|
2625
|
+
header->refcount = 0;
|
2626
|
+
header->hdr_refcount = 0;
|
2627
|
+
}
|
2628
|
+
|
2629
|
+
header->dim[header->dims-1].size = new_size;
|
2630
|
+
header->type = (header->type & ~CV_MAT_TYPE_MASK) | CV_MAKETYPE(header->type, new_cn);
|
2631
|
+
}
|
2632
|
+
}
|
2633
|
+
else
|
2634
|
+
{
|
2635
|
+
CvMatND stub;
|
2636
|
+
CvMatND* mat = (CvMatND*)arr;
|
2637
|
+
int i, size1, size2;
|
2638
|
+
int step;
|
2639
|
+
|
2640
|
+
if( new_cn != 0 )
|
2641
|
+
CV_Error( CV_StsBadArg,
|
2642
|
+
"Simultaneous change of shape and number of channels is not supported. "
|
2643
|
+
"Do it by 2 separate calls" );
|
2644
|
+
|
2645
|
+
if( !CV_IS_MATND( mat ))
|
2646
|
+
{
|
2647
|
+
cvGetMatND( mat, &stub, &coi );
|
2648
|
+
mat = &stub;
|
2649
|
+
}
|
2650
|
+
|
2651
|
+
if( CV_IS_MAT_CONT( mat->type ))
|
2652
|
+
CV_Error( CV_StsBadArg, "Non-continuous nD arrays are not supported" );
|
2653
|
+
|
2654
|
+
size1 = mat->dim[0].size;
|
2655
|
+
for( i = 1; i < dims; i++ )
|
2656
|
+
size1 *= mat->dim[i].size;
|
2657
|
+
|
2658
|
+
size2 = 1;
|
2659
|
+
for( i = 0; i < new_dims; i++ )
|
2660
|
+
{
|
2661
|
+
if( new_sizes[i] <= 0 )
|
2662
|
+
CV_Error( CV_StsBadSize,
|
2663
|
+
"One of new dimension sizes is non-positive" );
|
2664
|
+
size2 *= new_sizes[i];
|
2665
|
+
}
|
2666
|
+
|
2667
|
+
if( size1 != size2 )
|
2668
|
+
CV_Error( CV_StsBadSize,
|
2669
|
+
"Number of elements in the original and reshaped array is different" );
|
2670
|
+
|
2671
|
+
if( header != mat )
|
2672
|
+
{
|
2673
|
+
header->refcount = 0;
|
2674
|
+
header->hdr_refcount = 0;
|
2675
|
+
}
|
2676
|
+
|
2677
|
+
header->dims = new_dims;
|
2678
|
+
header->type = mat->type;
|
2679
|
+
header->data.ptr = mat->data.ptr;
|
2680
|
+
step = CV_ELEM_SIZE(header->type);
|
2681
|
+
|
2682
|
+
for( i = new_dims - 1; i >= 0; i-- )
|
2683
|
+
{
|
2684
|
+
header->dim[i].size = new_sizes[i];
|
2685
|
+
header->dim[i].step = step;
|
2686
|
+
step *= new_sizes[i];
|
2687
|
+
}
|
2688
|
+
}
|
2689
|
+
}
|
2690
|
+
|
2691
|
+
if( coi )
|
2692
|
+
CV_Error( CV_BadCOI, "COI is not supported by this operation" );
|
2693
|
+
|
2694
|
+
result = _header;
|
2695
|
+
return result;
|
2696
|
+
}
|
2697
|
+
|
2698
|
+
|
2699
|
+
CV_IMPL CvMat*
|
2700
|
+
cvReshape( const CvArr* array, CvMat* header,
|
2701
|
+
int new_cn, int new_rows )
|
2702
|
+
{
|
2703
|
+
CvMat* result = 0;
|
2704
|
+
CvMat *mat = (CvMat*)array;
|
2705
|
+
int total_width, new_width;
|
2706
|
+
|
2707
|
+
if( !header )
|
2708
|
+
CV_Error( CV_StsNullPtr, "" );
|
2709
|
+
|
2710
|
+
if( !CV_IS_MAT( mat ))
|
2711
|
+
{
|
2712
|
+
int coi = 0;
|
2713
|
+
mat = cvGetMat( mat, header, &coi, 1 );
|
2714
|
+
if( coi )
|
2715
|
+
CV_Error( CV_BadCOI, "COI is not supported" );
|
2716
|
+
}
|
2717
|
+
|
2718
|
+
if( new_cn == 0 )
|
2719
|
+
new_cn = CV_MAT_CN(mat->type);
|
2720
|
+
else if( (unsigned)(new_cn - 1) > 3 )
|
2721
|
+
CV_Error( CV_BadNumChannels, "" );
|
2722
|
+
|
2723
|
+
if( mat != header )
|
2724
|
+
{
|
2725
|
+
int hdr_refcount = header->hdr_refcount;
|
2726
|
+
*header = *mat;
|
2727
|
+
header->refcount = 0;
|
2728
|
+
header->hdr_refcount = hdr_refcount;
|
2729
|
+
}
|
2730
|
+
|
2731
|
+
total_width = mat->cols * CV_MAT_CN( mat->type );
|
2732
|
+
|
2733
|
+
if( (new_cn > total_width || total_width % new_cn != 0) && new_rows == 0 )
|
2734
|
+
new_rows = mat->rows * total_width / new_cn;
|
2735
|
+
|
2736
|
+
if( new_rows == 0 || new_rows == mat->rows )
|
2737
|
+
{
|
2738
|
+
header->rows = mat->rows;
|
2739
|
+
header->step = mat->step;
|
2740
|
+
}
|
2741
|
+
else
|
2742
|
+
{
|
2743
|
+
int total_size = total_width * mat->rows;
|
2744
|
+
if( !CV_IS_MAT_CONT( mat->type ))
|
2745
|
+
CV_Error( CV_BadStep,
|
2746
|
+
"The matrix is not continuous, thus its number of rows can not be changed" );
|
2747
|
+
|
2748
|
+
if( (unsigned)new_rows > (unsigned)total_size )
|
2749
|
+
CV_Error( CV_StsOutOfRange, "Bad new number of rows" );
|
2750
|
+
|
2751
|
+
total_width = total_size / new_rows;
|
2752
|
+
|
2753
|
+
if( total_width * new_rows != total_size )
|
2754
|
+
CV_Error( CV_StsBadArg, "The total number of matrix elements "
|
2755
|
+
"is not divisible by the new number of rows" );
|
2756
|
+
|
2757
|
+
header->rows = new_rows;
|
2758
|
+
header->step = total_width * CV_ELEM_SIZE1(mat->type);
|
2759
|
+
}
|
2760
|
+
|
2761
|
+
new_width = total_width / new_cn;
|
2762
|
+
|
2763
|
+
if( new_width * new_cn != total_width )
|
2764
|
+
CV_Error( CV_BadNumChannels,
|
2765
|
+
"The total width is not divisible by the new number of channels" );
|
2766
|
+
|
2767
|
+
header->cols = new_width;
|
2768
|
+
header->type = (mat->type & ~CV_MAT_TYPE_MASK) | CV_MAKETYPE(mat->type, new_cn);
|
2769
|
+
|
2770
|
+
result = header;
|
2771
|
+
return result;
|
2772
|
+
}
|
2773
|
+
|
2774
|
+
|
2775
|
+
// convert array (CvMat or IplImage) to IplImage
|
2776
|
+
CV_IMPL IplImage*
|
2777
|
+
cvGetImage( const CvArr* array, IplImage* img )
|
2778
|
+
{
|
2779
|
+
IplImage* result = 0;
|
2780
|
+
const IplImage* src = (const IplImage*)array;
|
2781
|
+
int depth;
|
2782
|
+
|
2783
|
+
if( !img )
|
2784
|
+
CV_Error( CV_StsNullPtr, "" );
|
2785
|
+
|
2786
|
+
if( !CV_IS_IMAGE_HDR(src) )
|
2787
|
+
{
|
2788
|
+
const CvMat* mat = (const CvMat*)src;
|
2789
|
+
|
2790
|
+
if( !CV_IS_MAT_HDR(mat))
|
2791
|
+
CV_Error( CV_StsBadFlag, "" );
|
2792
|
+
|
2793
|
+
if( mat->data.ptr == 0 )
|
2794
|
+
CV_Error( CV_StsNullPtr, "" );
|
2795
|
+
|
2796
|
+
depth = cvIplDepth(mat->type);
|
2797
|
+
|
2798
|
+
cvInitImageHeader( img, cvSize(mat->cols, mat->rows),
|
2799
|
+
depth, CV_MAT_CN(mat->type) );
|
2800
|
+
cvSetData( img, mat->data.ptr, mat->step );
|
2801
|
+
|
2802
|
+
result = img;
|
2803
|
+
}
|
2804
|
+
else
|
2805
|
+
{
|
2806
|
+
result = (IplImage*)src;
|
2807
|
+
}
|
2808
|
+
|
2809
|
+
return result;
|
2810
|
+
}
|
2811
|
+
|
2812
|
+
|
2813
|
+
/****************************************************************************************\
|
2814
|
+
* IplImage-specific functions *
|
2815
|
+
\****************************************************************************************/
|
2816
|
+
|
2817
|
+
static IplROI* icvCreateROI( int coi, int xOffset, int yOffset, int width, int height )
|
2818
|
+
{
|
2819
|
+
IplROI *roi = 0;
|
2820
|
+
if( !CvIPL.createROI )
|
2821
|
+
{
|
2822
|
+
roi = (IplROI*)cvAlloc( sizeof(*roi));
|
2823
|
+
|
2824
|
+
roi->coi = coi;
|
2825
|
+
roi->xOffset = xOffset;
|
2826
|
+
roi->yOffset = yOffset;
|
2827
|
+
roi->width = width;
|
2828
|
+
roi->height = height;
|
2829
|
+
}
|
2830
|
+
else
|
2831
|
+
{
|
2832
|
+
roi = CvIPL.createROI( coi, xOffset, yOffset, width, height );
|
2833
|
+
}
|
2834
|
+
|
2835
|
+
return roi;
|
2836
|
+
}
|
2837
|
+
|
2838
|
+
static void
|
2839
|
+
icvGetColorModel( int nchannels, const char** colorModel, const char** channelSeq )
|
2840
|
+
{
|
2841
|
+
static const char* tab[][2] =
|
2842
|
+
{
|
2843
|
+
{"GRAY", "GRAY"},
|
2844
|
+
{"",""},
|
2845
|
+
{"RGB","BGR"},
|
2846
|
+
{"RGB","BGRA"}
|
2847
|
+
};
|
2848
|
+
|
2849
|
+
nchannels--;
|
2850
|
+
*colorModel = *channelSeq = "";
|
2851
|
+
|
2852
|
+
if( (unsigned)nchannels <= 3 )
|
2853
|
+
{
|
2854
|
+
*colorModel = tab[nchannels][0];
|
2855
|
+
*channelSeq = tab[nchannels][1];
|
2856
|
+
}
|
2857
|
+
}
|
2858
|
+
|
2859
|
+
|
2860
|
+
// create IplImage header
|
2861
|
+
CV_IMPL IplImage *
|
2862
|
+
cvCreateImageHeader( CvSize size, int depth, int channels )
|
2863
|
+
{
|
2864
|
+
IplImage *img = 0;
|
2865
|
+
|
2866
|
+
if( !CvIPL.createHeader )
|
2867
|
+
{
|
2868
|
+
img = (IplImage *)cvAlloc( sizeof( *img ));
|
2869
|
+
cvInitImageHeader( img, size, depth, channels, IPL_ORIGIN_TL,
|
2870
|
+
CV_DEFAULT_IMAGE_ROW_ALIGN );
|
2871
|
+
}
|
2872
|
+
else
|
2873
|
+
{
|
2874
|
+
const char *colorModel, *channelSeq;
|
2875
|
+
|
2876
|
+
icvGetColorModel( channels, &colorModel, &channelSeq );
|
2877
|
+
|
2878
|
+
img = CvIPL.createHeader( channels, 0, depth, (char*)colorModel, (char*)channelSeq,
|
2879
|
+
IPL_DATA_ORDER_PIXEL, IPL_ORIGIN_TL,
|
2880
|
+
CV_DEFAULT_IMAGE_ROW_ALIGN,
|
2881
|
+
size.width, size.height, 0, 0, 0, 0 );
|
2882
|
+
}
|
2883
|
+
|
2884
|
+
return img;
|
2885
|
+
}
|
2886
|
+
|
2887
|
+
|
2888
|
+
// create IplImage header and allocate underlying data
|
2889
|
+
CV_IMPL IplImage *
|
2890
|
+
cvCreateImage( CvSize size, int depth, int channels )
|
2891
|
+
{
|
2892
|
+
IplImage *img = cvCreateImageHeader( size, depth, channels );
|
2893
|
+
assert( img );
|
2894
|
+
cvCreateData( img );
|
2895
|
+
|
2896
|
+
return img;
|
2897
|
+
}
|
2898
|
+
|
2899
|
+
|
2900
|
+
// initalize IplImage header, allocated by the user
|
2901
|
+
CV_IMPL IplImage*
|
2902
|
+
cvInitImageHeader( IplImage * image, CvSize size, int depth,
|
2903
|
+
int channels, int origin, int align )
|
2904
|
+
{
|
2905
|
+
const char *colorModel, *channelSeq;
|
2906
|
+
|
2907
|
+
if( !image )
|
2908
|
+
CV_Error( CV_HeaderIsNull, "null pointer to header" );
|
2909
|
+
|
2910
|
+
memset( image, 0, sizeof( *image ));
|
2911
|
+
image->nSize = sizeof( *image );
|
2912
|
+
|
2913
|
+
icvGetColorModel( channels, &colorModel, &channelSeq );
|
2914
|
+
strncpy( image->colorModel, colorModel, 4 );
|
2915
|
+
strncpy( image->channelSeq, channelSeq, 4 );
|
2916
|
+
|
2917
|
+
if( size.width < 0 || size.height < 0 )
|
2918
|
+
CV_Error( CV_BadROISize, "Bad input roi" );
|
2919
|
+
|
2920
|
+
if( (depth != (int)IPL_DEPTH_1U && depth != (int)IPL_DEPTH_8U &&
|
2921
|
+
depth != (int)IPL_DEPTH_8S && depth != (int)IPL_DEPTH_16U &&
|
2922
|
+
depth != (int)IPL_DEPTH_16S && depth != (int)IPL_DEPTH_32S &&
|
2923
|
+
depth != (int)IPL_DEPTH_32F && depth != (int)IPL_DEPTH_64F) ||
|
2924
|
+
channels < 0 )
|
2925
|
+
CV_Error( CV_BadDepth, "Unsupported format" );
|
2926
|
+
if( origin != CV_ORIGIN_BL && origin != CV_ORIGIN_TL )
|
2927
|
+
CV_Error( CV_BadOrigin, "Bad input origin" );
|
2928
|
+
|
2929
|
+
if( align != 4 && align != 8 )
|
2930
|
+
CV_Error( CV_BadAlign, "Bad input align" );
|
2931
|
+
|
2932
|
+
image->width = size.width;
|
2933
|
+
image->height = size.height;
|
2934
|
+
|
2935
|
+
if( image->roi )
|
2936
|
+
{
|
2937
|
+
image->roi->coi = 0;
|
2938
|
+
image->roi->xOffset = image->roi->yOffset = 0;
|
2939
|
+
image->roi->width = size.width;
|
2940
|
+
image->roi->height = size.height;
|
2941
|
+
}
|
2942
|
+
|
2943
|
+
image->nChannels = MAX( channels, 1 );
|
2944
|
+
image->depth = depth;
|
2945
|
+
image->align = align;
|
2946
|
+
image->widthStep = (((image->width * image->nChannels *
|
2947
|
+
(image->depth & ~IPL_DEPTH_SIGN) + 7)/8)+ align - 1) & (~(align - 1));
|
2948
|
+
image->origin = origin;
|
2949
|
+
image->imageSize = image->widthStep * image->height;
|
2950
|
+
|
2951
|
+
return image;
|
2952
|
+
}
|
2953
|
+
|
2954
|
+
|
2955
|
+
CV_IMPL void
|
2956
|
+
cvReleaseImageHeader( IplImage** image )
|
2957
|
+
{
|
2958
|
+
if( !image )
|
2959
|
+
CV_Error( CV_StsNullPtr, "" );
|
2960
|
+
|
2961
|
+
if( *image )
|
2962
|
+
{
|
2963
|
+
IplImage* img = *image;
|
2964
|
+
*image = 0;
|
2965
|
+
|
2966
|
+
if( !CvIPL.deallocate )
|
2967
|
+
{
|
2968
|
+
cvFree( &img->roi );
|
2969
|
+
cvFree( &img );
|
2970
|
+
}
|
2971
|
+
else
|
2972
|
+
{
|
2973
|
+
CvIPL.deallocate( img, IPL_IMAGE_HEADER | IPL_IMAGE_ROI );
|
2974
|
+
}
|
2975
|
+
}
|
2976
|
+
}
|
2977
|
+
|
2978
|
+
|
2979
|
+
CV_IMPL void
|
2980
|
+
cvReleaseImage( IplImage ** image )
|
2981
|
+
{
|
2982
|
+
if( !image )
|
2983
|
+
CV_Error( CV_StsNullPtr, "" );
|
2984
|
+
|
2985
|
+
if( *image )
|
2986
|
+
{
|
2987
|
+
IplImage* img = *image;
|
2988
|
+
*image = 0;
|
2989
|
+
|
2990
|
+
cvReleaseData( img );
|
2991
|
+
cvReleaseImageHeader( &img );
|
2992
|
+
}
|
2993
|
+
}
|
2994
|
+
|
2995
|
+
|
2996
|
+
CV_IMPL void
|
2997
|
+
cvSetImageROI( IplImage* image, CvRect rect )
|
2998
|
+
{
|
2999
|
+
if( !image )
|
3000
|
+
CV_Error( CV_HeaderIsNull, "" );
|
3001
|
+
|
3002
|
+
// allow zero ROI width or height
|
3003
|
+
CV_Assert( rect.width >= 0 && rect.height >= 0 &&
|
3004
|
+
rect.x < image->width && rect.y < image->height &&
|
3005
|
+
rect.x + rect.width >= (int)(rect.width > 0) &&
|
3006
|
+
rect.y + rect.height >= (int)(rect.height > 0) );
|
3007
|
+
|
3008
|
+
rect.width += rect.x;
|
3009
|
+
rect.height += rect.y;
|
3010
|
+
|
3011
|
+
rect.x = std::max(rect.x, 0);
|
3012
|
+
rect.y = std::max(rect.y, 0);
|
3013
|
+
rect.width = std::min(rect.width, image->width);
|
3014
|
+
rect.height = std::min(rect.height, image->height);
|
3015
|
+
|
3016
|
+
rect.width -= rect.x;
|
3017
|
+
rect.height -= rect.y;
|
3018
|
+
|
3019
|
+
if( image->roi )
|
3020
|
+
{
|
3021
|
+
image->roi->xOffset = rect.x;
|
3022
|
+
image->roi->yOffset = rect.y;
|
3023
|
+
image->roi->width = rect.width;
|
3024
|
+
image->roi->height = rect.height;
|
3025
|
+
}
|
3026
|
+
else
|
3027
|
+
image->roi = icvCreateROI( 0, rect.x, rect.y, rect.width, rect.height );
|
3028
|
+
}
|
3029
|
+
|
3030
|
+
|
3031
|
+
CV_IMPL void
|
3032
|
+
cvResetImageROI( IplImage* image )
|
3033
|
+
{
|
3034
|
+
if( !image )
|
3035
|
+
CV_Error( CV_HeaderIsNull, "" );
|
3036
|
+
|
3037
|
+
if( image->roi )
|
3038
|
+
{
|
3039
|
+
if( !CvIPL.deallocate )
|
3040
|
+
{
|
3041
|
+
cvFree( &image->roi );
|
3042
|
+
}
|
3043
|
+
else
|
3044
|
+
{
|
3045
|
+
CvIPL.deallocate( image, IPL_IMAGE_ROI );
|
3046
|
+
image->roi = 0;
|
3047
|
+
}
|
3048
|
+
}
|
3049
|
+
}
|
3050
|
+
|
3051
|
+
|
3052
|
+
CV_IMPL CvRect
|
3053
|
+
cvGetImageROI( const IplImage* img )
|
3054
|
+
{
|
3055
|
+
CvRect rect = { 0, 0, 0, 0 };
|
3056
|
+
if( !img )
|
3057
|
+
CV_Error( CV_StsNullPtr, "Null pointer to image" );
|
3058
|
+
|
3059
|
+
if( img->roi )
|
3060
|
+
rect = cvRect( img->roi->xOffset, img->roi->yOffset,
|
3061
|
+
img->roi->width, img->roi->height );
|
3062
|
+
else
|
3063
|
+
rect = cvRect( 0, 0, img->width, img->height );
|
3064
|
+
|
3065
|
+
return rect;
|
3066
|
+
}
|
3067
|
+
|
3068
|
+
|
3069
|
+
CV_IMPL void
|
3070
|
+
cvSetImageCOI( IplImage* image, int coi )
|
3071
|
+
{
|
3072
|
+
if( !image )
|
3073
|
+
CV_Error( CV_HeaderIsNull, "" );
|
3074
|
+
|
3075
|
+
if( (unsigned)coi > (unsigned)(image->nChannels) )
|
3076
|
+
CV_Error( CV_BadCOI, "" );
|
3077
|
+
|
3078
|
+
if( image->roi || coi != 0 )
|
3079
|
+
{
|
3080
|
+
if( image->roi )
|
3081
|
+
{
|
3082
|
+
image->roi->coi = coi;
|
3083
|
+
}
|
3084
|
+
else
|
3085
|
+
{
|
3086
|
+
image->roi = icvCreateROI( coi, 0, 0, image->width, image->height );
|
3087
|
+
}
|
3088
|
+
}
|
3089
|
+
}
|
3090
|
+
|
3091
|
+
|
3092
|
+
CV_IMPL int
|
3093
|
+
cvGetImageCOI( const IplImage* image )
|
3094
|
+
{
|
3095
|
+
if( !image )
|
3096
|
+
CV_Error( CV_HeaderIsNull, "" );
|
3097
|
+
|
3098
|
+
return image->roi ? image->roi->coi : 0;
|
3099
|
+
}
|
3100
|
+
|
3101
|
+
|
3102
|
+
CV_IMPL IplImage*
|
3103
|
+
cvCloneImage( const IplImage* src )
|
3104
|
+
{
|
3105
|
+
IplImage* dst = 0;
|
3106
|
+
|
3107
|
+
if( !CV_IS_IMAGE_HDR( src ))
|
3108
|
+
CV_Error( CV_StsBadArg, "Bad image header" );
|
3109
|
+
|
3110
|
+
if( !CvIPL.cloneImage )
|
3111
|
+
{
|
3112
|
+
dst = (IplImage*)cvAlloc( sizeof(*dst));
|
3113
|
+
|
3114
|
+
memcpy( dst, src, sizeof(*src));
|
3115
|
+
dst->imageData = dst->imageDataOrigin = 0;
|
3116
|
+
dst->roi = 0;
|
3117
|
+
|
3118
|
+
if( src->roi )
|
3119
|
+
{
|
3120
|
+
dst->roi = icvCreateROI( src->roi->coi, src->roi->xOffset,
|
3121
|
+
src->roi->yOffset, src->roi->width, src->roi->height );
|
3122
|
+
}
|
3123
|
+
|
3124
|
+
if( src->imageData )
|
3125
|
+
{
|
3126
|
+
int size = src->imageSize;
|
3127
|
+
cvCreateData( dst );
|
3128
|
+
memcpy( dst->imageData, src->imageData, size );
|
3129
|
+
}
|
3130
|
+
}
|
3131
|
+
else
|
3132
|
+
dst = CvIPL.cloneImage( src );
|
3133
|
+
|
3134
|
+
return dst;
|
3135
|
+
}
|
3136
|
+
|
3137
|
+
|
3138
|
+
/****************************************************************************************\
|
3139
|
+
* Additional operations on CvTermCriteria *
|
3140
|
+
\****************************************************************************************/
|
3141
|
+
|
3142
|
+
CV_IMPL CvTermCriteria
|
3143
|
+
cvCheckTermCriteria( CvTermCriteria criteria, double default_eps,
|
3144
|
+
int default_max_iters )
|
3145
|
+
{
|
3146
|
+
CvTermCriteria crit;
|
3147
|
+
|
3148
|
+
crit.type = CV_TERMCRIT_ITER|CV_TERMCRIT_EPS;
|
3149
|
+
crit.max_iter = default_max_iters;
|
3150
|
+
crit.epsilon = (float)default_eps;
|
3151
|
+
|
3152
|
+
if( (criteria.type & ~(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER)) != 0 )
|
3153
|
+
CV_Error( CV_StsBadArg,
|
3154
|
+
"Unknown type of term criteria" );
|
3155
|
+
|
3156
|
+
if( (criteria.type & CV_TERMCRIT_ITER) != 0 )
|
3157
|
+
{
|
3158
|
+
if( criteria.max_iter <= 0 )
|
3159
|
+
CV_Error( CV_StsBadArg,
|
3160
|
+
"Iterations flag is set and maximum number of iterations is <= 0" );
|
3161
|
+
crit.max_iter = criteria.max_iter;
|
3162
|
+
}
|
3163
|
+
|
3164
|
+
if( (criteria.type & CV_TERMCRIT_EPS) != 0 )
|
3165
|
+
{
|
3166
|
+
if( criteria.epsilon < 0 )
|
3167
|
+
CV_Error( CV_StsBadArg, "Accuracy flag is set and epsilon is < 0" );
|
3168
|
+
|
3169
|
+
crit.epsilon = criteria.epsilon;
|
3170
|
+
}
|
3171
|
+
|
3172
|
+
if( (criteria.type & (CV_TERMCRIT_EPS | CV_TERMCRIT_ITER)) == 0 )
|
3173
|
+
CV_Error( CV_StsBadArg,
|
3174
|
+
"Neither accuracy nor maximum iterations "
|
3175
|
+
"number flags are set in criteria type" );
|
3176
|
+
|
3177
|
+
crit.epsilon = (float)MAX( 0, crit.epsilon );
|
3178
|
+
crit.max_iter = MAX( 1, crit.max_iter );
|
3179
|
+
|
3180
|
+
return crit;
|
3181
|
+
}
|
3182
|
+
|
3183
|
+
namespace cv
|
3184
|
+
{
|
3185
|
+
|
3186
|
+
template<> void Ptr<CvMat>::delete_obj()
|
3187
|
+
{ cvReleaseMat(&obj); }
|
3188
|
+
|
3189
|
+
template<> void Ptr<IplImage>::delete_obj()
|
3190
|
+
{ cvReleaseImage(&obj); }
|
3191
|
+
|
3192
|
+
template<> void Ptr<CvMatND>::delete_obj()
|
3193
|
+
{ cvReleaseMatND(&obj); }
|
3194
|
+
|
3195
|
+
template<> void Ptr<CvSparseMat>::delete_obj()
|
3196
|
+
{ cvReleaseSparseMat(&obj); }
|
3197
|
+
|
3198
|
+
template<> void Ptr<CvMemStorage>::delete_obj()
|
3199
|
+
{ cvReleaseMemStorage(&obj); }
|
3200
|
+
|
3201
|
+
template<> void Ptr<CvFileStorage>::delete_obj()
|
3202
|
+
{ cvReleaseFileStorage(&obj); }
|
3203
|
+
|
3204
|
+
}
|
3205
|
+
|
3206
|
+
/* End of file. */
|