My fourth day of OpenCV

    前一天未开电脑,写下这OpenCV的所谓“第四天”,倒是已经是开始的第五天了。

    结束了第二章的内容,第三章不再码代码,更多地从基本功开始探索OpenCV了。

    首先,Getting to Know OpenCV先介绍了CvPoint、CvSize、CvRect、CvScalar四种数据结构,它们各自有着自己名字雷同或相似的构造函数,它们几个的关系被说得妙趣横生,CvPoint(成员有x、y,其亲戚为CvPoint2D32f and CvPoint3D32f,后者多一维z),CvSize(成员有width和height,皆为整型,它的堂兄弟CvSize2D32f则为浮点型),CvRect被作者说成是CvPoint和CvSize的收养的“孩子”(画外音:以免吾等读者误会其“乱伦”),CvScalar的成员是double型val[4](代表RGBA value,A是Alpha通道)

   接下来的大量笔墨花在了CvMat之上。说到矩阵的类型,其写法值得记忆:

   CV_<bit_depth>(S|U|F)C<number_of_channels>

   (一)矩阵的构造方法有五个:

   1.cvCreateMat()

      // Create a new rows by cols matrix of type ‘type’.
      CvMat* cvCreateMat( int rows, int cols, int type );

   2.cvCreateMatHeader()

     // Create only matrix header without allocating data
     CvMat* cvCreateMatHeader( int rows, int cols, int type );

   3.cvCreateData()

     // Initialize header on existing CvMat structure
        CvMat* cvInitMatHeader(CvMat* mat,int rows,int cols,int type,void* data = NULL,int step =      

                                           CV_AUTOSTEP);

   4.cvCloneMat

     // Allocate a new matrix just like the matrix ‘mat’.
        CvMat* cvCloneMat( const cvMat* mat );

   5.cvMat

      // Like cvInitMatHeader() but allocates CvMat as well.
         CvMat cvMat(int rows,int cols,int type,void* data = NULL);

   (二)而矩阵的查询函数则有:

    cvGetElemType( const CvArr* arr ), cvGetDims( const CvArr* arr, int* sizes=NULL ),
    和 cvGetDimSize( const CvArr* arr, int index ).  用途基本都可以望文生义(注:Dim是维数dimension的缩写)

   (三)获得矩阵元素
   1.简单的方法

      CvMat* mat = cvCreateMat( 5, 5, CV_32FC1 );
      float element_3_2 = CV_MAT_ELEM( *mat, float, 3, 2 );

 

      CvMat* mat = cvCreateMat( 5, 5, CV_32FC1 );
      float element_3_2 = 7.7;
      *( (float*)CV_MAT_ELEM_PTR( *mat, 3, 2 ) ) = element_3_2; 

       CV_MAT_ELEM_PTR比之CV_MAT_ELEM,区别也无非在于其为指针,仅仅读取的话CV_MAT_ELEM即可,但   

       CV_MAT_ELEM_PTR还能够设定元素值。果然有个指针定位就是不一般啊。

   2.难办的方法

     仅仅读取的话:

double cvGetReal1D( const CvArr* arr, int idx0 );
double cvGetReal2D( const CvArr* arr, int idx0, int idx1 );
double cvGetReal3D( const CvArr* arr, int idx0, int idx1, int idx2 );
double cvGetRealND( const CvArr* arr, int* idx );
CvScalar cvGet1D( const CvArr* arr, int idx0 );
CvScalar cvGet2D( const CvArr* arr, int idx0, int idx1 );
CvScalar cvGet3D( const CvArr* arr, int idx0, int idx1, int idx2 );
CvScalar cvGetND( const CvArr* arr, int* idx );

若是还要设定矩阵元素值:

double cvmGet( const CvMat* mat, int row, int col )
void cvmSet( CvMat* mat, int row, int col, double value )

3.正确的方法

何谓正确之法呢?实际上在博主看来,作者想要告诉我们的就是,实际操作中我们会偏向于最高效的方法,可能会自己写一些矩阵操作以符合实际最迫切的需求,此时,你不会用以上介绍的那么多已经被写好的函数,此时,我们要做的就是了解矩阵数据结构,然后写函数一步到位地达到目的。下面的例子就是书中附带的求矩阵个各元素求和的函数

float sum( const CvMat* mat ) {
float s = 0.0f;
for(int row=0; row<mat->rows; row++ ) {
const float* ptr = (const float*)(mat->data.ptr + row * mat->step);
for( col=0; col<mat->cols; col++ ) {
s += *ptr++;
}
}
return( s );
}

(四)点阵的存储

今天看的最后一部分内容。其中心是N个m维点的存储方式有很多,可能是将其作为m维处理,也可能作为1维处理(这时就有m溜),前者的array中元素是点,而后者的元素是数。

博主今日看英文已经超过承受水平,脑子都混乱了,很多细节和问题也都没有深究,希望今后在实践中能够透彻理解。先放过自己的脑细胞吧,放假的节奏快不起来呀!

posted @ 2013-01-29 23:02  傻呵呵的日子  阅读(233)  评论(0编辑  收藏  举报