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

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of opencv/modules/core/src/matrix_c.cpp