Merge pull request #10789 from mshabunin:split-matrix

pull/10856/head
Vadim Pisarevsky 7 years ago
commit 292dfc2d72
  1. 46
      modules/core/src/array.cpp
  2. 5187
      modules/core/src/matrix.cpp
  3. 384
      modules/core/src/matrix_c.cpp
  4. 48
      modules/core/src/matrix_decomp.cpp
  5. 49
      modules/core/src/matrix_expressions.cpp
  6. 358
      modules/core/src/matrix_iterator.cpp
  7. 1449
      modules/core/src/matrix_operations.cpp
  8. 802
      modules/core/src/matrix_sparse.cpp
  9. 1948
      modules/core/src/matrix_wrap.cpp
  10. 3
      modules/core/src/precomp.hpp
  11. 67
      modules/core/src/types.cpp

@ -1448,7 +1448,6 @@ cvGetDiag( const CvArr* arr, CvMat* submat, int diag )
return res;
}
/****************************************************************************************\
* Operations on CvScalar and accessing array elements *
\****************************************************************************************/
@ -3215,6 +3214,51 @@ template<> void DefaultDeleter<CvMemStorage>::operator ()(CvMemStorage* obj) con
template<> void DefaultDeleter<CvFileStorage>::operator ()(CvFileStorage* obj) const
{ cvReleaseFileStorage(&obj); }
template <typename T> static inline
void scalarToRawData_(const Scalar& s, T * const buf, const int cn, const int unroll_to)
{
int i = 0;
for(; i < cn; i++)
buf[i] = saturate_cast<T>(s.val[i]);
for(; i < unroll_to; i++)
buf[i] = buf[i-cn];
}
void scalarToRawData(const Scalar& s, void* _buf, int type, int unroll_to)
{
CV_INSTRUMENT_REGION()
const int depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
CV_Assert(cn <= 4);
switch(depth)
{
case CV_8U:
scalarToRawData_<uchar>(s, (uchar*)_buf, cn, unroll_to);
break;
case CV_8S:
scalarToRawData_<schar>(s, (schar*)_buf, cn, unroll_to);
break;
case CV_16U:
scalarToRawData_<ushort>(s, (ushort*)_buf, cn, unroll_to);
break;
case CV_16S:
scalarToRawData_<short>(s, (short*)_buf, cn, unroll_to);
break;
case CV_32S:
scalarToRawData_<int>(s, (int*)_buf, cn, unroll_to);
break;
case CV_32F:
scalarToRawData_<float>(s, (float*)_buf, cn, unroll_to);
break;
case CV_64F:
scalarToRawData_<double>(s, (double*)_buf, cn, unroll_to);
break;
default:
CV_Error(CV_StsUnsupportedFormat,"");
}
}
} // cv::
/* End of file. */

File diff suppressed because it is too large Load Diff

