最近在调用opencv的时候,我总是去看看opencv的原代码.在那些烦琐的宏定义里面感觉自己还是很有意思的.
cvGet2D( const CvArr* arr, int y, int x );//第一个坐标是y坐标,第二个是x坐标
CV_IMPL CvScalar
cvGet2D( const CvArr* arr, int y, int x )//CV_IMPL 宏定义extern "C"
{
CvScalar scalar = {{0,0,0,0}};
CV_FUNCNAME( "cvGet2D" );//这里的CV_FUNCNAME是传递一个函数名到系统全局静态变量cvFuncName,然后在CvError里面会用到这个变量,以便输出那个函数出错误.
__BEGIN__;//这里就是{
int type = 0;
uchar* ptr;
if( CV_IS_MAT( arr ))//普通矩阵数组
{
CvMat* mat = (CvMat*)arr;
if( (unsigned)y >= (unsigned)(mat->rows) ||
(unsigned)x >= (unsigned)(mat->cols) )
CV_ERROR( CV_StsOutOfRange, "index is out of range" );
type = CV_MAT_TYPE(mat->type);
ptr = mat->data.ptr + (size_t)y*mat->step + x*icvPixSize[type];
}
else if( !CV_IS_SPARSE_MAT( arr ))//图象
ptr = cvPtr2D( arr, y, x, &type );
else//稀疏矩阵数组
{
int idx[] = { y, x };
ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
}
cvRawDataToScalar( ptr, type, &scalar );
__END__;//这里就是#define __END__ goto exit; exit: ; },实际上就是执行了一个空语句.不明白用这样的宏在每个函数里面什么意思.
return scalar;
}
///
opencv里面有很多宏定义,IPPI_CALL一般是在函数调用的时候对函数指针做一个判断.
在看原文件Cvtemplmatch.cpp的时候,发现一些函数定义的初倪
//先定义一个函数的指针类型.下面的声明是调用了intel的内部函数,在opencv里面是找不到原代码的了.我是没有找到,但是不知道有没有牛人可以找到.
/***************************** IPP Match Template Functions ******************************/
icvCrossCorrValid_Norm_8u32f_C1R_t icvCrossCorrValid_Norm_8u32f_C1R_p = 0;
icvCrossCorrValid_NormLevel_8u32f_C1R_t icvCrossCorrValid_NormLevel_8u32f_C1R_p = 0;
icvSqrDistanceValid_Norm_8u32f_C1R_t icvSqrDistanceValid_Norm_8u32f_C1R_p = 0;
icvCrossCorrValid_Norm_32f_C1R_t icvCrossCorrValid_Norm_32f_C1R_p = 0;
icvCrossCorrValid_NormLevel_32f_C1R_t icvCrossCorrValid_NormLevel_32f_C1R_p = 0;
icvSqrDistanceValid_Norm_32f_C1R_t icvSqrDistanceValid_Norm_32f_C1R_p = 0;
typedef CvStatus (CV_STDCALL * CvTemplMatchIPPFunc)
( const void* img, int imgstep, CvSize imgsize,
const void* templ, int templstep, CvSize templsize,
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里面一个函数体,但是函数名称却是动态改变的,这个策略可以用到代码加密上.
#define ICV_DECL_CROSSCORR_DIRECT( flavor, arrtype, corrtype, worktype ) /
static CvStatus CV_STDCALL /
icvCrossCorrDirect_##flavor##_CnR( const arrtype* img0, int imgstep, /
CvSize imgsize, const arrtype* templ0, int templstep, CvSize templsize, /
corrtype* corr, int corrstep, CvSize corrsize, int cn ) /
{
//函数体
}
下面函数声明
ICV_DECL_CROSSCORR_DIRECT( 8u32f, uchar, float, int )
ICV_DECL_CROSSCORR_DIRECT( 32f, float, float, double )
ICV_DECL_CROSSCORR_DIRECT( 64f, double, double, double )
typedef CvStatus (CV_STDCALL * CvCrossCorrDirectFunc)(
const void* img, int imgstep, CvSize imgsize,
const void* templ, int templstep, CvSize templsize,
void* corr, int corrstep, CvSize corrsize, int cn );
下面是调用方法
CvCrossCorrDirectFunc corr_func = 0;
if( depth == CV_8U && corr_type == CV_32F )
corr_func = (CvCrossCorrDirectFunc)icvCrossCorrDirect_8u32f_CnR;
else if( depth == CV_32F && corr_type == CV_32F )
corr_func = (CvCrossCorrDirectFunc)icvCrossCorrDirect_32f_CnR;
else if( depth == CV_64F && corr_type == CV_64F )
corr_func = (CvCrossCorrDirectFunc)icvCrossCorrDirect_64f_CnR;
else
CV_ERROR( CV_StsUnsupportedFormat,
"Unsupported combination of input and output formats" );
IPPI_CALL( corr_func( img->data.ptr, img->step, imgsize,
templ->data.ptr, templ->step, templsize,
corr->data.ptr, corr->step, corrsize, cn ));
呵呵真的很有意思.