2010. 12. 17. 00:22



void myPCA( CvMat* A, CvMat* U2 ) {
 CvMat* U  = ::cvCreateMat( A->rows, A->cols, A->type );
 CvMat* S  = ::cvCreateMat( A->cols, A->cols, A->type );
 functionFillMatrixUandS( A, S, U );

 // GOAL: Efficent way copy data from U to U2, Just like crop matrix U as size of U2
 // Matlab:  [ uy, ux ] = size(U);
 //              U2 = U( 1:uy, 1:ux ); % simple isn't it?
 
  // 1. Create header only matrix, if you give null matrix it cause error
 CvMat* header = ::cvCreateMatHeader( U2->width, U2->height, U2->type );
  // 2. Fill matrix 'header' with pointers which pointing each row start position in U element
  //    accessing matrix element are restricted width small size(resized matrix width),
  //    accessing next row restricted with U's step
  //    header matrix has U's step, U2's width
 ::cvGetSubRect( U, header, cvRect( 0, 0, U2->width, U2->height ) );
  // 3. Need hard copy, to survie without U matrix
 ::cvCopy( header, U2 );

 ::cvReleaseMat( &U );
 ::cvReleaseMat( &header );
 ::cvReleaseMat( &S );
}

note:

// Selects sub-array (no data is copied)
CV_IMPL  CvMat*
cvGetSubRect( const CvArr* arr, CvMat* submat, CvRect rect )
{
    /*
    int* refcount = mat->refcount;

    if( refcount )
        ++*refcount;

    cvDecRefData( submat );
    */
    submat->data.ptr = mat->data.ptr + (size_t)rect.y*mat->step +
                       rect.x*CV_ELEM_SIZE(mat->type);
    submat->step = mat->step;
    submat->type = (mat->type & (rect.width < mat->cols ? ~CV_MAT_CONT_FLAG : -1)) |
                   (rect.height <= 1 ? CV_MAT_CONT_FLAG : 0);
    submat->rows = rect.height;
    submat->cols = rect.width;
    submat->refcount = 0;
    res = submat;

    return res;
}

 

Posted by newpolaris