@ -0,0 +1,384 @@
#include "opencv2/core/mat.hpp"
#include "opencv2/core/types_c.h"
#include "precomp.hpp"
// glue
CvMatND::CvMatND(const cv::Mat& m)
{
cvInitMatNDHeader(this, m.dims, m.size, m.type(), m.data );
int i, d = m.dims;
for( i = 0; i < d; i++ )
dim[i].step = (int)m.step[i];
type |= m.flags & cv::Mat::CONTINUOUS_FLAG;
}
_IplImage::_IplImage(const cv::Mat& m)
{
CV_Assert( m.dims <= 2 );
cvInitImageHeader(this, m.size(), cvIplDepth(m.flags), m.channels());
cvSetData(this, m.data, (int)m.step[0]);
}
namespace cv {
static Mat cvMatToMat(const CvMat* m, bool copyData)
{
Mat thiz;
if( !m )
return thiz;
if( !copyData )
{
thiz.flags = Mat::MAGIC_VAL + (m->type & (CV_MAT_TYPE_MASK|CV_MAT_CONT_FLAG));
thiz.dims = 2;
thiz.rows = m->rows;
thiz.cols = m->cols;
thiz.datastart = thiz.data = m->data.ptr;
size_t esz = CV_ELEM_SIZE(m->type), minstep = thiz.cols*esz, _step = m->step;
if( _step == 0 )
_step = minstep;
thiz.datalimit = thiz.datastart + _step*thiz.rows;
thiz.dataend = thiz.datalimit - _step + minstep;
thiz.step[0] = _step; thiz.step[1] = esz;
}
else
{
thiz.datastart = thiz.dataend = thiz.data = 0;
Mat(m->rows, m->cols, m->type, m->data.ptr, m->step).copyTo(thiz);
}
return thiz;
}
static Mat cvMatNDToMat(const CvMatND* m, bool copyData)
{
Mat thiz;
if( !m )
return thiz;
thiz.datastart = thiz.data = m->data.ptr;
thiz.flags |= CV_MAT_TYPE(m->type);
int _sizes[CV_MAX_DIM];
size_t _steps[CV_MAX_DIM];
int d = m->dims;
for( int i = 0; i < d; i++ )
{
_sizes[i] = m->dim[i].size;
_steps[i] = m->dim[i].step;
}
setSize(thiz, d, _sizes, _steps);
finalizeHdr(thiz);
if( copyData )
{
Mat temp(thiz);
thiz.release();
temp.copyTo(thiz);
}
return thiz;
}
static Mat iplImageToMat(const IplImage* img, bool copyData)
{
Mat m;
if( !img )
return m;
m.dims = 2;
CV_DbgAssert(CV_IS_IMAGE(img) && img->imageData != 0);
int imgdepth = IPL2CV_DEPTH(img->depth);
size_t esz;
m.step[0] = img->widthStep;
if(!img->roi)
{
CV_Assert(img->dataOrder == IPL_DATA_ORDER_PIXEL);
m.flags = Mat::MAGIC_VAL + CV_MAKETYPE(imgdepth, img->nChannels);
m.rows = img->height;
m.cols = img->width;
m.datastart = m.data = (uchar*)img->imageData;
esz = CV_ELEM_SIZE(m.flags);
}
else
{
CV_Assert(img->dataOrder == IPL_DATA_ORDER_PIXEL || img->roi->coi != 0);
bool selectedPlane = img->roi->coi && img->dataOrder == IPL_DATA_ORDER_PLANE;
m.flags = Mat::MAGIC_VAL + CV_MAKETYPE(imgdepth, selectedPlane ? 1 : img->nChannels);
m.rows = img->roi->height;
m.cols = img->roi->width;
esz = CV_ELEM_SIZE(m.flags);
m.datastart = m.data = (uchar*)img->imageData +
(selectedPlane ? (img->roi->coi - 1)*m.step*img->height : 0) +
img->roi->yOffset*m.step[0] + img->roi->xOffset*esz;
}
m.datalimit = m.datastart + m.step.p[0]*m.rows;
m.dataend = m.datastart + m.step.p[0]*(m.rows-1) + esz*m.cols;
m.flags |= (m.cols*esz == m.step.p[0] || m.rows == 1 ? Mat::CONTINUOUS_FLAG : 0);
m.step[1] = esz;
if( copyData )
{
Mat m2 = m;
m.release();
if( !img->roi || !img->roi->coi ||
img->dataOrder == IPL_DATA_ORDER_PLANE)
m2.copyTo(m);
else
{
int ch[] = {img->roi->coi - 1, 0};
m.create(m2.rows, m2.cols, m2.type());
mixChannels(&m2, 1, &m, 1, ch, 1);
}
}
return m;
}
Mat cvarrToMat(const CvArr* arr, bool copyData,
bool /*allowND*/, int coiMode, AutoBuffer<double>* abuf )
{
if( !arr )
return Mat();
if( CV_IS_MAT_HDR_Z(arr) )
return cvMatToMat((const CvMat*)arr, copyData);
if( CV_IS_MATND(arr) )
return cvMatNDToMat((const CvMatND*)arr, copyData );
if( CV_IS_IMAGE(arr) )
{
const IplImage* iplimg = (const IplImage*)arr;
if( coiMode == 0 && iplimg->roi && iplimg->roi->coi > 0 )
CV_Error(CV_BadCOI, "COI is not supported by the function");
return iplImageToMat(iplimg, copyData);
}
if( CV_IS_SEQ(arr) )
{
CvSeq* seq = (CvSeq*)arr;
int total = seq->total, type = CV_MAT_TYPE(seq->flags), esz = seq->elem_size;
if( total == 0 )
return Mat();
CV_Assert(total > 0 && CV_ELEM_SIZE(seq->flags) == esz);
if(!copyData && seq->first->next == seq->first)
return Mat(total, 1, type, seq->first->data);
if( abuf )
{
abuf->allocate(((size_t)total*esz + sizeof(double)-1)/sizeof(double));
double* bufdata = *abuf;
cvCvtSeqToArray(seq, bufdata, CV_WHOLE_SEQ);
return Mat(total, 1, type, bufdata);
}
Mat buf(total, 1, type);
cvCvtSeqToArray(seq, buf.ptr(), CV_WHOLE_SEQ);
return buf;
}
CV_Error(CV_StsBadArg, "Unknown array type");
return Mat();
}
void extractImageCOI(const CvArr* arr, OutputArray _ch, int coi)
{
Mat mat = cvarrToMat(arr, false, true, 1);
_ch.create(mat.dims, mat.size, mat.depth());
Mat ch = _ch.getMat();
if(coi < 0)
{
CV_Assert( CV_IS_IMAGE(arr) );
coi = cvGetImageCOI((const IplImage*)arr)-1;
}
CV_Assert(0 <= coi && coi < mat.channels());
int _pairs[] = { coi, 0 };
mixChannels( &mat, 1, &ch, 1, _pairs, 1 );
}
void insertImageCOI(InputArray _ch, CvArr* arr, int coi)
{
Mat ch = _ch.getMat(), mat = cvarrToMat(arr, false, true, 1);
if(coi < 0)
{
CV_Assert( CV_IS_IMAGE(arr) );
coi = cvGetImageCOI((const IplImage*)arr)-1;
}
CV_Assert(ch.size == mat.size && ch.depth() == mat.depth() && 0 <= coi && coi < mat.channels());
int _pairs[] = { 0, coi };
mixChannels( &ch, 1, &mat, 1, _pairs, 1 );
}
} // cv::
// operations
CV_IMPL void cvSetIdentity( CvArr* arr, CvScalar value )
{
cv::Mat m = cv::cvarrToMat(arr);
cv::setIdentity(m, value);
}
CV_IMPL CvScalar cvTrace( const CvArr* arr )
{
return cv::trace(cv::cvarrToMat(arr));
}
CV_IMPL void cvTranspose( const CvArr* srcarr, CvArr* dstarr )
{
cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr);
CV_Assert( src.rows == dst.cols && src.cols == dst.rows && src.type() == dst.type() );
transpose( src, dst );
}
CV_IMPL void cvCompleteSymm( CvMat* matrix, int LtoR )
{
cv::Mat m = cv::cvarrToMat(matrix);
cv::completeSymm( m, LtoR != 0 );
}
CV_IMPL void cvCrossProduct( const CvArr* srcAarr, const CvArr* srcBarr, CvArr* dstarr )
{
cv::Mat srcA = cv::cvarrToMat(srcAarr), dst = cv::cvarrToMat(dstarr);
CV_Assert( srcA.size() == dst.size() && srcA.type() == dst.type() );
srcA.cross(cv::cvarrToMat(srcBarr)).copyTo(dst);
}
CV_IMPL void
cvReduce( const CvArr* srcarr, CvArr* dstarr, int dim, int op )
{
cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr);
if( dim < 0 )
dim = src.rows > dst.rows ? 0 : src.cols > dst.cols ? 1 : dst.cols == 1;
if( dim > 1 )
CV_Error( CV_StsOutOfRange, "The reduced dimensionality index is out of range" );
if( (dim == 0 && (dst.cols != src.cols || dst.rows != 1)) ||
(dim == 1 && (dst.rows != src.rows || dst.cols != 1)) )
CV_Error( CV_StsBadSize, "The output array size is incorrect" );
if( src.channels() != dst.channels() )
CV_Error( CV_StsUnmatchedFormats, "Input and output arrays must have the same number of channels" );
cv::reduce(src, dst, dim, op, dst.type());
}
CV_IMPL CvArr*
cvRange( CvArr* arr, double start, double end )
{
CvMat stub, *mat = (CvMat*)arr;
int step;
double val = start;
if( !CV_IS_MAT(mat) )
mat = cvGetMat( mat, &stub);
int rows = mat->rows;
int cols = mat->cols;
int type = CV_MAT_TYPE(mat->type);
double delta = (end-start)/(rows*cols);
if( CV_IS_MAT_CONT(mat->type) )
{
cols *= rows;
rows = 1;
step = 1;
}
else
step = mat->step / CV_ELEM_SIZE(type);
if( type == CV_32SC1 )
{
int* idata = mat->data.i;
int ival = cvRound(val), idelta = cvRound(delta);
if( fabs(val - ival) < DBL_EPSILON &&
fabs(delta - idelta) < DBL_EPSILON )
{
for( int i = 0; i < rows; i++, idata += step )
for( int j = 0; j < cols; j++, ival += idelta )
idata[j] = ival;
}
else
{
for( int i = 0; i < rows; i++, idata += step )
for( int j = 0; j < cols; j++, val += delta )
idata[j] = cvRound(val);
}
}
else if( type == CV_32FC1 )
{
float* fdata = mat->data.fl;
for( int i = 0; i < rows; i++, fdata += step )
for( int j = 0; j < cols; j++, val += delta )
fdata[j] = (float)val;
}
else
CV_Error( CV_StsUnsupportedFormat, "The function only supports 32sC1 and 32fC1 datatypes" );
return arr;
}
CV_IMPL void
cvSort( const CvArr* _src, CvArr* _dst, CvArr* _idx, int flags )
{
cv::Mat src = cv::cvarrToMat(_src);
if( _idx )
{
cv::Mat idx0 = cv::cvarrToMat(_idx), idx = idx0;
CV_Assert( src.size() == idx.size() && idx.type() == CV_32S && src.data != idx.data );
cv::sortIdx( src, idx, flags );
CV_Assert( idx0.data == idx.data );
}
if( _dst )
{
cv::Mat dst0 = cv::cvarrToMat(_dst), dst = dst0;
CV_Assert( src.size() == dst.size() && src.type() == dst.type() );
cv::sort( src, dst, flags );
CV_Assert( dst0.data == dst.data );
}
}
CV_IMPL int
cvKMeans2( const CvArr* _samples, int cluster_count, CvArr* _labels,
CvTermCriteria termcrit, int attempts, CvRNG*,
int flags, CvArr* _centers, double* _compactness )
{
cv::Mat data = cv::cvarrToMat(_samples), labels = cv::cvarrToMat(_labels), centers;
if( _centers )
{
centers = cv::cvarrToMat(_centers);
centers = centers.reshape(1);
data = data.reshape(1);
CV_Assert( !centers.empty() );
CV_Assert( centers.rows == cluster_count );
CV_Assert( centers.cols == data.cols );
CV_Assert( centers.depth() == data.depth() );
}
CV_Assert( labels.isContinuous() && labels.type() == CV_32S &&
(labels.cols == 1 || labels.rows == 1) &&
labels.cols + labels.rows - 1 == data.rows );
double compactness = cv::kmeans(data, cluster_count, labels, termcrit, attempts,
flags, _centers ? cv::_OutputArray(centers) : cv::_OutputArray() );
if( _compactness )
*_compactness = compactness;
return 1;
}

