织梦CMS - 轻松建站从此开始!

罗索

感受大师的代码风格_opencv源代码结构分析一

jackyhwei 发布于 2011-07-15 14:22 点击:次 
最近在调用opencv的时候,我总是去看看opencv的原代码.在那些烦琐的宏定义里面感觉自己还是很有意思的.
TAG:

最近在调用opencv的时候,我总是去看看opencv的原代码.在那些烦琐的宏定义里面感觉自己还是很有意思的.

cvGet2D( const CvArr* arr, int y, int x );//第一个坐标是y坐标,第二个是x坐标

  1. CV_IMPL  CvScalar 
  2. cvGet2D( const CvArr* arr, int y, int x )//CV_IMPL  宏定义extern "C" 
  3.     CvScalar scalar = {{0,0,0,0}}; 
  4.  
  5.     CV_FUNCNAME( "cvGet2D" );//这里的CV_FUNCNAME是传递一个函数名到系统全局
  6. //静态变量cvFuncName,然后在CvError里面会用到这个变量,以便输出那个函数出错误. 
  7.  
  8.     __BEGIN__;//这里就是{ 
  9.  
  10.     int type = 0; 
  11.     uchar* ptr; 
  12.  
  13.     if( CV_IS_MAT( arr ))//普通矩阵数组 
  14.     { 
  15.         CvMat* mat = (CvMat*)arr; 
  16.  
  17.         if( (unsigned)y >= (unsigned)(mat->rows) || 
  18.             (unsigned)x >= (unsigned)(mat->cols) ) 
  19.             CV_ERROR( CV_StsOutOfRange, "index is out of range" ); 
  20.  
  21.         type = CV_MAT_TYPE(mat->type); 
  22.         ptr = mat->data.ptr + (size_t)y*mat->step + x*icvPixSize[type]; 
  23.     } 
  24.     else if( !CV_IS_SPARSE_MAT( arr ))//图象 
  25.         ptr = cvPtr2D( arr, y, x, &type ); 
  26.     else//稀疏矩阵数组 
  27.     { 
  28.         int idx[] = { y, x }; 
  29.         ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 ); 
  30.     } 
  31.  
  32.     cvRawDataToScalar( ptr, type, &scalar ); 
  33.  
  34.     __END__;//这里就是#define __END__         goto exit; exit: ; },
  35. //实际上就是执行了一个空语句.不明白用这样的宏在每个函数里面什么意思. 
  36.  
  37.     return scalar; 

///

opencv里面有很多宏定义,IPPI_CALL一般是在函数调用的时候对函数指针做一个判断.

在看原文件Cvtemplmatch.cpp的时候,发现一些函数定义的初倪

//先定义一个函数的指针类型.下面的声明是调用了intel的内部函数,在opencv里面是找不到原代码的了.我是没有找到,但是不知道有没有牛人可以找到.

/***************************** IPP Match Template Functions ******************************/

  1. icvCrossCorrValid_Norm_8u32f_C1R_t  icvCrossCorrValid_Norm_8u32f_C1R_p = 0; 
  2. icvCrossCorrValid_NormLevel_8u32f_C1R_t  icvCrossCorrValid_NormLevel_8u32f_C1R_p = 0; 
  3. icvSqrDistanceValid_Norm_8u32f_C1R_t  icvSqrDistanceValid_Norm_8u32f_C1R_p = 0; 
  4. icvCrossCorrValid_Norm_32f_C1R_t  icvCrossCorrValid_Norm_32f_C1R_p = 0; 
  5. icvCrossCorrValid_NormLevel_32f_C1R_t  icvCrossCorrValid_NormLevel_32f_C1R_p = 0; 
  6. icvSqrDistanceValid_Norm_32f_C1R_t  icvSqrDistanceValid_Norm_32f_C1R_p = 0; 
  7.  
  8. typedef CvStatus (CV_STDCALL * CvTemplMatchIPPFunc) 
  9.     ( const void* img, int imgstep, CvSize imgsize, 
  10.       const void* templ, int templstep, CvSize templsize, 
  11.       void* result, int rstep ); 

/*****************************************************************************************/

定义一些函数指针,但是这些函数找不到

在cvMatchTemplate函数里面,根据不同的模板匹配方法,选择不同的函数.

CvTemplMatchIPPFunc ipp_func =
            depth == CV_8U ?
            (method == CV_TM_SQDIFF_NORMED ? (CvTemplMatchIPPFunc)icvSqrDistanceValid_Norm_8u32f_C1R_p :
            method == CV_TM_CCORR_NORMED ? (CvTemplMatchIPPFunc)icvCrossCorrValid_Norm_8u32f_C1R_p :
            (CvTemplMatchIPPFunc)icvCrossCorrValid_NormLevel_8u32f_C1R_p) :
            (method == CV_TM_SQDIFF_NORMED ? (CvTemplMatchIPPFunc)icvSqrDistanceValid_Norm_32f_C1R_p :
            method == CV_TM_CCORR_NORMED ? (CvTemplMatchIPPFunc)icvCrossCorrValid_Norm_32f_C1R_p :
            (CvTemplMatchIPPFunc)icvCrossCorrValid_NormLevel_32f_C1R_p);

在opencv里面一个函数体,但是函数名称却是动态改变的,这个策略可以用到代码加密上.

  1. #define ICV_DECL_CROSSCORR_DIRECT( flavor, arrtype, corrtype, worktype )    / 
  2. static CvStatus CV_STDCALL                                                  / 
  3. icvCrossCorrDirect_##flavor##_CnR( const arrtype* img0, int imgstep,        / 
  4.     CvSize imgsize, const arrtype* templ0, int templstep, CvSize templsize, / 
  5.     corrtype* corr, int corrstep, CvSize corrsize, int cn )                 / 
  6. {   
  7.  
  8.     //函数体 
  9.  

下面函数声明

  1. ICV_DECL_CROSSCORR_DIRECT( 8u32f, uchar, floatint ) 
  2. ICV_DECL_CROSSCORR_DIRECT( 32f, floatfloatdouble ) 
  3. ICV_DECL_CROSSCORR_DIRECT( 64f, doubledoubledouble ) 
  4.  
  5. typedef CvStatus (CV_STDCALL * CvCrossCorrDirectFunc)( 
  6.     const void* img, int imgstep, CvSize imgsize, 
  7.     const void* templ, int templstep, CvSize templsize, 
  8.     void* corr, int corrstep, CvSize corrsize, int cn ); 

下面是调用方法

  1. CvCrossCorrDirectFunc corr_func = 0; 
  2. if( depth == CV_8U && corr_type == CV_32F ) 
  3. corr_func = (CvCrossCorrDirectFunc)icvCrossCorrDirect_8u32f_CnR; 
  4. else if( depth == CV_32F && corr_type == CV_32F ) 
  5. corr_func = (CvCrossCorrDirectFunc)icvCrossCorrDirect_32f_CnR; 
  6. else if( depth == CV_64F && corr_type == CV_64F ) 
  7. corr_func = (CvCrossCorrDirectFunc)icvCrossCorrDirect_64f_CnR; 
  8. else 
  9. CV_ERROR( CV_StsUnsupportedFormat, 
  10. "Unsupported combination of input and output formats" ); 
  11.  
  12. IPPI_CALL( corr_func( img->data.ptr, img->step, imgsize, 
  13. templ->data.ptr, templ->step, templsize, 
  14.   corr->data.ptr, corr->step, corrsize, cn )); 

呵呵真的很有意思.

(luhuillll)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201107/14713.html]
本文出处:CSDN博客 作者:luhuillll
顶一下
(4)
80%
踩一下
(1)
20%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容