a big patch; use special proxy types (Input/OutputArray, Input/OutputArrayOfArrays) for passing in vectors, matrices etc.

This commit is contained in:
Vadim Pisarevsky
2011-04-17 13:14:45 +00:00
parent 335370a7c0
commit abeeb40d46
94 changed files with 10831 additions and 9631 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -722,10 +722,10 @@ icvGetNodePtr( CvSparseMat* mat, const int* idx, int* _type,
node->hashval = hashval;
node->next = (CvSparseNode*)mat->hashtable[tabidx];
mat->hashtable[tabidx] = node;
CV_MEMCPY_INT( CV_NODE_IDX(mat,node), idx, mat->dims );
memcpy(CV_NODE_IDX(mat,node), idx, mat->dims*sizeof(idx[0]));
ptr = (uchar*)CV_NODE_VAL(mat,node);
if( create_node > 0 )
CV_ZERO_CHAR( ptr, CV_ELEM_SIZE(mat->type));
memset( ptr, 0, CV_ELEM_SIZE(mat->type));
}
if( _type )
@@ -1512,7 +1512,7 @@ cvScalarToRawData( const CvScalar* scalar, void* data, int type, int extend_to_1
do
{
offset -= pix_size;
CV_MEMCPY_AUTO( (char*)data + offset, data, pix_size );
memcpy((char*)data + offset, data, pix_size);
}
while( offset > pix_size );
}
@@ -2358,7 +2358,7 @@ cvClearND( CvArr* arr, const int* idx )
uchar* ptr;
ptr = cvPtrND( arr, idx, &type );
if( ptr )
CV_ZERO_CHAR( ptr, CV_ELEM_SIZE(type) );
memset( ptr, 0, CV_ELEM_SIZE(type) );
}
else
icvDeleteNode( (CvSparseMat*)arr, idx, 0 );

File diff suppressed because it is too large Load Diff

View File