@ -1,44 +1,7 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html
#include "precomp.hpp"
@ -371,5 +334,4 @@ bool Cholesky(double* A, size_t astep, int m, double* b, size_t bstep, int n)
return CholImpl(A, astep, m, b, bstep, n);
}
}}
}} // cv::hal::

@ -1,44 +1,7 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009-2010, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html
/* ////////////////////////////////////////////////////////////////////
//
@ -1769,6 +1732,4 @@ MatExpr Mat::eye(Size size, int type)
return e;
}
}
/* End of file. */
} // cv::

@ -0,0 +1,358 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html
#include "opencv2/core/mat.hpp"
#include "precomp.hpp"
namespace cv {
NAryMatIterator::NAryMatIterator()
: arrays(0), planes(0), ptrs(0), narrays(0), nplanes(0), size(0), iterdepth(0), idx(0)
{
}
NAryMatIterator::NAryMatIterator(const Mat** _arrays, Mat* _planes, int _narrays)
: arrays(0), planes(0), ptrs(0), narrays(0), nplanes(0), size(0), iterdepth(0), idx(0)
{
init(_arrays, _planes, 0, _narrays);
}
NAryMatIterator::NAryMatIterator(const Mat** _arrays, uchar** _ptrs, int _narrays)
: arrays(0), planes(0), ptrs(0), narrays(0), nplanes(0), size(0), iterdepth(0), idx(0)
{
init(_arrays, 0, _ptrs, _narrays);
}
void NAryMatIterator::init(const Mat** _arrays, Mat* _planes, uchar** _ptrs, int _narrays)
{
CV_Assert( _arrays && (_ptrs || _planes) );
int i, j, d1=0, i0 = -1, d = -1;
arrays = _arrays;
ptrs = _ptrs;
planes = _planes;
narrays = _narrays;
nplanes = 0;
size = 0;
if( narrays < 0 )
{
for( i = 0; _arrays[i] != 0; i++ )
;
narrays = i;
CV_Assert(narrays <= 1000);
}
iterdepth = 0;
for( i = 0; i < narrays; i++ )
{
CV_Assert(arrays[i] != 0);
const Mat& A = *arrays[i];
if( ptrs )
ptrs[i] = A.data;
if( !A.data )
continue;
if( i0 < 0 )
{
i0 = i;
d = A.dims;
// find the first dimensionality which is different from 1;
// in any of the arrays the first "d1" step do not affect the continuity
for( d1 = 0; d1 < d; d1++ )
if( A.size[d1] > 1 )
break;
}
else
CV_Assert( A.size == arrays[i0]->size );
if( !A.isContinuous() )
{
CV_Assert( A.step[d-1] == A.elemSize() );
for( j = d-1; j > d1; j-- )
if( A.step[j]*A.size[j] < A.step[j-1] )
break;
iterdepth = std::max(iterdepth, j);
}
}
if( i0 >= 0 )
{
size = arrays[i0]->size[d-1];
for( j = d-1; j > iterdepth; j-- )
{
int64 total1 = (int64)size*arrays[i0]->size[j-1];
if( total1 != (int)total1 )
break;
size = (int)total1;
}
iterdepth = j;
if( iterdepth == d1 )
iterdepth = 0;
nplanes = 1;
for( j = iterdepth-1; j >= 0; j-- )
nplanes *= arrays[i0]->size[j];
}
else
iterdepth = 0;
idx = 0;
if( !planes )
return;
for( i = 0; i < narrays; i++ )
{
CV_Assert(arrays[i] != 0);
const Mat& A = *arrays[i];
if( !A.data )
{
planes[i] = Mat();
continue;
}
planes[i] = Mat(1, (int)size, A.type(), A.data);
}
}
NAryMatIterator& NAryMatIterator::operator ++()
{
if( idx >= nplanes-1 )
return *this;
++idx;
if( iterdepth == 1 )
{
if( ptrs )
{
for( int i = 0; i < narrays; i++ )
{
if( !ptrs[i] )
continue;
ptrs[i] = arrays[i]->data + arrays[i]->step[0]*idx;
}
}
if( planes )
{
for( int i = 0; i < narrays; i++ )
{
if( !planes[i].data )
continue;
planes[i].data = arrays[i]->data + arrays[i]->step[0]*idx;
}
}
}
else
{
for( int i = 0; i < narrays; i++ )
{
const Mat& A = *arrays[i];
if( !A.data )
continue;
int _idx = (int)idx;
uchar* data = A.data;
for( int j = iterdepth-1; j >= 0 && _idx > 0; j-- )
{
int szi = A.size[j], t = _idx/szi;
data += (_idx - t * szi)*A.step[j];
_idx = t;
}
if( ptrs )
ptrs[i] = data;
if( planes )
planes[i].data = data;
}
}
return *this;
}
NAryMatIterator NAryMatIterator::operator ++(int)
{
NAryMatIterator it = *this;
++*this;
return it;
}
//==================================================================================================
Point MatConstIterator::pos() const
{
if( !m )
return Point();
CV_DbgAssert(m->dims <= 2);
ptrdiff_t ofs = ptr - m->ptr();
int y = (int)(ofs/m->step[0]);
return Point((int)((ofs - y*m->step[0])/elemSize), y);
}
void MatConstIterator::pos(int* _idx) const
{
CV_Assert(m != 0 && _idx);
ptrdiff_t ofs = ptr - m->ptr();
for( int i = 0; i < m->dims; i++ )
{
size_t s = m->step[i], v = ofs/s;
ofs -= v*s;
_idx[i] = (int)v;
}
}
ptrdiff_t MatConstIterator::lpos() const
{
if(!m)
return 0;
if( m->isContinuous() )
return (ptr - sliceStart)/elemSize;
ptrdiff_t ofs = ptr - m->ptr();
int i, d = m->dims;
if( d == 2 )
{
ptrdiff_t y = ofs/m->step[0];
return y*m->cols + (ofs - y*m->step[0])/elemSize;
}
ptrdiff_t result = 0;
for( i = 0; i < d; i++ )
{
size_t s = m->step[i], v = ofs/s;
ofs -= v*s;
result = result*m->size[i] + v;
}
return result;
}
void MatConstIterator::seek(ptrdiff_t ofs, bool relative)
{
if( m->isContinuous() )
{
ptr = (relative ? ptr : sliceStart) + ofs*elemSize;
if( ptr < sliceStart )
ptr = sliceStart;
else if( ptr > sliceEnd )
ptr = sliceEnd;
return;
}
int d = m->dims;
if( d == 2 )
{
ptrdiff_t ofs0, y;
if( relative )
{
ofs0 = ptr - m->ptr();
y = ofs0/m->step[0];
ofs += y*m->cols + (ofs0 - y*m->step[0])/elemSize;
}
y = ofs/m->cols;
int y1 = std::min(std::max((int)y, 0), m->rows-1);
sliceStart = m->ptr(y1);
sliceEnd = sliceStart + m->cols*elemSize;
ptr = y < 0 ? sliceStart : y >= m->rows ? sliceEnd :
sliceStart + (ofs - y*m->cols)*elemSize;
return;
}
if( relative )
ofs += lpos();
if( ofs < 0 )
ofs = 0;
int szi = m->size[d-1];
ptrdiff_t t = ofs/szi;
int v = (int)(ofs - t*szi);
ofs = t;
ptr = m->ptr() + v*elemSize;
sliceStart = m->ptr();
for( int i = d-2; i >= 0; i-- )
{
szi = m->size[i];
t = ofs/szi;
v = (int)(ofs - t*szi);
ofs = t;
sliceStart += v*m->step[i];
}
sliceEnd = sliceStart + m->size[d-1]*elemSize;
if( ofs > 0 )
ptr = sliceEnd;
else
ptr = sliceStart + (ptr - m->ptr());
}
void MatConstIterator::seek(const int* _idx, bool relative)
{
int d = m->dims;
ptrdiff_t ofs = 0;
if( !_idx )
;
else if( d == 2 )
ofs = _idx[0]*m->size[1] + _idx[1];
else
{
for( int i = 0; i < d; i++ )
ofs = ofs*m->size[i] + _idx[i];
}
seek(ofs, relative);
}
//==================================================================================================
SparseMatConstIterator::SparseMatConstIterator(const SparseMat* _m) : m((SparseMat*)_m), hashidx(0), ptr(0)
{
if(!_m || !_m->hdr)
return;
SparseMat::Hdr& hdr = *m->hdr;
const std::vector<size_t>& htab = hdr.hashtab;
size_t i, hsize = htab.size();
for( i = 0; i < hsize; i++ )
{
size_t nidx = htab[i];
if( nidx )
{
hashidx = i;
ptr = &hdr.pool[nidx] + hdr.valueOffset;
return;
}
}
}
SparseMatConstIterator& SparseMatConstIterator::operator ++()
{
if( !ptr || !m || !m->hdr )
return *this;
SparseMat::Hdr& hdr = *m->hdr;
size_t next = ((const SparseMat::Node*)(ptr - hdr.valueOffset))->next;
if( next )
{
ptr = &hdr.pool[next] + hdr.valueOffset;
return *this;
}
size_t i = hashidx + 1, sz = hdr.hashtab.size();
for( ; i < sz; i++ )
{
size_t nidx = hdr.hashtab[i];
if( nidx )
{
hashidx = i;
ptr = &hdr.pool[nidx] + hdr.valueOffset;
return *this;
}
}
hashidx = sz;
ptr = 0;
return *this;
}
} // cv::

