Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/modules/core/src/matrix_c.cpp
16337 views
1
#include "opencv2/core/mat.hpp"
2
#include "opencv2/core/types_c.h"
3
#include "precomp.hpp"
4
5
// glue
6
7
CvMatND cvMatND(const cv::Mat& m)
8
{
9
CvMatND self;
10
cvInitMatNDHeader(&self, m.dims, m.size, m.type(), m.data );
11
int i, d = m.dims;
12
for( i = 0; i < d; i++ )
13
self.dim[i].step = (int)m.step[i];
14
self.type |= m.flags & cv::Mat::CONTINUOUS_FLAG;
15
return self;
16
}
17
18
_IplImage cvIplImage(const cv::Mat& m)
19
{
20
_IplImage self;
21
CV_Assert( m.dims <= 2 );
22
cvInitImageHeader(&self, cvSize(m.size()), cvIplDepth(m.flags), m.channels());
23
cvSetData(&self, m.data, (int)m.step[0]);
24
return self;
25
}
26
27
namespace cv {
28
29
static Mat cvMatToMat(const CvMat* m, bool copyData)
30
{
31
Mat thiz;
32
33
if( !m )
34
return thiz;
35
36
if( !copyData )
37
{
38
thiz.flags = Mat::MAGIC_VAL + (m->type & (CV_MAT_TYPE_MASK|CV_MAT_CONT_FLAG));
39
thiz.dims = 2;
40
thiz.rows = m->rows;
41
thiz.cols = m->cols;
42
thiz.datastart = thiz.data = m->data.ptr;
43
size_t esz = CV_ELEM_SIZE(m->type), minstep = thiz.cols*esz, _step = m->step;
44
if( _step == 0 )
45
_step = minstep;
46
thiz.datalimit = thiz.datastart + _step*thiz.rows;
47
thiz.dataend = thiz.datalimit - _step + minstep;
48
thiz.step[0] = _step; thiz.step[1] = esz;
49
}
50
else
51
{
52
thiz.datastart = thiz.dataend = thiz.data = 0;
53
Mat(m->rows, m->cols, m->type, m->data.ptr, m->step).copyTo(thiz);
54
}
55
56
return thiz;
57
}
58
59
static Mat cvMatNDToMat(const CvMatND* m, bool copyData)
60
{
61
Mat thiz;
62
63
if( !m )
64
return thiz;
65
thiz.datastart = thiz.data = m->data.ptr;
66
thiz.flags |= CV_MAT_TYPE(m->type);
67
int _sizes[CV_MAX_DIM];
68
size_t _steps[CV_MAX_DIM];
69
70
int d = m->dims;
71
for( int i = 0; i < d; i++ )
72
{
73
_sizes[i] = m->dim[i].size;
74
_steps[i] = m->dim[i].step;
75
}
76
77
setSize(thiz, d, _sizes, _steps);
78
finalizeHdr(thiz);
79
80
if( copyData )
81
{
82
Mat temp(thiz);
83
thiz.release();
84
temp.copyTo(thiz);
85
}
86
87
return thiz;
88
}
89
90
static Mat iplImageToMat(const IplImage* img, bool copyData)
91
{
92
Mat m;
93
94
if( !img )
95
return m;
96
97
m.dims = 2;
98
CV_DbgAssert(CV_IS_IMAGE(img) && img->imageData != 0);
99
100
int imgdepth = IPL2CV_DEPTH(img->depth);
101
size_t esz;
102
m.step[0] = img->widthStep;
103
104
if(!img->roi)
105
{
106
CV_Assert(img->dataOrder == IPL_DATA_ORDER_PIXEL);
107
m.flags = Mat::MAGIC_VAL + CV_MAKETYPE(imgdepth, img->nChannels);
108
m.rows = img->height;
109
m.cols = img->width;
110
m.datastart = m.data = (uchar*)img->imageData;
111
esz = CV_ELEM_SIZE(m.flags);
112
}
113
else
114
{
115
CV_Assert(img->dataOrder == IPL_DATA_ORDER_PIXEL || img->roi->coi != 0);
116
bool selectedPlane = img->roi->coi && img->dataOrder == IPL_DATA_ORDER_PLANE;
117
m.flags = Mat::MAGIC_VAL + CV_MAKETYPE(imgdepth, selectedPlane ? 1 : img->nChannels);
118
m.rows = img->roi->height;
119
m.cols = img->roi->width;
120
esz = CV_ELEM_SIZE(m.flags);
121
m.datastart = m.data = (uchar*)img->imageData +
122
(selectedPlane ? (img->roi->coi - 1)*m.step*img->height : 0) +
123
img->roi->yOffset*m.step[0] + img->roi->xOffset*esz;
124
}
125
m.datalimit = m.datastart + m.step.p[0]*m.rows;
126
m.dataend = m.datastart + m.step.p[0]*(m.rows-1) + esz*m.cols;
127
m.step[1] = esz;
128
m.updateContinuityFlag();
129
130
if( copyData )
131
{
132
Mat m2 = m;
133
m.release();
134
if( !img->roi || !img->roi->coi ||
135
img->dataOrder == IPL_DATA_ORDER_PLANE)
136
m2.copyTo(m);
137
else
138
{
139
int ch[] = {img->roi->coi - 1, 0};
140
m.create(m2.rows, m2.cols, m2.type());
141
mixChannels(&m2, 1, &m, 1, ch, 1);
142
}
143
}
144
145
return m;
146
}
147
148
Mat cvarrToMat(const CvArr* arr, bool copyData,
149
bool /*allowND*/, int coiMode, AutoBuffer<double>* abuf )
150
{
151
if( !arr )
152
return Mat();
153
if( CV_IS_MAT_HDR_Z(arr) )
154
return cvMatToMat((const CvMat*)arr, copyData);
155
if( CV_IS_MATND(arr) )
156
return cvMatNDToMat((const CvMatND*)arr, copyData );
157
if( CV_IS_IMAGE(arr) )
158
{
159
const IplImage* iplimg = (const IplImage*)arr;
160
if( coiMode == 0 && iplimg->roi && iplimg->roi->coi > 0 )
161
CV_Error(CV_BadCOI, "COI is not supported by the function");
162
return iplImageToMat(iplimg, copyData);
163
}
164
if( CV_IS_SEQ(arr) )
165
{
166
CvSeq* seq = (CvSeq*)arr;
167
int total = seq->total, type = CV_MAT_TYPE(seq->flags), esz = seq->elem_size;
168
if( total == 0 )
169
return Mat();
170
CV_Assert(total > 0 && CV_ELEM_SIZE(seq->flags) == esz);
171
if(!copyData && seq->first->next == seq->first)
172
return Mat(total, 1, type, seq->first->data);
173
if( abuf )
174
{
175
abuf->allocate(((size_t)total*esz + sizeof(double)-1)/sizeof(double));
176
double* bufdata = abuf->data();
177
cvCvtSeqToArray(seq, bufdata, CV_WHOLE_SEQ);
178
return Mat(total, 1, type, bufdata);
179
}
180
181
Mat buf(total, 1, type);
182
cvCvtSeqToArray(seq, buf.ptr(), CV_WHOLE_SEQ);
183
return buf;
184
}
185
CV_Error(CV_StsBadArg, "Unknown array type");
186
}
187
188
void extractImageCOI(const CvArr* arr, OutputArray _ch, int coi)
189
{
190
Mat mat = cvarrToMat(arr, false, true, 1);
191
_ch.create(mat.dims, mat.size, mat.depth());
192
Mat ch = _ch.getMat();
193
if(coi < 0)
194
{
195
CV_Assert( CV_IS_IMAGE(arr) );
196
coi = cvGetImageCOI((const IplImage*)arr)-1;
197
}
198
CV_Assert(0 <= coi && coi < mat.channels());
199
int _pairs[] = { coi, 0 };
200
mixChannels( &mat, 1, &ch, 1, _pairs, 1 );
201
}
202
203
void insertImageCOI(InputArray _ch, CvArr* arr, int coi)
204
{
205
Mat ch = _ch.getMat(), mat = cvarrToMat(arr, false, true, 1);
206
if(coi < 0)
207
{
208
CV_Assert( CV_IS_IMAGE(arr) );
209
coi = cvGetImageCOI((const IplImage*)arr)-1;
210
}
211
CV_Assert(ch.size == mat.size && ch.depth() == mat.depth() && 0 <= coi && coi < mat.channels());
212
int _pairs[] = { 0, coi };
213
mixChannels( &ch, 1, &mat, 1, _pairs, 1 );
214
}
215
216
} // cv::
217
218
// operations
219
220
CV_IMPL void cvSetIdentity( CvArr* arr, CvScalar value )
221
{
222
cv::Mat m = cv::cvarrToMat(arr);
223
cv::setIdentity(m, value);
224
}
225
226
227
CV_IMPL CvScalar cvTrace( const CvArr* arr )
228
{
229
return cvScalar(cv::trace(cv::cvarrToMat(arr)));
230
}
231
232
233
CV_IMPL void cvTranspose( const CvArr* srcarr, CvArr* dstarr )
234
{
235
cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr);
236
237
CV_Assert( src.rows == dst.cols && src.cols == dst.rows && src.type() == dst.type() );
238
transpose( src, dst );
239
}
240
241
242
CV_IMPL void cvCompleteSymm( CvMat* matrix, int LtoR )
243
{
244
cv::Mat m = cv::cvarrToMat(matrix);
245
cv::completeSymm( m, LtoR != 0 );
246
}
247
248
249
CV_IMPL void cvCrossProduct( const CvArr* srcAarr, const CvArr* srcBarr, CvArr* dstarr )
250
{
251
cv::Mat srcA = cv::cvarrToMat(srcAarr), dst = cv::cvarrToMat(dstarr);
252
253
CV_Assert( srcA.size() == dst.size() && srcA.type() == dst.type() );
254
srcA.cross(cv::cvarrToMat(srcBarr)).copyTo(dst);
255
}
256
257
258
CV_IMPL void
259
cvReduce( const CvArr* srcarr, CvArr* dstarr, int dim, int op )
260
{
261
cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr);
262
263
if( dim < 0 )
264
dim = src.rows > dst.rows ? 0 : src.cols > dst.cols ? 1 : dst.cols == 1;
265
266
if( dim > 1 )
267
CV_Error( CV_StsOutOfRange, "The reduced dimensionality index is out of range" );
268
269
if( (dim == 0 && (dst.cols != src.cols || dst.rows != 1)) ||
270
(dim == 1 && (dst.rows != src.rows || dst.cols != 1)) )
271
CV_Error( CV_StsBadSize, "The output array size is incorrect" );
272
273
if( src.channels() != dst.channels() )
274
CV_Error( CV_StsUnmatchedFormats, "Input and output arrays must have the same number of channels" );
275
276
cv::reduce(src, dst, dim, op, dst.type());
277
}
278
279
280
CV_IMPL CvArr*
281
cvRange( CvArr* arr, double start, double end )
282
{
283
CvMat stub, *mat = (CvMat*)arr;
284
int step;
285
double val = start;
286
287
if( !CV_IS_MAT(mat) )
288
mat = cvGetMat( mat, &stub);
289
290
int rows = mat->rows;
291
int cols = mat->cols;
292
int type = CV_MAT_TYPE(mat->type);
293
double delta = (end-start)/(rows*cols);
294
295
if( CV_IS_MAT_CONT(mat->type) )
296
{
297
cols *= rows;
298
rows = 1;
299
step = 1;
300
}
301
else
302
step = mat->step / CV_ELEM_SIZE(type);
303
304
if( type == CV_32SC1 )
305
{
306
int* idata = mat->data.i;
307
int ival = cvRound(val), idelta = cvRound(delta);
308
309
if( fabs(val - ival) < DBL_EPSILON &&
310
fabs(delta - idelta) < DBL_EPSILON )
311
{
312
for( int i = 0; i < rows; i++, idata += step )
313
for( int j = 0; j < cols; j++, ival += idelta )
314
idata[j] = ival;
315
}
316
else
317
{
318
for( int i = 0; i < rows; i++, idata += step )
319
for( int j = 0; j < cols; j++, val += delta )
320
idata[j] = cvRound(val);
321
}
322
}
323
else if( type == CV_32FC1 )
324
{
325
float* fdata = mat->data.fl;
326
for( int i = 0; i < rows; i++, fdata += step )
327
for( int j = 0; j < cols; j++, val += delta )
328
fdata[j] = (float)val;
329
}
330
else
331
CV_Error( CV_StsUnsupportedFormat, "The function only supports 32sC1 and 32fC1 datatypes" );
332
333
return arr;
334
}
335
336
337
CV_IMPL void
338
cvSort( const CvArr* _src, CvArr* _dst, CvArr* _idx, int flags )
339
{
340
cv::Mat src = cv::cvarrToMat(_src);
341
342
if( _idx )
343
{
344
cv::Mat idx0 = cv::cvarrToMat(_idx), idx = idx0;
345
CV_Assert( src.size() == idx.size() && idx.type() == CV_32S && src.data != idx.data );
346
cv::sortIdx( src, idx, flags );
347
CV_Assert( idx0.data == idx.data );
348
}
349
350
if( _dst )
351
{
352
cv::Mat dst0 = cv::cvarrToMat(_dst), dst = dst0;
353
CV_Assert( src.size() == dst.size() && src.type() == dst.type() );
354
cv::sort( src, dst, flags );
355
CV_Assert( dst0.data == dst.data );
356
}
357
}
358
359
360
CV_IMPL int
361
cvKMeans2( const CvArr* _samples, int cluster_count, CvArr* _labels,
362
CvTermCriteria termcrit, int attempts, CvRNG*,
363
int flags, CvArr* _centers, double* _compactness )
364
{
365
cv::Mat data = cv::cvarrToMat(_samples), labels = cv::cvarrToMat(_labels), centers;
366
if( _centers )
367
{
368
centers = cv::cvarrToMat(_centers);
369
370
centers = centers.reshape(1);
371
data = data.reshape(1);
372
373
CV_Assert( !centers.empty() );
374
CV_Assert( centers.rows == cluster_count );
375
CV_Assert( centers.cols == data.cols );
376
CV_Assert( centers.depth() == data.depth() );
377
}
378
CV_Assert( labels.isContinuous() && labels.type() == CV_32S &&
379
(labels.cols == 1 || labels.rows == 1) &&
380
labels.cols + labels.rows - 1 == data.rows );
381
382
double compactness = cv::kmeans(data, cluster_count, labels, termcrit, attempts,
383
flags, _centers ? cv::_OutputArray(centers) : cv::_OutputArray() );
384
if( _compactness )
385
*_compactness = compactness;
386
return 1;
387
}
388
389