@@ -11,7 +11,7 @@
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., 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,
@@ -52,18 +52,12 @@ namespace cv
{
template<typename T> static void
copyMask_(const Mat& srcmat, Mat& dstmat, const Mat& maskmat)
copyMask_(const uchar* _src, size_t sstep, const uchar* mask, size_t mstep, uchar* _dst, size_t dstep, Size size)
{
const uchar* mask = maskmat.data;
size_t sstep = srcmat.step;
size_t dstep = dstmat.step;
size_t mstep = maskmat.step;
Size size = getContinuousSize(srcmat, dstmat, maskmat);
for( int y = 0; y < size.height; y++, mask += mstep )
for( ; size.height--; mask += mstep, _src += sstep, _dst += dstep )
{
const T* src = (const T*)(srcmat.data + sstep*y);
T* dst = (T*)(dstmat.data + dstep*y);
const T* src = (const T*)_src;
T* dst = (T*)_dst;
int x = 0;
for( ; x <= size.width - 4; x += 4 )
{
@@ -82,389 +76,397 @@ copyMask_(const Mat& srcmat, Mat& dstmat, const Mat& maskmat)
}
}
template<typename T> static void
setMask_(const void* _scalar, Mat& dstmat, const Mat& maskmat)
static void
copyMaskGeneric(const uchar* _src, size_t sstep, const uchar* mask, size_t mstep, uchar* _dst, size_t dstep, Size size, void* _esz)
{
T scalar = *(T*)_scalar;
const uchar* mask = maskmat.data;
size_t dstep = dstmat.step;
size_t mstep = maskmat.step;
Size size = dstmat.size();
if( dstmat.isContinuous() && maskmat.isContinuous() )
size_t k, esz = *(size_t*)_esz;
for( ; size.height--; mask += mstep, _src += sstep, _dst += dstep )
{
size.width *= size.height;
size.height = 1;
const uchar* src = _src;
uchar* dst = _dst;
int x = 0;
for( ; x < size.width; x++, src += esz, dst += esz )
{
if( !mask[x] )
continue;
for( k = 0; k < esz; k++ )
dst[k] = src[k];
}
}
for( int y = 0; y < size.height; y++, mask += mstep )
}
template<typename T> static void
setMask_(T value, const uchar* mask, size_t mstep, uchar* _dst, size_t dstep, Size size)
{
for( ; size.height--; mask += mstep, _dst += dstep )
{
T* dst = (T*)(dstmat.data + dstep*y);
T* dst = (T*)_dst;
int x = 0;
for( ; x <= size.width - 4; x += 4 )
{
if( mask[x] )
dst[x] = scalar;
dst[x] = value;
if( mask[x+1] )
dst[x+1] = scalar;
dst[x+1] = value;
if( mask[x+2] )
dst[x+2] = scalar;
dst[x+2] = value;
if( mask[x+3] )
dst[x+3] = scalar;
dst[x+3] = value;
}
for( ; x < size.width; x++ )
if( mask[x] )
dst[x] = scalar;
dst[x] = value;
}
}
typedef void (*SetMaskFunc)(const void* scalar, Mat& dst, const Mat& mask);
CopyMaskFunc g_copyMaskFuncTab[] =
static void
setMaskGeneric(const uchar* value, size_t, const uchar* mask, size_t mstep, uchar* _dst, size_t dstep, Size size, void* _esz)
{
size_t k, esz = *(size_t*)_esz;
for( ; size.height--; mask += mstep, _dst += dstep )
{
uchar* dst = _dst;
int x = 0;
for( ; x < size.width; x++, dst += esz )
{
if( !mask[x] )
continue;
for( k = 0; k < esz; k++ )
dst[k] = value[k];
}
}
}
#define DEF_COPY_SET_MASK(suffix, type) \
static void copyMask##suffix(const uchar* src, size_t sstep, const uchar* mask, size_t mstep, \
uchar* dst, size_t dstep, Size size, void*) \
{ \
copyMask_<type>(src, sstep, mask, mstep, dst, dstep, size); \
} \
static void setMask##suffix( const uchar* src, size_t, const uchar* mask, size_t mstep, \
uchar* dst, size_t dstep, Size size, void*) \
{ \
setMask_<type>(*(const type*)src, mask, mstep, dst, dstep, size); \
}
DEF_COPY_SET_MASK(8u, uchar);
DEF_COPY_SET_MASK(16u, ushort);
DEF_COPY_SET_MASK(8uC3, Vec3b);
DEF_COPY_SET_MASK(32s, int);
DEF_COPY_SET_MASK(16uC3, Vec3s);
DEF_COPY_SET_MASK(32sC2, Vec2i);
DEF_COPY_SET_MASK(32sC3, Vec3i);
DEF_COPY_SET_MASK(32sC4, Vec4i);
DEF_COPY_SET_MASK(32sC6, Vec6i);
DEF_COPY_SET_MASK(32sC8, Vec8i);
BinaryFunc copyMaskTab[] =
{
0,
copyMask_<uchar>, // 1
copyMask_<ushort>, // 2
copyMask_<Vec<uchar,3> >, // 3
copyMask_<int>, // 4
copyMask8u,
copyMask16u,
copyMask8uC3,
copyMask32s,
0,
copyMask_<Vec<ushort,3> >, // 6
copyMask16uC3,
0,
copyMask_<Vec<int,2> >, // 8
copyMask32sC2,
0, 0, 0,
copyMask_<Vec<int,3> >, // 12
copyMask32sC3,
0, 0, 0,
copyMask_<Vec<int,4> >, // 16
copyMask32sC4,
0, 0, 0, 0, 0, 0, 0,
copyMask_<Vec<int,6> >, // 24
copyMask32sC6,
0, 0, 0, 0, 0, 0, 0,
copyMask_<Vec<int,8> > // 32
copyMask32sC8
};
static SetMaskFunc setMaskFuncTab[] =
BinaryFunc setMaskTab[] =
{
0,
setMask_<uchar>, // 1
setMask_<ushort>, // 2
setMask_<Vec<uchar,3> >, // 3
setMask_<int>, // 4
setMask8u,
setMask16u,
setMask8uC3,
setMask32s,
0,
setMask_<Vec<ushort,3> >, // 6
setMask16uC3,
0,
setMask_<Vec<int,2> >, // 8
setMask32sC2,
0, 0, 0,
setMask_<Vec<int,3> >, // 12
setMask32sC3,
0, 0, 0,
setMask_<Vec<int,4> >, // 16
setMask32sC4,
0, 0, 0, 0, 0, 0, 0,
setMask_<Vec<int,6> >, // 24
setMask32sC6,
0, 0, 0, 0, 0, 0, 0,
setMask_<Vec<int,8> > // 32
};
setMask32sC8
};
BinaryFunc getCopyMaskFunc(size_t esz)
{
return esz <= 32 && copyMaskTab[esz] ? copyMaskTab[esz] : copyMaskGeneric;
}
/* dst = src */
void Mat::copyTo( Mat& dst ) const
void Mat::copyTo( OutputArray _dst ) const
{
if( data == dst.data && data != 0 )
return;
if( dims > 2 )
int dtype = _dst.type();
if( _dst.fixedType() && dtype != type() )
{
dst.create( dims, size, type() );
if( total() != 0 )
{
const Mat* arrays[] = { this, &dst, 0 };
Mat planes[2];
NAryMatIterator it(arrays, planes);
CV_DbgAssert(it.planes[0].isContinuous() &&
it.planes[1].isContinuous());
size_t planeSize = it.planes[0].elemSize()*it.planes[0].rows*it.planes[0].cols;
convertTo( _dst, dtype );
return;
}
if( empty() )
{
_dst.release();
return;
}
if( dims <= 2 )
{
_dst.create( rows, cols, type() );
Mat dst = _dst.getMat();
if( data == dst.data )
return;
for( int i = 0; i < it.nplanes; i++, ++it )
memcpy(it.planes[1].data, it.planes[0].data, planeSize);
if( rows > 0 && cols > 0 )
{
const uchar* sptr = data;
uchar* dptr = dst.data;
Size sz = getContinuousSize(*this, dst, (int)elemSize());
for( ; sz.height--; sptr += step, dptr += dst.step )
memcpy( dptr, sptr, sz.width );
}
return;
}
dst.create( rows, cols, type() );
Size sz = size();
_dst.create( dims, size, type() );
Mat dst = _dst.getMat();
if( data == dst.data )
return;
if( rows > 0 && cols > 0 )
if( total() != 0 )
{
const uchar* sptr = data;
uchar* dptr = dst.data;
size_t width = sz.width*elemSize();
if( isContinuous() && dst.isContinuous() )
{
width *= sz.height;
sz.height = 1;
}
for( ; sz.height--; sptr += step, dptr += dst.step )
memcpy( dptr, sptr, width );
const Mat* arrays[] = { this, &dst };
uchar* ptrs[2];
NAryMatIterator it(arrays, ptrs, 2);
size_t size = it.size*elemSize();
for( size_t i = 0; i < it.nplanes; i++, ++it )
memcpy(ptrs[1], ptrs[0], size);
}
}
void Mat::copyTo( Mat& dst, const Mat& mask ) const
void Mat::copyTo( OutputArray _dst, const InputArray& _mask ) const
{
Mat mask = _mask.getMat();
if( !mask.data )
{
copyTo(dst);
copyTo(_dst);
return;
}
if( dims > 2 )
{
dst.create( dims, size, type() );
const Mat* arrays[] = { this, &dst, &mask, 0 };
Mat planes[3];
NAryMatIterator it(arrays, planes);
for( int i = 0; i < it.nplanes; i++, ++it )
it.planes[0].copyTo(it.planes[1], it.planes[2]);
return;
}
uchar* data0 = dst.data;
dst.create( size(), type() );
CV_Assert( mask.type() == CV_8U );
size_t esz = elemSize();
BinaryFunc copymask = getCopyMaskFunc(esz);
uchar* data0 = _dst.getMat().data;
_dst.create( dims, size, type() );
Mat dst = _dst.getMat();
if( dst.data != data0 ) // do not leave dst uninitialized
dst = Scalar(0);
getCopyMaskFunc((int)elemSize())(*this, dst, mask);
if( dims <= 2 )
{
Size sz = getContinuousSize(*this, dst, mask);
copymask(data, step, mask.data, mask.step, dst.data, dst.step, sz, &esz);
return;
}
const Mat* arrays[] = { this, &dst, &mask, 0 };
uchar* ptrs[3];
NAryMatIterator it(arrays, ptrs);
Size sz((int)it.size, 1);
for( size_t i = 0; i < it.nplanes; i++, ++it )
copymask(ptrs[0], 0, ptrs[2], 0, ptrs[1], 0, sz, &esz);
}
Mat& Mat::operator = (const Scalar& s)
{
if( dims > 2 )
{
const Mat* arrays[] = { this, 0 };
Mat planes[1];
NAryMatIterator it(arrays, planes);
for( int i = 0; i < it.nplanes; i++, ++it )
it.planes[0] = s;
return *this;
}
Size sz = size();
uchar* dst = data;
sz.width *= (int)elemSize();
if( isContinuous() )
{
sz.width *= sz.height;
sz.height = 1;
}
const Mat* arrays[] = { this };
uchar* ptr;
NAryMatIterator it(arrays, &ptr, 1);
size_t size = it.size*elemSize();
if( s[0] == 0 && s[1] == 0 && s[2] == 0 && s[3] == 0 )
{
for( ; sz.height--; dst += step )
memset( dst, 0, sz.width );
for( size_t i = 0; i < it.nplanes; i++, ++it )
memset( ptr, 0, size );
}
else
{
int t = type(), esz1 = (int)elemSize1();
double scalar[12];
scalarToRawData(s, scalar, t, 12);
int copy_len = 12*esz1;
uchar* dst_limit = dst + sz.width;
if( sz.height-- )
if( it.nplanes > 0 )
{
while( dst + copy_len <= dst_limit )
double scalar[12];
scalarToRawData(s, scalar, type(), 12);
size_t blockSize = 12*elemSize1();
for( size_t j = 0; j < size; j += blockSize )
{
memcpy( dst, scalar, copy_len );
dst += copy_len;
size_t sz = std::min(blockSize, size - j);
memcpy( ptr + j, scalar, sz );
}
memcpy( dst, scalar, dst_limit - dst );
}
if( sz.height > 0 )
for( size_t i = 1; i < it.nplanes; i++ )
{
dst = dst_limit - sz.width + step;
for( ; sz.height--; dst += step )
memcpy( dst, data, sz.width );
++it;
memcpy( ptr, data, size );
}
}
return *this;
}
Mat& Mat::setTo(const Scalar& s, const Mat& mask)
Mat& Mat::setTo(const Scalar& s, const InputArray& _mask)
{
Mat mask = _mask.getMat();
if( !mask.data )
*this = s;
else
{
CV_Assert( channels() <= 4 );
SetMaskFunc func = setMaskFuncTab[elemSize()];
CV_Assert( func != 0 );
CV_Assert( channels() <= 4 && mask.type() == CV_8U );
size_t esz = elemSize();
BinaryFunc func = esz <= 32 ? setMaskTab[esz] : setMaskGeneric;
double buf[4];
scalarToRawData(s, buf, type(), 0);
if( dims > 2 )
{
const Mat* arrays[] = { this, &mask, 0 };
Mat planes[2];
NAryMatIterator it(arrays, planes);
for( int i = 0; i < it.nplanes; i++, ++it )
func(buf, it.planes[0], it.planes[1]);
}
else
func(buf, *this, mask);
const Mat* arrays[] = { this, &mask, 0 };
uchar* ptrs[2];
NAryMatIterator it(arrays, ptrs);
Size sz((int)it.size, 1);
for( size_t i = 0; i < it.nplanes; i++, ++it )
func((const uchar*)buf, 0, ptrs[1], 0, ptrs[0], 0, sz, &esz);
}
return *this;
}
template<typename T> static void
flipHoriz_( const Mat& srcmat, Mat& dstmat, bool flipv )
static void
flipHoriz( const uchar* src, size_t sstep, uchar* dst, size_t dstep, Size size, size_t esz )
{
uchar* dst0 = dstmat.data;
size_t srcstep = srcmat.step;
int dststep = (int)dstmat.step;
Size size = srcmat.size();
int i, j, limit = ((size.width + 1)/2)*esz;
AutoBuffer<int> _tab(size.width*esz);
int* tab = _tab;
for( i = 0; i < size.width; i++ )
for( size_t k = 0; k < esz; k++ )
tab[i*esz + k] = (size.width - i - 1)*esz + k;
if( flipv )
for( ; size.height--; src += sstep, dst += dstep )
{
dst0 += (size.height - 1)*dststep;
dststep = -dststep;
}
for( int y = 0; y < size.height; y++ )
{
const T* src = (const T*)(srcmat.data + srcstep*y);
T* dst = (T*)(dst0 + dststep*y);
for( int i = 0; i < (size.width + 1)/2; i++ )
for( i = 0; i < limit; i++ )
{
T t0 = src[i], t1 = src[size.width - i - 1];
dst[i] = t1; dst[size.width - i - 1] = t0;
j = tab[i];
uchar t0 = src[i], t1 = src[j];
dst[i] = t1; dst[j] = t0;
}
}
}
typedef void (*FlipHorizFunc)( const Mat& src, Mat& dst, bool flipv );
static void
flipVert( const Mat& srcmat, Mat& dstmat )
flipVert( const uchar* src0, size_t sstep, uchar* dst0, size_t dstep, Size size, size_t esz )
{
const uchar* src = srcmat.data;
uchar* dst = dstmat.data;
size_t srcstep = srcmat.step, dststep = dstmat.step;
Size size = srcmat.size();
const uchar* src1 = src + (size.height - 1)*srcstep;
uchar* dst1 = dst + (size.height - 1)*dststep;
size.width *= (int)srcmat.elemSize();
const uchar* src1 = src0 + (size.height - 1)*sstep;
uchar* dst1 = dst0 + (size.height - 1)*dstep;
size.width *= (int)esz;
for( int y = 0; y < (size.height + 1)/2; y++, src += srcstep, src1 -= srcstep,
dst += dststep, dst1 -= dststep )
for( int y = 0; y < (size.height + 1)/2; y++, src0 += sstep, src1 -= sstep,
dst0 += dstep, dst1 -= dstep )
{
int i = 0;
if( ((size_t)(src)|(size_t)(dst)|(size_t)src1|(size_t)dst1) % sizeof(int) == 0 )
if( ((size_t)src0|(size_t)dst0|(size_t)src1|(size_t)dst1) % sizeof(int) == 0 )
{
for( ; i <= size.width - 16; i += 16 )
{
int t0 = ((int*)(src + i))[0];
int t0 = ((int*)(src0 + i))[0];
int t1 = ((int*)(src1 + i))[0];
((int*)(dst + i))[0] = t1;
((int*)(dst0 + i))[0] = t1;
((int*)(dst1 + i))[0] = t0;
t0 = ((int*)(src + i))[1];
t0 = ((int*)(src0 + i))[1];
t1 = ((int*)(src1 + i))[1];
((int*)(dst + i))[1] = t1;
((int*)(dst0 + i))[1] = t1;
((int*)(dst1 + i))[1] = t0;
t0 = ((int*)(src + i))[2];
t0 = ((int*)(src0 + i))[2];
t1 = ((int*)(src1 + i))[2];
((int*)(dst + i))[2] = t1;
((int*)(dst0 + i))[2] = t1;
((int*)(dst1 + i))[2] = t0;
t0 = ((int*)(src + i))[3];
t0 = ((int*)(src0 + i))[3];
t1 = ((int*)(src1 + i))[3];
((int*)(dst + i))[3] = t1;
((int*)(dst0 + i))[3] = t1;
((int*)(dst1 + i))[3] = t0;
}
for( ; i <= size.width - 4; i += 4 )
{
int t0 = ((int*)(src + i))[0];
int t0 = ((int*)(src0 + i))[0];
int t1 = ((int*)(src1 + i))[0];
((int*)(dst + i))[0] = t1;
((int*)(dst0 + i))[0] = t1;
((int*)(dst1 + i))[0] = t0;
}
}
for( ; i < size.width; i++ )
{
uchar t0 = src[i];
uchar t0 = src0[i];
uchar t1 = src1[i];
dst[i] = t1;
dst0[i] = t1;
dst1[i] = t0;
}
}
}
void flip( const Mat& src, Mat& dst, int flip_mode )
void flip( const InputArray& _src, OutputArray _dst, int flip_mode )
{
static FlipHorizFunc tab[] =
{
0,
flipHoriz_<uchar>, // 1
flipHoriz_<ushort>, // 2
flipHoriz_<Vec<uchar,3> >, // 3
flipHoriz_<int>, // 4
0,
flipHoriz_<Vec<ushort,3> >, // 6
0,
flipHoriz_<Vec<int,2> >, // 8
0, 0, 0,
flipHoriz_<Vec<int,3> >, // 12
0, 0, 0,
flipHoriz_<Vec<int,4> >, // 16
0, 0, 0, 0, 0, 0, 0,
flipHoriz_<Vec<int,6> >, // 24
0, 0, 0, 0, 0, 0, 0,
flipHoriz_<Vec<int,8> > // 32
};
Mat src = _src.getMat();
CV_Assert( src.dims <= 2 );
dst.create( src.size(), src.type() );
_dst.create( src.size(), src.type() );
Mat dst = _dst.getMat();
size_t esz = src.elemSize();
if( flip_mode == 0 )
flipVert( src, dst );
if( flip_mode <= 0 )
flipVert( src.data, src.step, dst.data, dst.step, src.size(), esz );
else
{
int esz = (int)src.elemSize();
CV_Assert( esz <= 32 );
FlipHorizFunc func = tab[esz];
CV_Assert( func != 0 );
if( flip_mode > 0 )
func( src, dst, false );
else if( src.data != dst.data )
func( src, dst, true );
else
{
func( dst, dst, false );
flipVert( dst, dst );
}
}
flipHoriz( src.data, src.step, dst.data, dst.step, src.size(), esz );
if( flip_mode < 0 )
flipHoriz( dst.data, dst.step, dst.data, dst.step, dst.size(), esz );
}
void repeat(const Mat& src, int ny, int nx, Mat& dst)
void repeat(const InputArray& _src, int ny, int nx, OutputArray _dst)
{
Mat src = _src.getMat();
CV_Assert( src.dims <= 2 );
dst.create(src.rows*ny, src.cols*nx, src.type());
_dst.create(src.rows*ny, src.cols*nx, src.type());
Mat dst = _dst.getMat();
Size ssize = src.size(), dsize = dst.size();
int esz = (int)src.elemSize();
int x, y;
@@ -524,7 +526,7 @@ cvCopy( const void* srcarr, void* dstarr, const void* maskarr )
{
CvSparseNode* node_copy = (CvSparseNode*)cvSetNew( dst1->heap );
int tabidx = node->hashval & (dst1->hashsize - 1);
CV_MEMCPY_AUTO( node_copy, node, dst1->heap->elem_size );
memcpy( node_copy, node, dst1->heap->elem_size );
node_copy->next = (CvSparseNode*)dst1->hashtable[tabidx];
dst1->hashtable[tabidx] = node_copy;
}

View File

@@ -1146,7 +1146,7 @@ cvSeqPush( CvSeq *seq, const void *element )
}
if( element )
CV_MEMCPY_AUTO( ptr, element, elem_size );
memcpy( ptr, element, elem_size );
seq->first->prev->count++;
seq->total++;
seq->ptr = ptr + elem_size;
@@ -1171,7 +1171,7 @@ cvSeqPop( CvSeq *seq, void *element )
seq->ptr = ptr = seq->ptr - elem_size;
if( element )
CV_MEMCPY_AUTO( element, ptr, elem_size );
memcpy( element, ptr, elem_size );
seq->ptr = ptr;
seq->total--;
@@ -1208,7 +1208,7 @@ cvSeqPushFront( CvSeq *seq, const void *element )
ptr = block->data -= elem_size;
if( element )
CV_MEMCPY_AUTO( ptr, element, elem_size );
memcpy( ptr, element, elem_size );
block->count++;
block->start_index--;
seq->total++;
@@ -1233,7 +1233,7 @@ cvSeqPopFront( CvSeq *seq, void *element )
block = seq->first;
if( element )
CV_MEMCPY_AUTO( element, block->data, elem_size );
memcpy( element, block->data, elem_size );
block->data += elem_size;
block->start_index++;
seq->total--;
@@ -1708,7 +1708,7 @@ cvSeqRemoveSlice( CvSeq* seq, CvSlice slice )
for( i = 0; i < count; i++ )
{
CV_MEMCPY_AUTO( reader_to.ptr, reader_from.ptr, elem_size );
memcpy( reader_to.ptr, reader_from.ptr, elem_size );
CV_NEXT_SEQ_ELEM( elem_size, reader_to );
CV_NEXT_SEQ_ELEM( elem_size, reader_from );
}
@@ -1726,7 +1726,7 @@ cvSeqRemoveSlice( CvSeq* seq, CvSlice slice )
CV_PREV_SEQ_ELEM( elem_size, reader_to );
CV_PREV_SEQ_ELEM( elem_size, reader_from );
CV_MEMCPY_AUTO( reader_to.ptr, reader_from.ptr, elem_size );
memcpy( reader_to.ptr, reader_from.ptr, elem_size );
}
cvSeqPopMulti( seq, 0, slice.end_index - slice.start_index, 1 );
@@ -1796,7 +1796,7 @@ cvSeqInsertSlice( CvSeq* seq, int index, const CvArr* from_arr )
for( i = 0; i < index; i++ )
{
CV_MEMCPY_AUTO( reader_to.ptr, reader_from.ptr, elem_size );
memcpy( reader_to.ptr, reader_from.ptr, elem_size );
CV_NEXT_SEQ_ELEM( elem_size, reader_to );
CV_NEXT_SEQ_ELEM( elem_size, reader_from );
}
@@ -1814,7 +1814,7 @@ cvSeqInsertSlice( CvSeq* seq, int index, const CvArr* from_arr )
{
CV_PREV_SEQ_ELEM( elem_size, reader_to );
CV_PREV_SEQ_ELEM( elem_size, reader_from );
CV_MEMCPY_AUTO( reader_to.ptr, reader_from.ptr, elem_size );
memcpy( reader_to.ptr, reader_from.ptr, elem_size );
}
}
@@ -1823,7 +1823,7 @@ cvSeqInsertSlice( CvSeq* seq, int index, const CvArr* from_arr )
for( i = 0; i < from_total; i++ )
{
CV_MEMCPY_AUTO( reader_to.ptr, reader_from.ptr, elem_size );
memcpy( reader_to.ptr, reader_from.ptr, elem_size );
CV_NEXT_SEQ_ELEM( elem_size, reader_to );
CV_NEXT_SEQ_ELEM( elem_size, reader_from );
}
@@ -2525,7 +2525,7 @@ cvSetAdd( CvSet* set, CvSetElem* element, CvSetElem** inserted_element )
id = free_elem->flags & CV_SET_ELEM_IDX_MASK;
if( element )
CV_MEMCPY_INT( free_elem, element, (size_t)set->elem_size/sizeof(int) );
memcpy( free_elem, element, set->elem_size );
free_elem->flags = id;
set->active_count++;
@@ -2616,8 +2616,7 @@ cvGraphAddVtx( CvGraph* graph, const CvGraphVtx* _vertex, CvGraphVtx** _inserted
if( vertex )
{
if( _vertex )
CV_MEMCPY_INT( vertex + 1, _vertex + 1,
(size_t)(graph->elem_size - sizeof(CvGraphVtx))/sizeof(int) );
memcpy( vertex + 1, _vertex + 1, graph->elem_size - sizeof(CvGraphVtx) );
vertex->first = 0;
index = vertex->flags;
}
@@ -2784,17 +2783,17 @@ cvGraphAddEdgeByPtr( CvGraph* graph,
edge->next[1] = end_vtx->first;
start_vtx->first = end_vtx->first = edge;
delta = (graph->edges->elem_size - sizeof(*edge))/sizeof(int);
delta = graph->edges->elem_size - sizeof(*edge);
if( _edge )
{
if( delta > 0 )
CV_MEMCPY_INT( edge + 1, _edge + 1, delta );
memcpy( edge + 1, _edge + 1, delta );
edge->weight = _edge->weight;
}
else
{
if( delta > 0 )
CV_ZERO_INT( edge + 1, delta );
memset( edge + 1, 0, delta );
edge->weight = 1.f;
}
@@ -3548,14 +3547,14 @@ KDTree::KDTree()
normType = NORM_L2;
}
KDTree::KDTree(const Mat& _points, bool _copyData)
KDTree::KDTree(const InputArray& _points, bool _copyData)
{
maxDepth = -1;
normType = NORM_L2;
build(_points, _copyData);
}
KDTree::KDTree(const Mat& _points, const Mat& _labels, bool _copyData)
KDTree::KDTree(const InputArray& _points, const InputArray& _labels, bool _copyData)
{
maxDepth = -1;
normType = NORM_L2;
@@ -3638,14 +3637,15 @@ computeSums( const Mat& points, const size_t* ofs, int a, int b, double* sums )
}
void KDTree::build(const Mat& _points, bool _copyData)
void KDTree::build(const InputArray& _points, bool _copyData)
{
build(_points, Mat(), _copyData);
build(_points, InputArray(), _copyData);
}
void KDTree::build(const Mat& _points, const Mat& _labels, bool _copyData)
void KDTree::build(const InputArray& __points, const InputArray& __labels, bool _copyData)
{
Mat _points = __points.getMat(), _labels = __labels.getMat();
CV_Assert(_points.type() == CV_32F && !_points.empty());
vector<KDTree::Node>().swap(nodes);
@@ -3744,57 +3744,6 @@ void KDTree::build(const Mat& _points, const Mat& _labels, bool _copyData)
}
int KDTree::findNearest(const float* vec, int K, int emax,
vector<int>* neighborsIdx,
Mat* neighbors,
vector<float>* dist,
vector<int>* labels) const
{
K = std::min(K, points.rows);
CV_Assert(K > 0);
if(neighborsIdx)
neighborsIdx->resize(K);
if(dist)
dist->resize(K);
if(labels)
labels->resize(K);
K = findNearest(vec, K, emax, neighborsIdx ? &(*neighborsIdx)[0] : 0,
neighbors, dist ? &(*dist)[0] : 0, labels ? &(*labels)[0] : 0);
if(neighborsIdx)
neighborsIdx->resize(K);
if(dist)
dist->resize(K);
if(labels)
labels->resize(K);
return K;
}
int KDTree::findNearest(const vector<float>& vec, int K, int emax,
vector<int>* neighborsIdx,
Mat* neighbors,
vector<float>* dist,
vector<int>* labels) const
{
CV_Assert((int)vec.size() == points.cols);
K = std::min(K, points.rows);
CV_Assert(K > 0);
if(neighborsIdx)
neighborsIdx->resize(K);
if(dist)
dist->resize(K);
if(labels)
labels->resize(K);
K = findNearest(&vec[0], K, emax, neighborsIdx ? &(*neighborsIdx)[0] : 0,
neighbors, dist ? &(*dist)[0] : 0, labels ? &(*labels)[0] : 0);
if(neighborsIdx)
neighborsIdx->resize(K);
if(dist)
dist->resize(K);
if(labels)
labels->resize(K);
return K;
}
struct PQueueElem
{
PQueueElem() : dist(0), idx(0) {}
@@ -3804,11 +3753,14 @@ struct PQueueElem
};
int KDTree::findNearest(const float* vec, int K, int emax,
int* _neighborsIdx, Mat* _neighbors,
float* _dist, int* _labels) const
int KDTree::findNearest(const InputArray& _vec, int K, int emax,
OutputArray _neighborsIdx, OutputArray _neighbors,
OutputArray _dist, OutputArray _labels) const
{
Mat vecmat = _vec.getMat();
CV_Assert( vecmat.isContinuous() && vecmat.type() == CV_32F && vecmat.total() == (size_t)points.cols );
const float* vec = vecmat.ptr<float>();
K = std::min(K, points.rows);
int dims = points.cols;
@@ -3929,42 +3881,43 @@ int KDTree::findNearest(const float* vec, int K, int emax,
}
K = std::min(K, ncount);
if( _neighborsIdx )
if( _neighborsIdx.needed() )
{
for( i = 0; i < K; i++ )
_neighborsIdx[i] = idx[i];
}
if( _dist )
{
for( i = 0; i < K; i++ )
_dist[i] = std::sqrt(dist[i]);
}
if( _labels )
{
for( i = 0; i < K; i++ )
_labels[i] = labels[idx[i]];
_neighborsIdx.create(K, 1, CV_32S, -1, true);
Mat nidx = _neighborsIdx.getMat();
Mat(nidx.size(), CV_32S, &idx[0]).copyTo(nidx);
}
if( _dist.needed() )
sqrt(Mat(K, 1, CV_32F, dist), _dist);
if( _neighbors )
getPoints(idx, K, *_neighbors);
if( _neighbors.needed() || _labels.needed() )
getPoints(Mat(K, 1, CV_32S, idx), _neighbors, _labels);
return K;
}
void KDTree::findOrthoRange(const float* L, const float* R,
vector<int>* neighborsIdx,
Mat* neighbors, vector<int>* _labels) const
void KDTree::findOrthoRange(const InputArray& _lowerBound,
const InputArray& _upperBound,
OutputArray _neighborsIdx,
OutputArray _neighbors,
OutputArray _labels ) const
{
int dims = points.cols;
Mat lowerBound = _lowerBound.getMat(), upperBound = _upperBound.getMat();
CV_Assert( lowerBound.size == upperBound.size &&
lowerBound.isContinuous() &&
upperBound.isContinuous() &&
lowerBound.type() == upperBound.type() &&
lowerBound.type() == CV_32F &&
lowerBound.total() == (size_t)dims );
const float* L = lowerBound.ptr<float>();
const float* R = upperBound.ptr<float>();
CV_Assert( L && R );
vector<int> _idx, *idx = neighborsIdx ? neighborsIdx : &_idx;
vector<int> idx;
AutoBuffer<int> _stack(MAX_TREE_DEPTH*2 + 1);
int* stack = _stack;
int top = 0;
idx->clear();
stack[top++] = 0;
while( --top >= 0 )
@@ -3981,7 +3934,7 @@ void KDTree::findOrthoRange(const float* L, const float* R,
if( row[j] < L[j] || row[j] >= R[j] )
break;
if( j == dims )
idx->push_back(i);
idx.push_back(i);
continue;
}
if( L[n.idx] <= n.boundary )
@@ -3990,55 +3943,57 @@ void KDTree::findOrthoRange(const float* L, const float* R,
stack[top++] = n.right;
}
if( neighbors )
getPoints( &(*idx)[0], idx->size(), *neighbors, _labels );
}
void KDTree::findOrthoRange(const vector<float>& L, const vector<float>& R,
vector<int>* neighborsIdx, Mat* neighbors, vector<int>* _labels) const
{
size_t dims = points.cols;
CV_Assert(L.size() == dims && R.size() == dims);
findOrthoRange(&L[0], &R[0], neighborsIdx, neighbors, _labels);
}
void KDTree::getPoints(const int* idx, size_t nidx, Mat& pts, vector<int>* _labels) const
{
int dims = points.cols, n = (int)nidx;
pts.create( n, dims, points.type());
if(_labels)
_labels->resize(nidx);
for( int i = 0; i < n; i++ )
if( _neighborsIdx.needed() )
{
int k = idx[i];
CV_Assert( (unsigned)k < (unsigned)points.rows );
const float* src = points.ptr<float>(k);
std::copy(src, src + dims, pts.ptr<float>(i));
if(_labels)
(*_labels)[i] = labels[k];
_neighborsIdx.create(idx.size(), 1, CV_32S, -1, true);
Mat nidx = _neighborsIdx.getMat();
Mat(nidx.size(), CV_32S, &idx[0]).copyTo(nidx);
}
getPoints( idx, _neighbors, _labels );
}
void KDTree::getPoints(const vector<int>& idx, Mat& pts, vector<int>* _labels) const
{
int dims = points.cols;
int i, nidx = (int)idx.size();
pts.create( nidx, dims, points.type());
if(_labels)
_labels->resize(nidx);
void KDTree::getPoints(const InputArray& _idx, OutputArray _pts, OutputArray _labels) const
{
Mat idxmat = _idx.getMat(), pts, labelsmat;
CV_Assert( idxmat.isContinuous() && idxmat.type() == CV_32S &&
(idxmat.cols == 1 || idxmat.rows == 1) );
const int* idx = idxmat.ptr<int>();
int* dstlabels = 0;
int dims = points.cols;
int i, nidx = (int)idxmat.total();
if( nidx == 0 )
{
_pts.release();
_labels.release();
return;
}
if( _pts.needed() )
{
_pts.create( nidx, dims, points.type());
pts = _pts.getMat();
}
if(_labels.needed())
{
_labels.create(nidx, 1, CV_32S, -1, true);
labelsmat = _labels.getMat();
CV_Assert( labelsmat.isContinuous() );
dstlabels = labelsmat.ptr<int>();
}
const int* srclabels = !labels.empty() ? &labels[0] : 0;
for( i = 0; i < nidx; i++ )
{
int k = idx[i];
CV_Assert( (unsigned)k < (unsigned)points.rows );
const float* src = points.ptr<float>(k);
std::copy(src, src + dims, pts.ptr<float>(i));
if(_labels) (*_labels)[i] = labels[k];
if( pts.data )
std::copy(src, src + dims, pts.ptr<float>(i));
if( dstlabels )
dstlabels[i] = srclabels ? srclabels[k] : k;
}
}
@@ -4047,7 +4002,7 @@ const float* KDTree::getPoint(int ptidx, int* label) const
{
CV_Assert( (unsigned)ptidx < (unsigned)points.rows);
if(label)
*label = label[ptidx];
*label = labels[ptidx];
return points.ptr<float>(ptidx);
}

View File

@@ -235,7 +235,7 @@ LineIterator::LineIterator(const Mat& img, Point pt1, Point pt2,
static void
Line( Mat& img, Point pt1, Point pt2,
const void* color, int connectivity = 8 )
const void* _color, int connectivity = 8 )
{
if( connectivity == 0 )
connectivity = 8;
@@ -245,10 +245,21 @@ Line( Mat& img, Point pt1, Point pt2,
LineIterator iterator(img, pt1, pt2, connectivity, true);
int i, count = iterator.count;
int pix_size = (int)img.elemSize();
const uchar* color = (const uchar*)_color;
for( i = 0; i < count; i++, ++iterator )
{
CV_MEMCPY_AUTO( *iterator, color, pix_size );
uchar* ptr = *iterator;
if( pix_size == 1 )
ptr[0] = color[0];
else if( pix_size == 3 )
{
ptr[0] = color[0];
ptr[1] = color[1];
ptr[2] = color[2];
}
else
memcpy( *iterator, color, pix_size );
}
}
@@ -1317,7 +1328,7 @@ Circle( Mat& img, Point center, int radius, const void* color, int fill )
center.y >= radius && center.y < size.height - radius;
#define ICV_PUT_POINT( ptr, x ) \
CV_MEMCPY_CHAR( ptr + (x)*pix_size, color, pix_size );
memcpy( ptr + (x)*pix_size, color, pix_size );
while( dx >= dy )
{

View File

@@ -1449,27 +1449,25 @@ static void CCSIDFT_64f( const double* src, double* dst, int n, int nf, int* fac
CCSIDFT( src, dst, n, nf, factors, itab, wave, tab_size, spec, buf, flags, scale);
}
}
void dft( const Mat& src0, Mat& dst, int flags, int nonzero_rows )
void cv::dft( const InputArray& _src0, OutputArray _dst, int flags, int nonzero_rows )
{
static DFTFunc dft_tbl[6];
static int inittab = 0;
if( !inittab )
static DFTFunc dft_tbl[6] =
{
dft_tbl[0] = (DFTFunc)DFT_32f;
dft_tbl[1] = (DFTFunc)RealDFT_32f;
dft_tbl[2] = (DFTFunc)CCSIDFT_32f;
dft_tbl[3] = (DFTFunc)DFT_64f;
dft_tbl[4] = (DFTFunc)RealDFT_64f;
dft_tbl[5] = (DFTFunc)CCSIDFT_64f;
inittab = 1;
}
(DFTFunc)DFT_32f,
(DFTFunc)RealDFT_32f,
(DFTFunc)CCSIDFT_32f,
(DFTFunc)DFT_64f,
(DFTFunc)RealDFT_64f,
(DFTFunc)CCSIDFT_64f
};
AutoBuffer<uchar> buf;
void *spec = 0;
Mat src = src0;
Mat src0 = _src0.getMat(), src = src0;
int prev_len = 0, stage = 0;
bool inv = (flags & DFT_INVERSE) != 0;
int nf = 0, real_transform = src.channels() == 1 || (inv && (flags & DFT_REAL_OUTPUT)!=0);
@@ -1485,11 +1483,13 @@ void dft( const Mat& src0, Mat& dst, int flags, int nonzero_rows )
CV_Assert( type == CV_32FC1 || type == CV_32FC2 || type == CV_64FC1 || type == CV_64FC2 );
if( !inv && src.channels() == 1 && (flags & DFT_COMPLEX_OUTPUT) )
dst.create( src.size(), CV_MAKETYPE(depth, 2) );
_dst.create( src.size(), CV_MAKETYPE(depth, 2) );
else if( inv && src.channels() == 2 && (flags & DFT_REAL_OUTPUT) )
dst.create( src.size(), depth );
_dst.create( src.size(), depth );
else
dst.create( src.size(), type );
_dst.create( src.size(), type );
Mat dst = _dst.getMat();
if( !real_transform )
elem_size = complex_elem_size;
@@ -1840,14 +1840,15 @@ void dft( const Mat& src0, Mat& dst, int flags, int nonzero_rows )
}
void idft( const Mat& src, Mat& dst, int flags, int nonzero_rows )
void cv::idft( const InputArray& src, OutputArray dst, int flags, int nonzero_rows )
{
dft( src, dst, flags | DFT_INVERSE, nonzero_rows );
}
void mulSpectrums( const Mat& srcA, const Mat& srcB,
Mat& dst, int flags, bool conjB )
void cv::mulSpectrums( const InputArray& _srcA, const InputArray& _srcB,
OutputArray _dst, int flags, bool conjB )
{
Mat srcA = _srcA.getMat(), srcB = _srcB.getMat();
int depth = srcA.depth(), cn = srcA.channels(), type = srcA.type();
int rows = srcA.rows, cols = srcA.cols;
int j, k;
@@ -1855,7 +1856,8 @@ void mulSpectrums( const Mat& srcA, const Mat& srcB,
CV_Assert( type == srcB.type() && srcA.size() == srcB.size() );
CV_Assert( type == CV_32FC1 || type == CV_32FC2 || type == CV_64FC1 || type == CV_64FC2 );
dst.create( srcA.rows, srcA.cols, type );
_dst.create( srcA.rows, srcA.cols, type );
Mat dst = _dst.getMat();
bool is_1d = (flags & DFT_ROWS) || (rows == 1 || (cols == 1 &&
srcA.isContinuous() && srcB.isContinuous() && dst.isContinuous()));
@@ -2008,6 +2010,9 @@ void mulSpectrums( const Mat& srcA, const Mat& srcB,
Discrete Cosine Transform
\****************************************************************************************/
namespace cv
{
/* DCT is calculated using DFT, as described here:
http://www.ece.utexas.edu/~bevans/courses/ee381k/lectures/09_DCT/lecture9/:
*/
@@ -2210,23 +2215,21 @@ static void IDCT_64f(const double* src, int src_step, double* dft_src, double* d
IDCT(src, src_step, dft_src, dft_dst, dst, dst_step,
n, nf, factors, itab, dft_wave, dct_wave, spec, buf);
}
}
void dct( const Mat& src0, Mat& dst, int flags )
void cv::dct( const InputArray& _src0, OutputArray _dst, int flags )
{
static DCTFunc dct_tbl[4];
static int inittab = 0;
if( !inittab )
static DCTFunc dct_tbl[4] =
{
dct_tbl[0] = (DCTFunc)DCT_32f;
dct_tbl[1] = (DCTFunc)IDCT_32f;
dct_tbl[2] = (DCTFunc)DCT_64f;
dct_tbl[3] = (DCTFunc)IDCT_64f;
inittab = 1;
}
(DCTFunc)DCT_32f,
(DCTFunc)IDCT_32f,
(DCTFunc)DCT_64f,
(DCTFunc)IDCT_64f
};
bool inv = (flags & DCT_INVERSE) != 0;
Mat src = src0;
Mat src0 = _src0.getMat(), src = src0;
int type = src.type(), depth = src.depth();
void /* *spec_dft = 0, */ *spec = 0;
@@ -2242,7 +2245,8 @@ void dct( const Mat& src0, Mat& dst, int flags )
AutoBuffer<uchar> buf;
CV_Assert( type == CV_32FC1 || type == CV_64FC1 );
dst.create( src.rows, src.cols, type );
_dst.create( src.rows, src.cols, type );
Mat dst = _dst.getMat();
DCTFunc dct_func = dct_tbl[inv + (depth == CV_64F)*2];
@@ -2369,11 +2373,14 @@ void dct( const Mat& src0, Mat& dst, int flags )
}
void idct( const Mat& src, Mat& dst, int flags )
void cv::idct( const InputArray& src, OutputArray dst, int flags )
{
dct( src, dst, flags | DCT_INVERSE );
}
namespace cv
{
static const int optimalDFTSizeTab[] = {
1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, 36, 40, 45, 48,
50, 54, 60, 64, 72, 75, 80, 81, 90, 96, 100, 108, 120, 125, 128, 135, 144, 150, 160,
@@ -2555,8 +2562,9 @@ static const int optimalDFTSizeTab[] = {
2097152000, 2099520000, 2109375000, 2123366400, 2125764000
};
int
getOptimalDFTSize( int size0 )
}
int cv::getOptimalDFTSize( int size0 )
{
int a = 0, b = sizeof(optimalDFTSizeTab)/sizeof(optimalDFTSizeTab[0]) - 1;
if( (unsigned)size0 >= (unsigned)optimalDFTSizeTab[b] )
@@ -2574,8 +2582,6 @@ getOptimalDFTSize( int size0 )
return optimalDFTSizeTab[b];
}
}
CV_IMPL void
cvDFT( const CvArr* srcarr, CvArr* dstarr, int flags, int nonzero_rows )
{

View File

@@ -212,6 +212,8 @@ bool Cholesky(double* A, int m, double* b, int n)
{
return CholImpl(A, m, b, n);
}
}
/****************************************************************************************\
* Determinant of the matrix *
@@ -222,8 +224,9 @@ bool Cholesky(double* A, int m, double* b, int n)
m(0,1)*((double)m(1,0)*m(2,2) - (double)m(1,2)*m(2,0)) + \
m(0,2)*((double)m(1,0)*m(2,1) - (double)m(1,1)*m(2,0)))
double determinant( const Mat& mat )
double cv::determinant( const InputArray& _mat )
{
Mat mat = _mat.getMat();
double result = 0;
int type = mat.type(), rows = mat.rows;
size_t step = mat.step;
@@ -325,13 +328,16 @@ double determinant( const Mat& mat )
#define Df( y, x ) ((float*)(dstdata + y*dststep))[x]
#define Dd( y, x ) ((double*)(dstdata + y*dststep))[x]
double invert( const Mat& src, Mat& dst, int method )
double cv::invert( const InputArray& _src, OutputArray _dst, int method )
{
double result = 0;
Mat src = _src.getMat();
int type = src.type();
CV_Assert( method == DECOMP_LU || method == DECOMP_CHOLESKY || method == DECOMP_SVD );
_dst.create( src.cols, src.rows, type );
Mat dst = _dst.getMat();
if( method == DECOMP_SVD )
{
int n = std::min(src.rows, src.cols);
@@ -346,8 +352,7 @@ double invert( const Mat& src, Mat& dst, int method )
}
CV_Assert( src.rows == src.cols && (type == CV_32F || type == CV_64F));
dst.create( src.rows, src.cols, type );
if( src.rows <= 3 )
{
uchar* srcdata = src.data;
@@ -572,9 +577,10 @@ double invert( const Mat& src, Mat& dst, int method )
* Solving a linear system *
\****************************************************************************************/
bool solve( const Mat& src, const Mat& _src2, Mat& dst, int method )
bool cv::solve( const InputArray& _src, const InputArray& _src2arg, OutputArray _dst, int method )
{
bool result = true;
Mat src = _src.getMat(), _src2 = _src2arg.getMat();
int type = src.type();
bool is_normal = (method & DECOMP_NORMAL) != 0;
@@ -588,7 +594,8 @@ bool solve( const Mat& src, const Mat& _src2, Mat& dst, int method )
if( (method == DECOMP_LU || method == DECOMP_CHOLESKY) &&
src.rows <= 3 && src.rows == src.cols && _src2.cols == 1 )
{
dst.create( src.cols, _src2.cols, src.type() );
_dst.create( src.cols, _src2.cols, src.type() );
Mat dst = _dst.getMat();
#define bf(y) ((float*)(bdata + y*src2step))[0]
#define bd(y) ((double*)(bdata + y*src2step))[0]
@@ -729,7 +736,8 @@ bool solve( const Mat& src, const Mat& _src2, Mat& dst, int method )
char N[] = {'N', '\0'}, L[] = {'L', '\0'};
Mat src2 = _src2;
dst.create( src.cols, src2.cols, src.type() );
_dst.create( src.cols, src2.cols, src.type() );
Mat dst = _dst.getMat();
if( m <= n )
is_normal = false;
@@ -905,6 +913,9 @@ bool solve( const Mat& src, const Mat& _src2, Mat& dst, int method )
/////////////////// finding eigenvalues and eigenvectors of a symmetric matrix ///////////////
namespace cv
{
template<typename Real> static inline Real hypot(Real a, Real b)
{
a = std::abs(a);
@@ -1077,9 +1088,10 @@ template<typename Real> bool jacobi(const Mat& _S0, Mat& _e, Mat& matE, bool com
}
static bool eigen( const Mat& src, Mat& evals, Mat& evects, bool computeEvects,
static bool eigen( const InputArray& _src, OutputArray _evals, OutputArray _evects, bool computeEvects,
int lowindex, int highindex )
{
Mat src = _src.getMat();
int type = src.type();
integer n = src.rows;
@@ -1094,9 +1106,14 @@ static bool eigen( const Mat& src, Mat& evals, Mat& evects, bool computeEvects,
CV_Assert( src.rows == src.cols );
CV_Assert (type == CV_32F || type == CV_64F);
// allow for 1xn eigenvalue matrix too
if( !(evals.rows == 1 && evals.cols == n && evals.type() == type) )
evals.create(n, 1, type);
_evals.create(n, 1, type, -1, true);
Mat evals = _evals.getMat(), evects;
if( computeEvects )
{
_evects.create(n, n, type);
evects = _evects.getMat();
}
if( n <= 20 )
{
@@ -1122,10 +1139,7 @@ static bool eigen( const Mat& src, Mat& evals, Mat& evects, bool computeEvects,
lda = (int)(src.step/elem_size);
if( computeEvects )
{
evects.create(n, n, type);
ldv = (int)(evects.step/elem_size);
}
bool copy_evals = !evals.isContinuous();
@@ -1211,19 +1225,21 @@ static bool eigen( const Mat& src, Mat& evals, Mat& evects, bool computeEvects,
return result;
}
bool eigen( const Mat& src, Mat& evals, int lowindex, int highindex )
}
bool cv::eigen( const InputArray& src, OutputArray evals, int lowindex, int highindex )
{
Mat evects;
return eigen(src, evals, evects, false, lowindex, highindex);
return eigen(src, evals, OutputArray(), false, lowindex, highindex);
}
bool eigen( const Mat& src, Mat& evals, Mat& evects, int lowindex,
int highindex )
bool cv::eigen( const InputArray& src, OutputArray evals, OutputArray evects,
int lowindex, int highindex )
{
return eigen(src, evals, evects, true, lowindex, highindex);
}
namespace cv
{
/* y[0:m,0:n] += diag(a[0:1,0:m]) * x[0:m,0:n] */
template<typename T1, typename T2, typename T3> static void
@@ -1316,29 +1332,33 @@ SVBkSb( int m, int n, const T* w, int incw,
}
static void _SVDcompute( const Mat& a, Mat& w, Mat* u, Mat* vt, int flags )
static void _SVDcompute( const InputArray& _aarr, OutputArray _w,
OutputArray _u, OutputArray _vt, int flags )
{
Mat a = _aarr.getMat(), u, vt;
integer m = a.rows, n = a.cols, mn = std::max(m, n), nm = std::min(m, n);
int type = a.type(), elem_size = (int)a.elemSize();
bool compute_uv = u && vt;
bool compute_uv = _u.needed() || _vt.needed();
if( flags & SVD::NO_UV )
{
if(u) u->release();
if(vt) vt->release();
u = vt = 0;
_u.release();
_vt.release();
compute_uv = false;
}
if( compute_uv )
{
u->create( (int)m, (int)((flags & SVD::FULL_UV) ? m : nm), type );
vt->create( (int)((flags & SVD::FULL_UV) ? n : nm), n, type );
_u.create( (int)m, (int)((flags & SVD::FULL_UV) ? m : nm), type );
_vt.create( (int)((flags & SVD::FULL_UV) ? n : nm), n, type );
u = _u.getMat();
vt = _vt.getMat();
}
w.create(nm, 1, type);
_w.create(nm, 1, type, -1, true);
Mat _a = a;
Mat _a = a, w = _w.getMat();
CV_Assert( w.isContinuous() );
int a_ofs = 0, work_ofs=0, iwork_ofs=0, buf_size = 0;
bool temp_a = false;
double u1=0, v1=0, work1=0;
@@ -1353,7 +1373,7 @@ static void _SVDcompute( const Mat& a, Mat& w, Mat* u, Mat* vt, int flags )
{
if( mode[0] == 'N' || mode[0] == 'A' )
temp_a = true;
else if( compute_uv && (a.size() == vt->size() || a.size() == u->size()) && mode[0] == 'S' )
else if( compute_uv && (a.size() == vt.size() || a.size() == u.size()) && mode[0] == 'S' )
mode[0] = 'O';
}
@@ -1396,59 +1416,67 @@ static void _SVDcompute( const Mat& a, Mat& w, Mat* u, Mat* vt, int flags )
if( !(flags & SVD::MODIFY_A) && !temp_a )
{
if( compute_uv && a.size() == vt->size() )
if( compute_uv && a.size() == vt.size() )
{
a.copyTo(*vt);
_a = *vt;
a.copyTo(vt);
_a = vt;
}
else if( compute_uv && a.size() == u->size() )
else if( compute_uv && a.size() == u.size() )
{
a.copyTo(*u);
_a = *u;
a.copyTo(u);
_a = u;
}
}
if( compute_uv )
{
ldv = (int)(vt->step ? vt->step/elem_size : vt->cols);
ldu = (int)(u->step ? u->step/elem_size : u->cols);
ldv = (int)(vt.step ? vt.step/elem_size : vt.cols);
ldu = (int)(u.step ? u.step/elem_size : u.cols);
}
lda = (int)(_a.step ? _a.step/elem_size : _a.cols);
if( type == CV_32F )
{
sgesdd_(mode, &n, &m, (float*)_a.data, &lda, (float*)w.data,
vt ? (float*)vt->data : (float*)&v1, &ldv, u ? (float*)u->data : (float*)&u1, &ldu,
(float*)(buffer + work_ofs), &lwork, (integer*)(buffer + iwork_ofs), &info );
sgesdd_(mode, &n, &m, _a.ptr<float>(), &lda, w.ptr<float>(),
vt.data ? vt.ptr<float>() : (float*)&v1, &ldv,
u.data ? u.ptr<float>() : (float*)&u1, &ldu,
(float*)(buffer + work_ofs), &lwork,
(integer*)(buffer + iwork_ofs), &info );
}
else
{
dgesdd_(mode, &n, &m, (double*)_a.data, &lda, (double*)w.data,
vt ? (double*)vt->data : &v1, &ldv, u ? (double*)u->data : &u1, &ldu,
(double*)(buffer + work_ofs), &lwork, (integer*)(buffer + iwork_ofs), &info );
dgesdd_(mode, &n, &m, _a.ptr<double>(), &lda, w.ptr<double>(),
vt.data ? vt.ptr<double>() : &v1, &ldv,
u.data ? u.ptr<double>() : &u1, &ldu,
(double*)(buffer + work_ofs), &lwork,
(integer*)(buffer + iwork_ofs), &info );
}
CV_Assert(info >= 0);
if(info != 0)
{
*u = Scalar(0.);
*vt = Scalar(0.);
if( u.data )
u = Scalar(0.);
if( vt.data )
vt = Scalar(0.);
w = Scalar(0.);
}
}
void SVD::compute( const Mat& a, Mat& w, Mat& u, Mat& vt, int flags )
void SVD::compute( const InputArray& a, OutputArray w, OutputArray u, OutputArray vt, int flags )
{
_SVDcompute(a, w, &u, &vt, flags);
_SVDcompute(a, w, u, vt, flags);
}
void SVD::compute( const Mat& a, Mat& w, int flags )
void SVD::compute( const InputArray& a, OutputArray w, int flags )
{
_SVDcompute(a, w, 0, 0, flags);
_SVDcompute(a, w, OutputArray(), OutputArray(), flags);
}
void SVD::backSubst( const Mat& w, const Mat& u, const Mat& vt, const Mat& rhs, Mat& dst )
void SVD::backSubst( const InputArray& _w, const InputArray& _u, const InputArray& _vt,
const InputArray& _rhs, OutputArray _dst )
{
Mat w = _w.getMat(), u = _u.getMat(), vt = _vt.getMat(), rhs = _rhs.getMat();
int type = w.type(), esz = (int)w.elemSize();
int m = u.rows, n = vt.cols, nb = rhs.data ? rhs.cols : m;
AutoBuffer<double> buffer(nb);
@@ -1456,7 +1484,8 @@ void SVD::backSubst( const Mat& w, const Mat& u, const Mat& vt, const Mat& rhs,
CV_Assert( rhs.data == 0 || (rhs.type() == type && rhs.rows == m) );
dst.create( n, nb, type );
_dst.create( n, nb, type );
Mat dst = _dst.getMat();
if( type == CV_32F )
SVBkSb(m, n, (float*)w.data, 1, (float*)u.data, (int)(u.step/esz), false,
(float*)vt.data, (int)(vt.step/esz), true, (float*)rhs.data, (int)(rhs.step/esz),
@@ -1470,14 +1499,14 @@ void SVD::backSubst( const Mat& w, const Mat& u, const Mat& vt, const Mat& rhs,
}
SVD& SVD::operator ()(const Mat& a, int flags)
SVD& SVD::operator ()(const InputArray& a, int flags)
{
_SVDcompute(a, w, &u, &vt, flags);
_SVDcompute(a, w, u, vt, flags);
return *this;
}
void SVD::backSubst( const Mat& rhs, Mat& dst ) const
void SVD::backSubst( const InputArray& rhs, OutputArray dst ) const
{
backSubst( w, u, vt, rhs, dst );
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -208,9 +208,11 @@ static inline bool isIdentity(const MatExpr& e) { return e.op == &g_MatOp_Identi
static inline bool isAddEx(const MatExpr& e) { return e.op == &g_MatOp_AddEx; }
static inline bool isScaled(const MatExpr& e) { return isAddEx(e) && (!e.b.data || e.beta == 0) && e.s == Scalar(); }
static inline bool isBin(const MatExpr& e, char c) { return e.op == &g_MatOp_Bin && e.flags == c; }
static inline bool isCmp(const MatExpr& e) { return e.op == &g_MatOp_Cmp; }
static inline bool isReciprocal(const MatExpr& e) { return isBin(e,'/') && (!e.b.data || e.beta == 0); }
static inline bool isT(const MatExpr& e) { return e.op == &g_MatOp_T; }
static inline bool isInv(const MatExpr& e) { return e.op == &g_MatOp_Invert; }
static inline bool isSolve(const MatExpr& e) { return e.op == &g_MatOp_Solve; }
static inline bool isGEMM(const MatExpr& e) { return e.op == &g_MatOp_GEMM; }
static inline bool isMatProd(const MatExpr& e) { return e.op == &g_MatOp_GEMM && (!e.c.data || e.beta == 0); }
static inline bool isInitializer(const MatExpr& e) { return e.op == &g_MatOp_Initializer; }
@@ -571,7 +573,18 @@ void MatOp::invert(const MatExpr& expr, int method, MatExpr& res) const
expr.op->assign(expr, m);
MatOp_Invert::makeExpr(res, method, m);
}
Size MatOp::size(const MatExpr& expr) const
{
return !expr.a.empty() ? expr.a.size() : expr.b.empty() ? expr.b.size() : expr.c.size();
}
int MatOp::type(const MatExpr& expr) const
{
return !expr.a.empty() ? expr.a.type() : expr.b.empty() ? expr.b.type() : expr.c.type();
}
//////////////////////////////////////////////////////////////////////////////////////////////////
MatExpr::MatExpr(const Mat& m) : op(&g_MatOp_Identity), flags(0), a(m), b(Mat()), c(Mat()), alpha(1), beta(0), s(Scalar())
@@ -1142,6 +1155,30 @@ MatExpr abs(const MatExpr& e)
}
Size MatExpr::size() const
{
if( isT(*this) || isInv(*this) )
return Size(a.rows, a.cols);
if( isGEMM(*this) )
return Size(b.cols, a.rows);
if( isSolve(*this) )
return Size(b.cols, a.cols);
if( isInitializer(*this) )
return a.size();
return op ? op->size(*this) : Size();
}
int MatExpr::type() const
{
if( isInitializer(*this) )
return a.type();
if( isCmp(*this) )
return CV_8U;
return op ? op->type(*this) : -1;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
void MatOp_Identity::assign(const MatExpr& e, Mat& m, int type) const
@@ -1552,10 +1589,10 @@ MatExpr Mat::inv(int method) const
}
MatExpr Mat::mul(const Mat& m, double scale) const
MatExpr Mat::mul(const InputArray& m, double scale) const
{
MatExpr e;
MatOp_Bin::makeExpr(e, '*', *this, m, scale);
MatOp_Bin::makeExpr(e, '*', *this, m.getMat(), scale);
return e;
}

File diff suppressed because it is too large Load Diff

View File

@@ -65,74 +65,6 @@
#include <stdlib.h>
#include <string.h>
#define CV_MEMCPY_CHAR( dst, src, len ) \
{ \
size_t _icv_memcpy_i_, _icv_memcpy_len_ = (len); \
char* _icv_memcpy_dst_ = (char*)(dst); \
const char* _icv_memcpy_src_ = (const char*)(src); \
\
for( _icv_memcpy_i_ = 0; _icv_memcpy_i_ < _icv_memcpy_len_; _icv_memcpy_i_++ ) \
_icv_memcpy_dst_[_icv_memcpy_i_] = _icv_memcpy_src_[_icv_memcpy_i_]; \
}
#define CV_MEMCPY_INT( dst, src, len ) \
{ \
size_t _icv_memcpy_i_, _icv_memcpy_len_ = (len); \
int* _icv_memcpy_dst_ = (int*)(dst); \
const int* _icv_memcpy_src_ = (const int*)(src); \
assert( ((size_t)_icv_memcpy_src_&(sizeof(int)-1)) == 0 && \
((size_t)_icv_memcpy_dst_&(sizeof(int)-1)) == 0 ); \
\
for(_icv_memcpy_i_=0;_icv_memcpy_i_<_icv_memcpy_len_;_icv_memcpy_i_++) \
_icv_memcpy_dst_[_icv_memcpy_i_] = _icv_memcpy_src_[_icv_memcpy_i_];\
}
#define CV_MEMCPY_AUTO( dst, src, len ) \
{ \
size_t _icv_memcpy_i_, _icv_memcpy_len_ = (len); \
char* _icv_memcpy_dst_ = (char*)(dst); \
const char* _icv_memcpy_src_ = (const char*)(src); \
if( (_icv_memcpy_len_ & (sizeof(int)-1)) == 0 ) \
{ \
assert( ((size_t)_icv_memcpy_src_&(sizeof(int)-1)) == 0 && \
((size_t)_icv_memcpy_dst_&(sizeof(int)-1)) == 0 ); \
for( _icv_memcpy_i_ = 0; _icv_memcpy_i_ < _icv_memcpy_len_; \
_icv_memcpy_i_+=sizeof(int) ) \
{ \
*(int*)(_icv_memcpy_dst_+_icv_memcpy_i_) = \
*(const int*)(_icv_memcpy_src_+_icv_memcpy_i_); \
} \
} \
else \
{ \
for(_icv_memcpy_i_ = 0; _icv_memcpy_i_ < _icv_memcpy_len_; _icv_memcpy_i_++)\
_icv_memcpy_dst_[_icv_memcpy_i_] = _icv_memcpy_src_[_icv_memcpy_i_]; \
} \
}
#define CV_ZERO_CHAR( dst, len ) \
{ \
size_t _icv_memcpy_i_, _icv_memcpy_len_ = (len); \
char* _icv_memcpy_dst_ = (char*)(dst); \
\
for( _icv_memcpy_i_ = 0; _icv_memcpy_i_ < _icv_memcpy_len_; _icv_memcpy_i_++ ) \
_icv_memcpy_dst_[_icv_memcpy_i_] = '\0'; \
}
#define CV_ZERO_INT( dst, len ) \
{ \
size_t _icv_memcpy_i_, _icv_memcpy_len_ = (len); \
int* _icv_memcpy_dst_ = (int*)(dst); \
assert( ((size_t)_icv_memcpy_dst_&(sizeof(int)-1)) == 0 ); \
\
for(_icv_memcpy_i_=0;_icv_memcpy_i_<_icv_memcpy_len_;_icv_memcpy_i_++) \
_icv_memcpy_dst_[_icv_memcpy_i_] = 0; \
}
namespace cv
{
@@ -150,23 +82,11 @@ extern const uchar g_Saturate8u[];
#define CV_MIN_8U(a,b) ((a) - CV_FAST_CAST_8U((a) - (b)))
#define CV_MAX_8U(a,b) ((a) + CV_FAST_CAST_8U((b) - (a)))
typedef void (*CopyMaskFunc)(const Mat& src, Mat& dst, const Mat& mask);
extern CopyMaskFunc g_copyMaskFuncTab[];
static inline CopyMaskFunc getCopyMaskFunc(int esz)
{
CV_Assert( (unsigned)esz <= 32U );
CopyMaskFunc func = g_copyMaskFuncTab[esz];
CV_Assert( func != 0 );
return func;
}
#if defined WIN32 || defined _WIN32
void deleteThreadAllocData();
void deleteThreadRNGData();
#endif
template<typename T1, typename T2=T1, typename T3=T1> struct OpAdd
{
@@ -192,22 +112,6 @@ template<typename T1, typename T2=T1, typename T3=T1> struct OpRSub
T3 operator ()(T1 a, T2 b) const { return saturate_cast<T3>(b - a); }
};
template<typename T1, typename T2=T1, typename T3=T1> struct OpMul
{
typedef T1 type1;
typedef T2 type2;
typedef T3 rtype;
T3 operator ()(T1 a, T2 b) const { return saturate_cast<T3>(a * b); }
};
template<typename T1, typename T2=T1, typename T3=T1> struct OpDiv
{
typedef T1 type1;
typedef T2 type2;
typedef T3 rtype;
T3 operator ()(T1 a, T2 b) const { return saturate_cast<T3>(a / b); }
};
template<typename T> struct OpMin
{
typedef T type1;
@@ -261,155 +165,35 @@ inline Size getContinuousSize( const Mat& m1, const Mat& m2,
struct NoVec
{
int operator()(const void*, const void*, void*, int) const { return 0; }
size_t operator()(const void*, const void*, void*, size_t) const { return 0; }
};
extern volatile bool USE_SSE2;
typedef void (*BinaryFunc)(const uchar* src1, size_t step1,
const uchar* src2, size_t step2,
uchar* dst, size_t step, Size sz,
void*);
BinaryFunc getConvertFunc(int sdepth, int ddepth);
BinaryFunc getConvertScaleFunc(int sdepth, int ddepth);
BinaryFunc getCopyMaskFunc(size_t esz);
enum { BLOCK_SIZE = 1024 };
#ifdef HAVE_IPP
static inline IppiSize ippiSize(int width, int height) { IppiSize sz={width, height}; return sz; }
static inline IppiSize ippiSize(Size _sz) { reIppiSize sz={_sz.width, _sz.height}; return sz; }
#endif
#if defined HAVE_IPP && (IPP_VERSION_MAJOR >= 7)
#define ARITHM_USE_IPP 1
#define IF_IPP(then_call, else_call) then_call
#else
#define ARITHM_USE_IPP 0
#define IF_IPP(then_call, else_call) else_call
#endif
template<class Op, class VecOp> static void
binaryOpC1_( const Mat& srcmat1, const Mat& srcmat2, Mat& dstmat )
{
Op op; VecOp vecOp;
typedef typename Op::type1 T1;
typedef typename Op::type2 T2;
typedef typename Op::rtype DT;
const T1* src1 = (const T1*)srcmat1.data;
const T2* src2 = (const T2*)srcmat2.data;
DT* dst = (DT*)dstmat.data;
size_t step1 = srcmat1.step/sizeof(src1[0]);
size_t step2 = srcmat2.step/sizeof(src2[0]);
size_t step = dstmat.step/sizeof(dst[0]);
Size size = getContinuousSize( srcmat1, srcmat2, dstmat, dstmat.channels() );
if( size.width == 1 )
{
for( ; size.height--; src1 += step1, src2 += step2, dst += step )
dst[0] = op( src1[0], src2[0] );
return;
}
for( ; size.height--; src1 += step1, src2 += step2, dst += step )
{
int x;
x = vecOp(src1, src2, dst, size.width);
for( ; x <= size.width - 4; x += 4 )
{
DT f0, f1;
f0 = op( src1[x], src2[x] );
f1 = op( src1[x+1], src2[x+1] );
dst[x] = f0;
dst[x+1] = f1;
f0 = op(src1[x+2], src2[x+2]);
f1 = op(src1[x+3], src2[x+3]);
dst[x+2] = f0;
dst[x+3] = f1;
}
for( ; x < size.width; x++ )
dst[x] = op( src1[x], src2[x] );
}
}
typedef void (*BinaryFunc)(const Mat& src1, const Mat& src2, Mat& dst);
template<class Op> static void
binarySOpCn_( const Mat& srcmat, Mat& dstmat, const Scalar& _scalar )
{
Op op;
typedef typename Op::type1 T;
typedef typename Op::type2 WT;
typedef typename Op::rtype DT;
const T* src0 = (const T*)srcmat.data;
DT* dst0 = (DT*)dstmat.data;
size_t step1 = srcmat.step/sizeof(src0[0]);
size_t step = dstmat.step/sizeof(dst0[0]);
int cn = dstmat.channels();
Size size = getContinuousSize( srcmat, dstmat, cn );
WT scalar[12];
scalarToRawData(_scalar, scalar, CV_MAKETYPE(DataType<WT>::depth,cn), 12);
for( ; size.height--; src0 += step1, dst0 += step )
{
int i, len = size.width;
const T* src = src0;
T* dst = dst0;
for( ; (len -= 12) >= 0; dst += 12, src += 12 )
{
DT t0 = op(src[0], scalar[0]);
DT t1 = op(src[1], scalar[1]);
dst[0] = t0; dst[1] = t1;
t0 = op(src[2], scalar[2]);
t1 = op(src[3], scalar[3]);
dst[2] = t0; dst[3] = t1;
t0 = op(src[4], scalar[4]);
t1 = op(src[5], scalar[5]);
dst[4] = t0; dst[5] = t1;
t0 = op(src[6], scalar[6]);
t1 = op(src[7], scalar[7]);
dst[6] = t0; dst[7] = t1;
t0 = op(src[8], scalar[8]);
t1 = op(src[9], scalar[9]);
dst[8] = t0; dst[9] = t1;
t0 = op(src[10], scalar[10]);
t1 = op(src[11], scalar[11]);
dst[10] = t0; dst[11] = t1;
}
for( (len) += 12, i = 0; i < (len); i++ )
dst[i] = op((WT)src[i], scalar[i]);
}
}
template<class Op> static void
binarySOpC1_( const Mat& srcmat, Mat& dstmat, double _scalar )
{
Op op;
typedef typename Op::type1 T;
typedef typename Op::type2 WT;
typedef typename Op::rtype DT;
WT scalar = saturate_cast<WT>(_scalar);
const T* src = (const T*)srcmat.data;
DT* dst = (DT*)dstmat.data;
size_t step1 = srcmat.step/sizeof(src[0]);
size_t step = dstmat.step/sizeof(dst[0]);
Size size = srcmat.size();
size.width *= srcmat.channels();
if( srcmat.isContinuous() && dstmat.isContinuous() )
{
size.width *= size.height;
size.height = 1;
}
for( ; size.height--; src += step1, dst += step )
{
int x;
for( x = 0; x <= size.width - 4; x += 4 )
{
DT f0 = op( src[x], scalar );
DT f1 = op( src[x+1], scalar );
dst[x] = f0;
dst[x+1] = f1;
f0 = op( src[x+2], scalar );
f1 = op( src[x+3], scalar );
dst[x+2] = f0;
dst[x+3] = f1;
}
for( ; x < size.width; x++ )
dst[x] = op( src[x], scalar );
}
}
typedef void (*BinarySFuncCn)(const Mat& src1, Mat& dst, const Scalar& scalar);
typedef void (*BinarySFuncC1)(const Mat& src1, Mat& dst, double scalar);
}
#endif /*_CXCORE_INTERNAL_H_*/

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -170,12 +170,14 @@ struct IPPInitializer
IPPInitializer ippInitializer;
#else
volatile bool useOptimizedFlag = false;
volatile bool USE_SSE2 = false;
#endif
void setUseOptimized( bool flag )
{
useOptimizedFlag = flag;
currentFeatures = flag ? &featuresEnabled : &featuresDisabled;
USE_SSE2 = currentFeatures->have[CV_CPU_SSE2];
}
bool useOptimized(void)