File diff suppressed because it is too large Load Diff

@ -0,0 +1,802 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html
#include "opencv2/core/mat.hpp"
#include "opencv2/core/types_c.h"
#include "precomp.hpp"
namespace cv {
template<typename T1, typename T2> void
convertData_(const void* _from, void* _to, int cn)
{
const T1* from = (const T1*)_from;
T2* to = (T2*)_to;
if( cn == 1 )
*to = saturate_cast<T2>(*from);
else
for( int i = 0; i < cn; i++ )
to[i] = saturate_cast<T2>(from[i]);
}
template<typename T1, typename T2> void
convertScaleData_(const void* _from, void* _to, int cn, double alpha, double beta)
{
const T1* from = (const T1*)_from;
T2* to = (T2*)_to;
if( cn == 1 )
*to = saturate_cast<T2>(*from*alpha + beta);
else
for( int i = 0; i < cn; i++ )
to[i] = saturate_cast<T2>(from[i]*alpha + beta);
}
typedef void (*ConvertData)(const void* from, void* to, int cn);
typedef void (*ConvertScaleData)(const void* from, void* to, int cn, double alpha, double beta);
static ConvertData getConvertElem(int fromType, int toType)
{
static ConvertData tab[][8] =
{{ convertData_<uchar, uchar>, convertData_<uchar, schar>,
convertData_<uchar, ushort>, convertData_<uchar, short>,
convertData_<uchar, int>, convertData_<uchar, float>,
convertData_<uchar, double>, 0 },
{ convertData_<schar, uchar>, convertData_<schar, schar>,
convertData_<schar, ushort>, convertData_<schar, short>,
convertData_<schar, int>, convertData_<schar, float>,
convertData_<schar, double>, 0 },
{ convertData_<ushort, uchar>, convertData_<ushort, schar>,
convertData_<ushort, ushort>, convertData_<ushort, short>,
convertData_<ushort, int>, convertData_<ushort, float>,
convertData_<ushort, double>, 0 },
{ convertData_<short, uchar>, convertData_<short, schar>,
convertData_<short, ushort>, convertData_<short, short>,
convertData_<short, int>, convertData_<short, float>,
convertData_<short, double>, 0 },
{ convertData_<int, uchar>, convertData_<int, schar>,
convertData_<int, ushort>, convertData_<int, short>,
convertData_<int, int>, convertData_<int, float>,
convertData_<int, double>, 0 },
{ convertData_<float, uchar>, convertData_<float, schar>,
convertData_<float, ushort>, convertData_<float, short>,
convertData_<float, int>, convertData_<float, float>,
convertData_<float, double>, 0 },
{ convertData_<double, uchar>, convertData_<double, schar>,
convertData_<double, ushort>, convertData_<double, short>,
convertData_<double, int>, convertData_<double, float>,
convertData_<double, double>, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 }};
ConvertData func = tab[CV_MAT_DEPTH(fromType)][CV_MAT_DEPTH(toType)];
CV_Assert( func != 0 );
return func;
}
static ConvertScaleData getConvertScaleElem(int fromType, int toType)
{
static ConvertScaleData tab[][8] =
{{ convertScaleData_<uchar, uchar>, convertScaleData_<uchar, schar>,
convertScaleData_<uchar, ushort>, convertScaleData_<uchar, short>,
convertScaleData_<uchar, int>, convertScaleData_<uchar, float>,
convertScaleData_<uchar, double>, 0 },
{ convertScaleData_<schar, uchar>, convertScaleData_<schar, schar>,
convertScaleData_<schar, ushort>, convertScaleData_<schar, short>,
convertScaleData_<schar, int>, convertScaleData_<schar, float>,
convertScaleData_<schar, double>, 0 },
{ convertScaleData_<ushort, uchar>, convertScaleData_<ushort, schar>,
convertScaleData_<ushort, ushort>, convertScaleData_<ushort, short>,
convertScaleData_<ushort, int>, convertScaleData_<ushort, float>,
convertScaleData_<ushort, double>, 0 },
{ convertScaleData_<short, uchar>, convertScaleData_<short, schar>,
convertScaleData_<short, ushort>, convertScaleData_<short, short>,
convertScaleData_<short, int>, convertScaleData_<short, float>,
convertScaleData_<short, double>, 0 },
{ convertScaleData_<int, uchar>, convertScaleData_<int, schar>,
convertScaleData_<int, ushort>, convertScaleData_<int, short>,
convertScaleData_<int, int>, convertScaleData_<int, float>,
convertScaleData_<int, double>, 0 },
{ convertScaleData_<float, uchar>, convertScaleData_<float, schar>,
convertScaleData_<float, ushort>, convertScaleData_<float, short>,
convertScaleData_<float, int>, convertScaleData_<float, float>,
convertScaleData_<float, double>, 0 },
{ convertScaleData_<double, uchar>, convertScaleData_<double, schar>,
convertScaleData_<double, ushort>, convertScaleData_<double, short>,
convertScaleData_<double, int>, convertScaleData_<double, float>,
convertScaleData_<double, double>, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 }};
ConvertScaleData func = tab[CV_MAT_DEPTH(fromType)][CV_MAT_DEPTH(toType)];
CV_Assert( func != 0 );
return func;
}
enum { HASH_SIZE0 = 8 };
static inline void copyElem(const uchar* from, uchar* to, size_t elemSize)
{
size_t i;
for( i = 0; i + sizeof(int) <= elemSize; i += sizeof(int) )
*(int*)(to + i) = *(const int*)(from + i);
for( ; i < elemSize; i++ )
to[i] = from[i];
}
static inline bool isZeroElem(const uchar* data, size_t elemSize)
{
size_t i;
for( i = 0; i + sizeof(int) <= elemSize; i += sizeof(int) )
if( *(int*)(data + i) != 0 )
return false;
for( ; i < elemSize; i++ )
if( data[i] != 0 )
return false;
return true;
}
SparseMat::Hdr::Hdr( int _dims, const int* _sizes, int _type )
{
refcount = 1;
dims = _dims;
valueOffset = (int)alignSize(sizeof(SparseMat::Node) - MAX_DIM*sizeof(int) +
dims*sizeof(int), CV_ELEM_SIZE1(_type));
nodeSize = alignSize(valueOffset +
CV_ELEM_SIZE(_type), (int)sizeof(size_t));
int i;
for( i = 0; i < dims; i++ )
size[i] = _sizes[i];
for( ; i < CV_MAX_DIM; i++ )
size[i] = 0;
clear();
}
void SparseMat::Hdr::clear()
{
hashtab.clear();
hashtab.resize(HASH_SIZE0);
pool.clear();
pool.resize(nodeSize);
nodeCount = freeList = 0;
}
SparseMat::SparseMat(const Mat& m)
: flags(MAGIC_VAL), hdr(0)
{
create( m.dims, m.size, m.type() );
int i, idx[CV_MAX_DIM] = {0}, d = m.dims, lastSize = m.size[d - 1];
size_t esz = m.elemSize();
const uchar* dptr = m.ptr();
for(;;)
{
for( i = 0; i < lastSize; i++, dptr += esz )
{
if( isZeroElem(dptr, esz) )
continue;
idx[d-1] = i;
uchar* to = newNode(idx, hash(idx));
copyElem( dptr, to, esz );
}
for( i = d - 2; i >= 0; i-- )
{
dptr += m.step[i] - m.size[i+1]*m.step[i+1];
if( ++idx[i] < m.size[i] )
break;
idx[i] = 0;
}
if( i < 0 )
break;
}
}
void SparseMat::create(int d, const int* _sizes, int _type)
{
CV_Assert( _sizes && 0 < d && d <= CV_MAX_DIM );
for( int i = 0; i < d; i++ )
CV_Assert( _sizes[i] > 0 );
_type = CV_MAT_TYPE(_type);
if( hdr && _type == type() && hdr->dims == d && hdr->refcount == 1 )
{
int i;
for( i = 0; i < d; i++ )
if( _sizes[i] != hdr->size[i] )
break;
if( i == d )
{
clear();
return;
}
}
int _sizes_backup[CV_MAX_DIM]; // #5991
if (_sizes == hdr->size)
{
for(int i = 0; i < d; i++ )
_sizes_backup[i] = _sizes[i];
_sizes = _sizes_backup;
}
release();
flags = MAGIC_VAL | _type;
hdr = new Hdr(d, _sizes, _type);
}
void SparseMat::copyTo( SparseMat& m ) const
{
if( hdr == m.hdr )
return;
if( !hdr )
{
m.release();
return;
}
m.create( hdr->dims, hdr->size, type() );
SparseMatConstIterator from = begin();
size_t N = nzcount(), esz = elemSize();
for( size_t i = 0; i < N; i++, ++from )
{
const Node* n = from.node();
uchar* to = m.newNode(n->idx, n->hashval);
copyElem( from.ptr, to, esz );
}
}
void SparseMat::copyTo( Mat& m ) const
{
CV_Assert( hdr );
int ndims = dims();
m.create( ndims, hdr->size, type() );
m = Scalar(0);
SparseMatConstIterator from = begin();
size_t N = nzcount(), esz = elemSize();
for( size_t i = 0; i < N; i++, ++from )
{
const Node* n = from.node();
copyElem( from.ptr, (ndims > 1 ? m.ptr(n->idx) : m.ptr(n->idx[0])), esz);
}
}
void SparseMat::convertTo( SparseMat& m, int rtype, double alpha ) const
{
int cn = channels();
if( rtype < 0 )
rtype = type();
rtype = CV_MAKETYPE(rtype, cn);
if( hdr == m.hdr && rtype != type() )
{
SparseMat temp;
convertTo(temp, rtype, alpha);
m = temp;
return;
}
CV_Assert(hdr != 0);
if( hdr != m.hdr )
m.create( hdr->dims, hdr->size, rtype );
SparseMatConstIterator from = begin();
size_t N = nzcount();
if( alpha == 1 )
{
ConvertData cvtfunc = getConvertElem(type(), rtype);
for( size_t i = 0; i < N; i++, ++from )
{
const Node* n = from.node();
uchar* to = hdr == m.hdr ? from.ptr : m.newNode(n->idx, n->hashval);
cvtfunc( from.ptr, to, cn );
}
}
else
{
ConvertScaleData cvtfunc = getConvertScaleElem(type(), rtype);
for( size_t i = 0; i < N; i++, ++from )
{
const Node* n = from.node();
uchar* to = hdr == m.hdr ? from.ptr : m.newNode(n->idx, n->hashval);
cvtfunc( from.ptr, to, cn, alpha, 0 );
}
}
}
void SparseMat::convertTo( Mat& m, int rtype, double alpha, double beta ) const
{
int cn = channels();
if( rtype < 0 )
rtype = type();
rtype = CV_MAKETYPE(rtype, cn);
CV_Assert( hdr );
m.create( dims(), hdr->size, rtype );
m = Scalar(beta);
SparseMatConstIterator from = begin();
size_t N = nzcount();
if( alpha == 1 && beta == 0 )
{
ConvertData cvtfunc = getConvertElem(type(), rtype);
for( size_t i = 0; i < N; i++, ++from )
{
const Node* n = from.node();
uchar* to = m.ptr(n->idx);
cvtfunc( from.ptr, to, cn );
}
}
else
{
ConvertScaleData cvtfunc = getConvertScaleElem(type(), rtype);
for( size_t i = 0; i < N; i++, ++from )
{
const Node* n = from.node();
uchar* to = m.ptr(n->idx);
cvtfunc( from.ptr, to, cn, alpha, beta );
}
}
}
void SparseMat::clear()
{
if( hdr )
hdr->clear();
}
uchar* SparseMat::ptr(int i0, bool createMissing, size_t* hashval)
{
CV_Assert( hdr && hdr->dims == 1 );
size_t h = hashval ? *hashval : hash(i0);
size_t hidx = h & (hdr->hashtab.size() - 1), nidx = hdr->hashtab[hidx];
uchar* pool = &hdr->pool[0];
while( nidx != 0 )
{
Node* elem = (Node*)(pool + nidx);
if( elem->hashval == h && elem->idx[0] == i0 )
return &value<uchar>(elem);
nidx = elem->next;
}
if( createMissing )
{
int idx[] = { i0 };
return newNode( idx, h );
}
return NULL;
}
uchar* SparseMat::ptr(int i0, int i1, bool createMissing, size_t* hashval)
{
CV_Assert( hdr && hdr->dims == 2 );
size_t h = hashval ? *hashval : hash(i0, i1);
size_t hidx = h & (hdr->hashtab.size() - 1), nidx = hdr->hashtab[hidx];
uchar* pool = &hdr->pool[0];
while( nidx != 0 )
{
Node* elem = (Node*)(pool + nidx);
if( elem->hashval == h && elem->idx[0] == i0 && elem->idx[1] == i1 )
return &value<uchar>(elem);
nidx = elem->next;
}
if( createMissing )
{
int idx[] = { i0, i1 };
return newNode( idx, h );
}
return NULL;
}
uchar* SparseMat::ptr(int i0, int i1, int i2, bool createMissing, size_t* hashval)
{
CV_Assert( hdr && hdr->dims == 3 );
size_t h = hashval ? *hashval : hash(i0, i1, i2);
size_t hidx = h & (hdr->hashtab.size() - 1), nidx = hdr->hashtab[hidx];
uchar* pool = &hdr->pool[0];
while( nidx != 0 )
{
Node* elem = (Node*)(pool + nidx);
if( elem->hashval == h && elem->idx[0] == i0 &&
elem->idx[1] == i1 && elem->idx[2] == i2 )
return &value<uchar>(elem);
nidx = elem->next;
}
if( createMissing )
{
int idx[] = { i0, i1, i2 };
return newNode( idx, h );
}
return NULL;
}
uchar* SparseMat::ptr(const int* idx, bool createMissing, size_t* hashval)
{
CV_Assert( hdr );
int i, d = hdr->dims;
size_t h = hashval ? *hashval : hash(idx);
size_t hidx = h & (hdr->hashtab.size() - 1), nidx = hdr->hashtab[hidx];
uchar* pool = &hdr->pool[0];
while( nidx != 0 )
{
Node* elem = (Node*)(pool + nidx);
if( elem->hashval == h )
{
for( i = 0; i < d; i++ )
if( elem->idx[i] != idx[i] )
break;
if( i == d )
return &value<uchar>(elem);
}
nidx = elem->next;
}
return createMissing ? newNode(idx, h) : NULL;
}
void SparseMat::erase(int i0, int i1, size_t* hashval)
{
CV_Assert( hdr && hdr->dims == 2 );
size_t h = hashval ? *hashval : hash(i0, i1);
size_t hidx = h & (hdr->hashtab.size() - 1), nidx = hdr->hashtab[hidx], previdx=0;
uchar* pool = &hdr->pool[0];
while( nidx != 0 )
{
Node* elem = (Node*)(pool + nidx);
if( elem->hashval == h && elem->idx[0] == i0 && elem->idx[1] == i1 )
break;
previdx = nidx;
nidx = elem->next;
}
if( nidx )
removeNode(hidx, nidx, previdx);
}
void SparseMat::erase(int i0, int i1, int i2, size_t* hashval)
{
CV_Assert( hdr && hdr->dims == 3 );
size_t h = hashval ? *hashval : hash(i0, i1, i2);
size_t hidx = h & (hdr->hashtab.size() - 1), nidx = hdr->hashtab[hidx], previdx=0;
uchar* pool = &hdr->pool[0];
while( nidx != 0 )
{
Node* elem = (Node*)(pool + nidx);
if( elem->hashval == h && elem->idx[0] == i0 &&
elem->idx[1] == i1 && elem->idx[2] == i2 )
break;
previdx = nidx;
nidx = elem->next;
}
if( nidx )
removeNode(hidx, nidx, previdx);
}
void SparseMat::erase(const int* idx, size_t* hashval)
{
CV_Assert( hdr );
int i, d = hdr->dims;
size_t h = hashval ? *hashval : hash(idx);
size_t hidx = h & (hdr->hashtab.size() - 1), nidx = hdr->hashtab[hidx], previdx=0;
uchar* pool = &hdr->pool[0];
while( nidx != 0 )
{
Node* elem = (Node*)(pool + nidx);
if( elem->hashval == h )
{
for( i = 0; i < d; i++ )
if( elem->idx[i] != idx[i] )
break;
if( i == d )
break;
}
previdx = nidx;
nidx = elem->next;
}
if( nidx )
removeNode(hidx, nidx, previdx);
}
void SparseMat::resizeHashTab(size_t newsize)
{
newsize = std::max(newsize, (size_t)8);
if((newsize & (newsize-1)) != 0)
newsize = (size_t)1 << cvCeil(std::log((double)newsize)/CV_LOG2);
size_t hsize = hdr->hashtab.size();
std::vector<size_t> _newh(newsize);
size_t* newh = &_newh[0];
for( size_t i = 0; i < newsize; i++ )
newh[i] = 0;
uchar* pool = &hdr->pool[0];
for( size_t i = 0; i < hsize; i++ )
{
size_t nidx = hdr->hashtab[i];
while( nidx )
{
Node* elem = (Node*)(pool + nidx);
size_t next = elem->next;
size_t newhidx = elem->hashval & (newsize - 1);
elem->next = newh[newhidx];
newh[newhidx] = nidx;
nidx = next;
}
}
hdr->hashtab = _newh;
}
uchar* SparseMat::newNode(const int* idx, size_t hashval)
{
const int HASH_MAX_FILL_FACTOR=3;
assert(hdr);
size_t hsize = hdr->hashtab.size();
if( ++hdr->nodeCount > hsize*HASH_MAX_FILL_FACTOR )
{
resizeHashTab(std::max(hsize*2, (size_t)8));
hsize = hdr->hashtab.size();
}
if( !hdr->freeList )
{
size_t i, nsz = hdr->nodeSize, psize = hdr->pool.size(),
newpsize = std::max(psize*3/2, 8*nsz);
newpsize = (newpsize/nsz)*nsz;
hdr->pool.resize(newpsize);
uchar* pool = &hdr->pool[0];
hdr->freeList = std::max(psize, nsz);
for( i = hdr->freeList; i < newpsize - nsz; i += nsz )
((Node*)(pool + i))->next = i + nsz;
((Node*)(pool + i))->next = 0;
}
size_t nidx = hdr->freeList;
Node* elem = (Node*)&hdr->pool[nidx];
hdr->freeList = elem->next;
elem->hashval = hashval;
size_t hidx = hashval & (hsize - 1);
elem->next = hdr->hashtab[hidx];
hdr->hashtab[hidx] = nidx;
int i, d = hdr->dims;
for( i = 0; i < d; i++ )
elem->idx[i] = idx[i];
size_t esz = elemSize();
uchar* p = &value<uchar>(elem);
if( esz == sizeof(float) )
*((float*)p) = 0.f;
else if( esz == sizeof(double) )
*((double*)p) = 0.;
else
memset(p, 0, esz);
return p;
}
void SparseMat::removeNode(size_t hidx, size_t nidx, size_t previdx)
{
Node* n = node(nidx);
if( previdx )
{
Node* prev = node(previdx);
prev->next = n->next;
}
else
hdr->hashtab[hidx] = n->next;
n->next = hdr->freeList;
hdr->freeList = nidx;
--hdr->nodeCount;
}
//
// Operations
//
double norm( const SparseMat& src, int normType )
{
CV_INSTRUMENT_REGION()
SparseMatConstIterator it = src.begin();
size_t i, N = src.nzcount();
normType &= NORM_TYPE_MASK;
int type = src.type();
double result = 0;
CV_Assert( normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2 );
if( type == CV_32F )
{
if( normType == NORM_INF )
for( i = 0; i < N; i++, ++it )
{
CV_Assert(it.ptr);
result = std::max(result, std::abs((double)it.value<float>()));
}
else if( normType == NORM_L1 )
for( i = 0; i < N; i++, ++it )
{
CV_Assert(it.ptr);
result += std::abs(it.value<float>());
}
else
for( i = 0; i < N; i++, ++it )
{
CV_Assert(it.ptr);
double v = it.value<float>();
result += v*v;
}
}
else if( type == CV_64F )
{
if( normType == NORM_INF )
for( i = 0; i < N; i++, ++it )
{
CV_Assert(it.ptr);
result = std::max(result, std::abs(it.value<double>()));
}
else if( normType == NORM_L1 )
for( i = 0; i < N; i++, ++it )
{
CV_Assert(it.ptr);
result += std::abs(it.value<double>());
}
else
for( i = 0; i < N; i++, ++it )
{
CV_Assert(it.ptr);
double v = it.value<double>();
result += v*v;
}
}
else
CV_Error( CV_StsUnsupportedFormat, "Only 32f and 64f are supported" );
if( normType == NORM_L2 )
result = std::sqrt(result);
return result;
}
void minMaxLoc( const SparseMat& src, double* _minval, double* _maxval, int* _minidx, int* _maxidx )
{
CV_INSTRUMENT_REGION()
SparseMatConstIterator it = src.begin();
size_t i, N = src.nzcount(), d = src.hdr ? src.hdr->dims : 0;
int type = src.type();
const int *minidx = 0, *maxidx = 0;
if( type == CV_32F )
{
float minval = FLT_MAX, maxval = -FLT_MAX;
for( i = 0; i < N; i++, ++it )
{
CV_Assert(it.ptr);
float v = it.value<float>();
if( v < minval )
{
minval = v;
minidx = it.node()->idx;
}
if( v > maxval )
{
maxval = v;
maxidx = it.node()->idx;
}
}
if( _minval )
*_minval = minval;
if( _maxval )
*_maxval = maxval;
}
else if( type == CV_64F )
{
double minval = DBL_MAX, maxval = -DBL_MAX;
for( i = 0; i < N; i++, ++it )
{
CV_Assert(it.ptr);
double v = it.value<double>();
if( v < minval )
{
minval = v;
minidx = it.node()->idx;
}
if( v > maxval )
{
maxval = v;
maxidx = it.node()->idx;
}
}
if( _minval )
*_minval = minval;
if( _maxval )
*_maxval = maxval;
}
else
CV_Error( CV_StsUnsupportedFormat, "Only 32f and 64f are supported" );
if( _minidx && minidx )
for( i = 0; i < d; i++ )
_minidx[i] = minidx[i];
if( _maxidx && maxidx )
for( i = 0; i < d; i++ )
_maxidx[i] = maxidx[i];
}
void normalize( const SparseMat& src, SparseMat& dst, double a, int norm_type )
{
CV_INSTRUMENT_REGION()
double scale = 1;
if( norm_type == CV_L2 || norm_type == CV_L1 || norm_type == CV_C )
{
scale = norm( src, norm_type );
scale = scale > DBL_EPSILON ? a/scale : 0.;
}
else
CV_Error( CV_StsBadArg, "Unknown/unsupported norm type" );
src.convertTo( dst, -1, scale );
}
} // cv::
//
// C-API glue
//
CvSparseMat* cvCreateSparseMat(const cv::SparseMat& sm)
{
if( !sm.hdr || sm.hdr->dims > (int)cv::SparseMat::MAX_DIM)
return 0;
CvSparseMat* m = cvCreateSparseMat(sm.hdr->dims, sm.hdr->size, sm.type());
cv::SparseMatConstIterator from = sm.begin();
size_t i, N = sm.nzcount(), esz = sm.elemSize();
for( i = 0; i < N; i++, ++from )
{
const cv::SparseMat::Node* n = from.node();
uchar* to = cvPtrND(m, n->idx, 0, -2, 0);
cv::copyElem(from.ptr, to, esz);
}
return m;
}
void CvSparseMat::copyToSparseMat(cv::SparseMat& m) const
{
m.create( dims, &size[0], type );
CvSparseMatIterator it;
CvSparseNode* n = cvInitSparseMatIterator(this, &it);
size_t esz = m.elemSize();
for( ; n != 0; n = cvGetNextSparseNode(&it) )
{
const int* idx = CV_NODE_IDX(this, n);
uchar* to = m.newNode(idx, m.hash(idx));
cv::copyElem((const uchar*)CV_NODE_VAL(this, n), to, esz);
}
}

