📄 cxmatrix.cpp
字号:
}
if( size.width <= CV_MAX_LOCAL_MAT_SIZE )
{
buffer = (uchar*)cvStackAlloc( buf_size );
local_alloc = 1;
}
else
{
CV_CALL( buffer = (uchar*)cvAlloc( buf_size ));
}
CV_CALL( cvInitMatHeader( &tmat, size.height, size.width, worktype, buffer ));
if( type == worktype )
{
CV_CALL( cvCopy( src, &tmat ));
}
else
CV_CALL( cvConvert( src, &tmat ));
CV_CALL( cvSetIdentity( dst ));
decomp_func = (CvLUDecompFunc)(lu_decomp_tab.fn_2d[CV_MAT_DEPTH(type)-CV_32F]);
back_func = (CvLUBackFunc)(lu_back_tab.fn_2d[CV_MAT_DEPTH(type)-CV_32F]);
assert( decomp_func && back_func );
IPPI_CALL( decomp_func( tmat.data.db, tmat.step, size,
dst->data.ptr, dst->step, size, &result ));
if( result != 0 )
{
IPPI_CALL( back_func( tmat.data.db, tmat.step, size,
dst->data.ptr, dst->step, size ));
}
}
if( !result )
CV_CALL( cvSetZero( dst ));
__END__;
if( buffer && !local_alloc )
cvFree( &buffer );
if( u || v || w )
{
cvReleaseMat( &u );
cvReleaseMat( &v );
cvReleaseMat( &w );
}
return result;
}
/****************************************************************************************\
* Linear system [least-squares] solution *
\****************************************************************************************/
CV_IMPL int
cvSolve( const CvArr* A, const CvArr* b, CvArr* x, int method )
{
CvMat* u = 0;
CvMat* v = 0;
CvMat* w = 0;
uchar* buffer = 0;
int local_alloc = 0;
int result = 1;
CV_FUNCNAME( "cvSolve" );
__BEGIN__;
CvMat sstub, *src = (CvMat*)A;
CvMat dstub, *dst = (CvMat*)x;
CvMat bstub, *src2 = (CvMat*)b;
int type;
if( !CV_IS_MAT( src ))
CV_CALL( src = cvGetMat( src, &sstub ));
if( !CV_IS_MAT( src2 ))
CV_CALL( src2 = cvGetMat( src2, &bstub ));
if( !CV_IS_MAT( dst ))
CV_CALL( dst = cvGetMat( dst, &dstub ));
if( method == CV_SVD || method == CV_SVD_SYM )
{
int n = MIN(src->rows,src->cols);
if( method == CV_SVD_SYM && src->rows != src->cols )
CV_ERROR( CV_StsBadSize, "CV_SVD_SYM method is used for non-square matrix" );
CV_CALL( u = cvCreateMat( n, src->rows, src->type ));
if( method != CV_SVD_SYM )
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 ? v : u, src2, dst, CV_SVD_U_T + CV_SVD_V_T ));
EXIT;
}
else if( method != CV_LU )
CV_ERROR( CV_StsBadArg, "Unknown inversion method" );
type = CV_MAT_TYPE( src->type );
if( !CV_ARE_TYPES_EQ( src, dst ) || !CV_ARE_TYPES_EQ( src, src2 ))
CV_ERROR( CV_StsUnmatchedFormats, "" );
if( src->width != src->height )
CV_ERROR( CV_StsBadSize, "The matrix must be square" );
if( !CV_ARE_SIZES_EQ( src2, dst ) || src->width != src2->height )
CV_ERROR( CV_StsUnmatchedSizes, "" );
if( type != CV_32FC1 && type != CV_64FC1 )
CV_ERROR( CV_StsUnsupportedFormat, "" );
// check case of a single equation and small matrix
if( src->width <= 3 && src2->width == 1 )
{
#define bf(y) ((float*)(bdata + y*src2step))[0]
#define bd(y) ((double*)(bdata + y*src2step))[0]
uchar* srcdata = src->data.ptr;
uchar* bdata = src2->data.ptr;
uchar* dstdata = dst->data.ptr;
int srcstep = src->step;
int src2step = src2->step;
int dststep = dst->step;
if( src->width == 2 )
{
if( type == CV_32FC1 )
{
double d = det2(Sf);
if( d != 0. )
{
float t;
d = 1./d;
t = (float)((bf(0)*Sf(1,1) - bf(1)*Sf(0,1))*d);
Df(1,0) = (float)((bf(1)*Sf(0,0) - bf(0)*Sf(1,0))*d);
Df(0,0) = t;
}
else
result = 0;
}
else
{
double d = det2(Sd);
if( d != 0. )
{
double t;
d = 1./d;
t = (bd(0)*Sd(1,1) - bd(1)*Sd(0,1))*d;
Dd(1,0) = (bd(1)*Sd(0,0) - bd(0)*Sd(1,0))*d;
Dd(0,0) = t;
}
else
result = 0;
}
}
else if( src->width == 3 )
{
if( type == CV_32FC1 )
{
double d = det3(Sf);
if( d != 0. )
{
float t[3];
d = 1./d;
t[0] = (float)(d*
(bf(0)*(Sf(1,1)*Sf(2,2) - Sf(1,2)*Sf(2,1)) -
Sf(0,1)*(bf(1)*Sf(2,2) - Sf(1,2)*bf(2)) +
Sf(0,2)*(bf(1)*Sf(2,1) - Sf(1,1)*bf(2))));
t[1] = (float)(d*
(Sf(0,0)*(bf(1)*Sf(2,2) - Sf(1,2)*bf(2)) -
bf(0)*(Sf(1,0)*Sf(2,2) - Sf(1,2)*Sf(2,0)) +
Sf(0,2)*(Sf(1,0)*bf(2) - bf(1)*Sf(2,0))));
t[2] = (float)(d*
(Sf(0,0)*(Sf(1,1)*bf(2) - bf(1)*Sf(2,1)) -
Sf(0,1)*(Sf(1,0)*bf(2) - bf(1)*Sf(2,0)) +
bf(0)*(Sf(1,0)*Sf(2,1) - Sf(1,1)*Sf(2,0))));
Df(0,0) = t[0];
Df(1,0) = t[1];
Df(2,0) = t[2];
}
else
result = 0;
}
else
{
double d = det3(Sd);
if( d != 0. )
{
double t[9];
d = 1./d;
t[0] = ((Sd(1,1) * Sd(2,2) - Sd(1,2) * Sd(2,1))*bd(0) +
(Sd(0,2) * Sd(2,1) - Sd(0,1) * Sd(2,2))*bd(1) +
(Sd(0,1) * Sd(1,2) - Sd(0,2) * Sd(1,1))*bd(2))*d;
t[1] = ((Sd(1,2) * Sd(2,0) - Sd(1,0) * Sd(2,2))*bd(0) +
(Sd(0,0) * Sd(2,2) - Sd(0,2) * Sd(2,0))*bd(1) +
(Sd(0,2) * Sd(1,0) - Sd(0,0) * Sd(1,2))*bd(2))*d;
t[2] = ((Sd(1,0) * Sd(2,1) - Sd(1,1) * Sd(2,0))*bd(0) +
(Sd(0,1) * Sd(2,0) - Sd(0,0) * Sd(2,1))*bd(1) +
(Sd(0,0) * Sd(1,1) - Sd(0,1) * Sd(1,0))*bd(2))*d;
Dd(0,0) = t[0];
Dd(1,0) = t[1];
Dd(2,0) = t[2];
}
else
result = 0;
}
}
else
{
assert( src->width == 1 );
if( type == CV_32FC1 )
{
double d = Sf(0,0);
if( d != 0. )
Df(0,0) = (float)(bf(0)/d);
else
result = 0;
}
else
{
double d = Sd(0,0);
if( d != 0. )
Dd(0,0) = (bd(0)/d);
else
result = 0;
}
}
}
else
{
CvLUDecompFunc decomp_func;
CvLUBackFunc back_func;
CvSize size = cvGetMatSize( src );
CvSize dstsize = cvGetMatSize( dst );
int worktype = CV_64FC1;
int buf_size = size.width*size.height*CV_ELEM_SIZE(worktype);
double d = 0;
CvMat tmat;
if( !lu_inittab )
{
icvInitLUTable( &lu_decomp_tab, &lu_back_tab );
lu_inittab = 1;
}
if( size.width <= CV_MAX_LOCAL_MAT_SIZE )
{
buffer = (uchar*)cvStackAlloc( buf_size );
local_alloc = 1;
}
else
{
CV_CALL( buffer = (uchar*)cvAlloc( buf_size ));
}
CV_CALL( cvInitMatHeader( &tmat, size.height, size.width, worktype, buffer ));
if( type == worktype )
{
CV_CALL( cvCopy( src, &tmat ));
}
else
CV_CALL( cvConvert( src, &tmat ));
if( src2->data.ptr != dst->data.ptr )
{
CV_CALL( cvCopy( src2, dst ));
}
decomp_func = (CvLUDecompFunc)(lu_decomp_tab.fn_2d[CV_MAT_DEPTH(type)-CV_32F]);
back_func = (CvLUBackFunc)(lu_back_tab.fn_2d[CV_MAT_DEPTH(type)-CV_32F]);
assert( decomp_func && back_func );
IPPI_CALL( decomp_func( tmat.data.db, tmat.step, size,
dst->data.ptr, dst->step, dstsize, &d ));
if( d != 0 )
{
IPPI_CALL( back_func( tmat.data.db, tmat.step, size,
dst->data.ptr, dst->step, dstsize ));
}
else
result = 0;
}
if( !result )
CV_CALL( cvSetZero( dst ));
__END__;
if( buffer && !local_alloc )
cvFree( &buffer );
if( u || v || w )
{
cvReleaseMat( &u );
cvReleaseMat( &v );
cvReleaseMat( &w );
}
return result;
}
/****************************************************************************************\
* 3D vector cross-product *
\****************************************************************************************/
CV_IMPL void
cvCrossProduct( const CvArr* srcAarr, const CvArr* srcBarr, CvArr* dstarr )
{
CV_FUNCNAME( "cvCrossProduct" );
__BEGIN__;
CvMat stubA, *srcA = (CvMat*)srcAarr;
CvMat stubB, *srcB = (CvMat*)srcBarr;
CvMat dstub, *dst = (CvMat*)dstarr;
int type;
if( !CV_IS_MAT(srcA))
CV_CALL( srcA = cvGetMat( srcA, &stubA ));
type = CV_MAT_TYPE( srcA->type );
if( srcA->width*srcA->height*CV_MAT_CN(type) != 3 )
CV_ERROR( CV_StsBadArg, "All the input arrays must be continuous 3-vectors" );
if( !srcB || !dst )
CV_ERROR( CV_StsNullPtr, "" );
if( (srcA->type & ~CV_MAT_CONT_FLAG) == (srcB->type & ~CV_MAT_CONT_FLAG) &&
(srcA->type & ~CV_MAT_CONT_FLAG) == (dst->type & ~CV_MAT_CONT_FLAG) )
{
if( !srcB->data.ptr || !dst->data.ptr )
CV_ERROR( CV_StsNullPtr, "" );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -