cvmatrix.cpp.svn-base
来自「非结构化路识别」· SVN-BASE 代码 · 共 1,534 行 · 第 1/5 页
SVN-BASE
1,534 行
A[i] = (arrtype)inv_val; \
\
/* update matrix and the right side of the system */ \
for( j = i + 1; j < n; j++ ) \
{ \
double alpha; \
\
(char*&)tA += stepA; \
(char*&)tB += stepB; \
\
alpha = -tA[i]*inv_val; \
\
for( k = i + 1; k < n; k++ ) \
tA[k] = (arrtype)(tA[k] + alpha*A[k]); \
\
if( m > 0 ) \
for( k = 0; k < m; k++ ) \
tB[k] = (arrtype)(tB[k] + alpha*B[k]); \
} \
} \
\
if( _det ) \
*_det = det; \
\
return CV_OK; \
}
ICV_DEF_LU_DECOMP_FUNC( 32f, float )
ICV_DEF_LU_DECOMP_FUNC( 64f, double )
#define ICV_DEF_LU_BACK_FUNC( flavor, arrtype ) \
IPCVAPI_IMPL( CvStatus, \
icvLUBack_##flavor, ( arrtype* A, int stepA, CvSize sizeA, \
arrtype* B, int stepB, CvSize sizeB )) \
{ \
int n = sizeA.width; \
int m = sizeB.width, i; \
\
assert( m > 0 && sizeA.width == sizeA.height && \
sizeA.height == sizeB.height ); \
\
(char*&)A += stepA*(n - 1); \
(char*&)B += stepB*(n - 1); \
\
for( i = n - 1; i >= 0; i--, (char*&)A -= stepA ) \
{ \
int j, k; \
\
for( j = 0; j < m; j++ ) \
{ \
arrtype* tB = B + j; \
double x = 0; \
\
for( k = n - 1; k > i; k--, (char*&)tB -= stepB ) \
x += A[k]*tB[0]; \
\
tB[0] = (arrtype)((tB[0] - x)*A[i]); \
} \
} \
\
return CV_OK; \
}
ICV_DEF_LU_BACK_FUNC( 32f, float )
ICV_DEF_LU_BACK_FUNC( 64f, double )
static CvFuncTable lu_decomp_tab, lu_back_tab;
static int lu_inittab = 0;
static void icvInitLUTable( CvFuncTable* decomp_tab,
CvFuncTable* back_tab )
{
decomp_tab->fn_2d[0] = (void*)icvLUDecomp_32f;
decomp_tab->fn_2d[1] = (void*)icvLUDecomp_64f;
back_tab->fn_2d[0] = (void*)icvLUBack_32f;
back_tab->fn_2d[1] = (void*)icvLUBack_64f;
}
/****************************************************************************************\
* Determinant *
\****************************************************************************************/
#define det2(m) (m(0,0)*m(1,1) - m(0,1)*m(1,0))
#define det3(m) (m(0,0)*(m(1,1)*m(2,2) - m(1,2)*m(2,1)) - \
m(0,1)*(m(1,0)*m(2,2) - m(1,2)*m(2,0)) + \
m(0,2)*(m(1,0)*m(2,1) - m(1,1)*m(2,0)))
CV_IMPL double
cvDet( const CvArr* arr )
{
double result = 0;
uchar* buffer = 0;
int local_alloc = 0;
CV_FUNCNAME( "cvDet" );
__BEGIN__;
CvMat stub, *mat = (CvMat*)arr;
int type;
if( !CV_IS_MAT( mat ))
{
CV_CALL( mat = cvGetMat( mat, &stub ));
}
type = CV_MAT_TYPE( mat->type );
if( mat->width != mat->height )
CV_ERROR( CV_StsBadSize, "The matrix must be square" );
#define Mf( y, x ) ((float*)(m + y*step))[x]
#define Md( y, x ) ((double*)(m + y*step))[x]
if( mat->width == 2 )
{
uchar* m = mat->data.ptr;
int step = mat->step;
if( type == CV_32FC1 )
{
result = det2(Mf);
}
else if( type == CV_64FC1 )
{
result = det2(Md);
}
else
{
CV_ERROR( CV_StsUnsupportedFormat, "" );
}
}
else if( mat->width == 3 )
{
uchar* m = mat->data.ptr;
int step = mat->step;
if( type == CV_32FC1 )
{
result = det3(Mf);
}
else if( type == CV_64FC1 )
{
result = det3(Md);
}
else
{
CV_ERROR( CV_StsUnsupportedFormat, "" );
}
}
else if( mat->width == 1 )
{
if( type == CV_32FC1 )
{
result = mat->data.fl[0];
}
else if( type == CV_64FC1 )
{
result = mat->data.db[0];
}
else
{
CV_ERROR( CV_StsUnsupportedFormat, "" );
}
}
else
{
CvLUDecompFunc decomp_func;
CvSize size = icvGetMatSize( mat );
int buf_size = size.width*size.height*icvPixSize[type];
CvMat tmat;
if( !lu_inittab )
{
icvInitLUTable( &lu_decomp_tab, &lu_back_tab );
lu_inittab = 1;
}
if( CV_MAT_CN( type ) != 1 || CV_MAT_DEPTH( type ) < CV_32F )
CV_ERROR( CV_StsUnsupportedFormat, "" );
if( size.width <= CV_MAX_LOCAL_MAT_SIZE )
{
buffer = (uchar*)alloca( buf_size + 8 );
buffer = (uchar*)icvAlignPtr( buffer, 8 );
local_alloc = 1;
}
else
{
CV_CALL( buffer = (uchar*)cvAlloc( buf_size ));
}
CV_CALL( cvInitMatHeader( &tmat, size.height, size.width, type, buffer ));
CV_CALL( cvCopy( mat, &tmat ));
decomp_func = (CvLUDecompFunc)(lu_decomp_tab.fn_2d[CV_MAT_DEPTH(type)-CV_32F]);
assert( decomp_func );
IPPI_CALL( decomp_func( tmat.data.ptr, tmat.step, size, 0, 0, size, &result ));
}
#undef Mf
#undef Md
icvCheckVector_64f( &result, 1 );
__END__;
if( buffer && !local_alloc )
cvFree( (void**)&buffer );
return result;
}
/****************************************************************************************\
* Inverse Matrix *
\****************************************************************************************/
#define Sf( y, x ) ((float*)(srcdata + y*srcstep))[x]
#define Sd( y, x ) ((double*)(srcdata + y*srcstep))[x]
#define Df( y, x ) ((float*)(dstdata + y*dststep))[x]
#define Dd( y, x ) ((double*)(dstdata + y*dststep))[x]
CV_IMPL double
cvInvert( const CvArr* srcarr, CvArr* dstarr, int method )
{
CvMat* u = 0;
CvMat* v = 0;
CvMat* w = 0;
uchar* buffer = 0;
int local_alloc = 0;
double result = 0;
CV_FUNCNAME( "cvInvert" );
__BEGIN__;
CvMat sstub, *src = (CvMat*)srcarr;
CvMat dstub, *dst = (CvMat*)dstarr;
int type;
if( !CV_IS_MAT( src ))
CV_CALL( src = cvGetMat( src, &sstub ));
if( !CV_IS_MAT( dst ))
CV_CALL( dst = cvGetMat( dst, &dstub ));
type = CV_MAT_TYPE( src->type );
if( method == CV_SVD )
{
int n = MIN(src->rows,src->cols);
CV_CALL( u = cvCreateMat( n, src->rows, src->type ));
CV_CALL( v = cvCreateMat( n, src->cols, src->type ));
CV_CALL( w = cvCreateMat( n, 1, src->type ));
CV_CALL( cvSVD( src, w, u, v, CV_SVD_U_T + CV_SVD_V_T ));
CV_CALL( cvSVBkSb( w, u, v, 0, dst, CV_SVD_U_T + CV_SVD_V_T ));
if( type == CV_32FC1 )
result = w->data.fl[0] >= FLT_EPSILON ?
w->data.fl[w->rows-1]/w->data.fl[0] : 0;
else
result = w->data.db[0] >= FLT_EPSILON ?
w->data.db[w->rows-1]/w->data.db[0] : 0;
CV_CALL( cvSVBkSb( w, u, v, 0, dst, CV_SVD_U_T + CV_SVD_V_T ));
EXIT;
}
else if( method != CV_LU )
CV_ERROR( CV_StsBadArg, "Unknown inversion method" );
if( !CV_ARE_TYPES_EQ( src, dst ))
CV_ERROR( CV_StsUnmatchedFormats, "" );
if( src->width != src->height )
CV_ERROR( CV_StsBadSize, "The matrix must be square" );
if( !CV_ARE_SIZES_EQ( src, dst ))
CV_ERROR( CV_StsUnmatchedSizes, "" );
if( type != CV_32FC1 && type != CV_64FC1 )
CV_ERROR( CV_StsUnsupportedFormat, "" );
if( src->width <= 3 )
{
uchar* srcdata = src->data.ptr;
uchar* dstdata = dst->data.ptr;
int srcstep = src->step;
int dststep = dst->step;
if( src->width == 2 )
{
if( type == CV_32FC1 )
{
double d = det2(Sf);
if( d != 0. )
{
double t0, t1;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?