File diff suppressed because it is too large Load Diff

@ -190,6 +190,9 @@ inline Size getContinuousSize( const Mat& m1, const Mat& m2,
m1.cols, m1.rows, widthScale);
}
void setSize( Mat& m, int _dims, const int* _sz, const size_t* _steps, bool autoSteps=false );
void finalizeHdr(Mat& m);
struct NoVec
{
size_t operator()(const void*, const void*, void*, size_t) const { return 0; }

@ -46,6 +46,8 @@
namespace cv
{
////////////////////// KeyPoint //////////////////////
size_t KeyPoint::hash() const
{
size_t _Val = 2166136261U, scale = 16777619U;
@ -140,4 +142,69 @@ float KeyPoint::overlap( const KeyPoint& kp1, const KeyPoint& kp2 )
return ovrl;
}
////////////////////// RotatedRect //////////////////////
RotatedRect::RotatedRect(const Point2f& _point1, const Point2f& _point2, const Point2f& _point3)
{
Point2f _center = 0.5f * (_point1 + _point3);
Vec2f vecs[2];
vecs[0] = Vec2f(_point1 - _point2);
vecs[1] = Vec2f(_point2 - _point3);
// check that given sides are perpendicular
CV_Assert( abs(vecs[0].dot(vecs[1])) / (norm(vecs[0]) * norm(vecs[1])) <= FLT_EPSILON );
// wd_i stores which vector (0,1) or (1,2) will make the width
// One of them will definitely have slope within -1 to 1
int wd_i = 0;
if( abs(vecs[1][1]) < abs(vecs[1][0]) ) wd_i = 1;
int ht_i = (wd_i + 1) % 2;
float _angle = atan(vecs[wd_i][1] / vecs[wd_i][0]) * 180.0f / (float) CV_PI;
float _width = (float) norm(vecs[wd_i]);
float _height = (float) norm(vecs[ht_i]);
center = _center;
size = Size2f(_width, _height);
angle = _angle;
}
void RotatedRect::points(Point2f pt[]) const
{
double _angle = angle*CV_PI/180.;
float b = (float)cos(_angle)*0.5f;
float a = (float)sin(_angle)*0.5f;
pt[0].x = center.x - a*size.height - b*size.width;
pt[0].y = center.y + b*size.height - a*size.width;
pt[1].x = center.x + a*size.height - b*size.width;
pt[1].y = center.y - b*size.height - a*size.width;
pt[2].x = 2*center.x - pt[0].x;
pt[2].y = 2*center.y - pt[0].y;
pt[3].x = 2*center.x - pt[1].x;
pt[3].y = 2*center.y - pt[1].y;
}
Rect RotatedRect::boundingRect() const
{
Point2f pt[4];
points(pt);
Rect r(cvFloor(std::min(std::min(std::min(pt[0].x, pt[1].x), pt[2].x), pt[3].x)),
cvFloor(std::min(std::min(std::min(pt[0].y, pt[1].y), pt[2].y), pt[3].y)),
cvCeil(std::max(std::max(std::max(pt[0].x, pt[1].x), pt[2].x), pt[3].x)),
cvCeil(std::max(std::max(std::max(pt[0].y, pt[1].y), pt[2].y), pt[3].y)));
r.width -= r.x - 1;
r.height -= r.y - 1;
return r;
}
Rect_<float> RotatedRect::boundingRect2f() const
{
Point2f pt[4];
points(pt);
Rect_<float> r(Point_<float>(min(min(min(pt[0].x, pt[1].x), pt[2].x), pt[3].x), min(min(min(pt[0].y, pt[1].y), pt[2].y), pt[3].y)),
Point_<float>(max(max(max(pt[0].x, pt[1].x), pt[2].x), pt[3].x), max(max(max(pt[0].y, pt[1].y), pt[2].y), pt[3].y)));
return r;
}
} // cv

Loading…
Cancel
Save