opencv之莫名其妙的条件宏ICV_DEF_FIND_STUMP_THRESHOLD_SQ解释~
2015-06-08 15:25
393 查看
本博转载自:http://www.itnose.net/detail/6183849.html
曾经有一刻,一直在纠结opencv->haartraining中的条件宏ICV_DEF_FIND_STUMP_THRESHOLD_SQ的使用,该宏的作用是寻找特征值数组中的最佳阈值,使得error最小。
ICV_DEF_FIND_STUMP_THRESHOLD_SQ代码如下:
其中,ICV_DEF_FIND_STUMP_THRESHOLD定义如下:
当时觉得很奇怪,内部条件宏ICV_DEF_FIND_STUMP_THRESHOLD括号内明明只有 suffix, type, error 三个参数,怎么调用传递的时候
里面却是上面这个样子,前面两个参数,外加两句代码行?
后来弄明白了,我们注意看ICV_DEF_FIND_STUMP_THRESHOLD中的error的相关使用就知道了,在ICV_DEF_FIND_STUMP_THRESHOLD中间,孤零零的一句代码
原来error不能说的上是条件宏的一个参数,他就是一个代码段,调用的时候,相当于直接把代码段粘贴到上面的位置!
为啥要这么用呢,原因就是error代表的代码段,复用率十分高,所以索性直接写成这样的形式,C语言,真的是灵活异常哎。。。。
类似的宏还有:
此外,sq_##suffix起到了连接字符串的功能,如果suffix是16s,那么sq_##suffix实际上就是sq_16s,再然后,直接指向相关函数。
本文转自:http://www.itnose.net/detail/6183849.html
曾经有一刻,一直在纠结opencv->haartraining中的条件宏ICV_DEF_FIND_STUMP_THRESHOLD_SQ的使用,该宏的作用是寻找特征值数组中的最佳阈值,使得error最小。
ICV_DEF_FIND_STUMP_THRESHOLD_SQ代码如下:
/* least sum of squares error */ #define ICV_DEF_FIND_STUMP_THRESHOLD_SQ( suffix, type ) \ ICV_DEF_FIND_STUMP_THRESHOLD( sq_##suffix, type, \ /* calculate error (sum of squares) */ \ /* err = sum( w * (y - left(rigt)Val)^2 ) */ \ curlerror = wyyl + curleft * curleft * wl - 2.0F * curleft * wyl; \ currerror = (*sumwyy) - wyyl + curright * curright * wr - 2.0F * curright * wyr; \ )
其中,ICV_DEF_FIND_STUMP_THRESHOLD定义如下:
#define ICV_DEF_FIND_STUMP_THRESHOLD( suffix, type, error ) \ CV_BOOST_IMPL int icvFindStumpThreshold_##suffix( \ uchar* data, size_t datastep, \ uchar* wdata, size_t wstep, \ uchar* ydata, size_t ystep, \ uchar* idxdata, size_t idxstep, int num, \ float* lerror, \ float* rerror, \ float* threshold, float* left, float* right, \ float* sumw, float* sumwy, float* sumwyy ) \ { \ int found = 0; \ float wyl = 0.0F; \ float wl = 0.0F; \ float wyyl = 0.0F; \ float wyr = 0.0F; \ float wr = 0.0F; \ \ float curleft = 0.0F; \ float curright = 0.0F; \ float* prevval = NULL; \ float* curval = NULL; \ float curlerror = 0.0F; \ float currerror = 0.0F; \ float wposl; \ float wposr; \ \ int i = 0; \ int idx = 0; \ \ wposl = wposr = 0.0F; \ if( *sumw == FLT_MAX ) \ { \ /* calculate sums */ \ float *y = NULL; \ float *w = NULL; \ float wy = 0.0F; \ \ *sumw = 0.0F; \ *sumwy = 0.0F; \ *sumwyy = 0.0F; \ for( i = 0; i < num; i++ ) \ { \ idx = (int) ( *((type*) (idxdata + i*idxstep)) ); \ w = (float*) (wdata + idx * wstep); \ *sumw += *w; \ y = (float*) (ydata + idx * ystep); \ wy = (*w) * (*y); \ *sumwy += wy; \ *sumwyy += wy * (*y); \ } \ } \ \ for( i = 0; i < num; i++ ) \ { \ idx = (int) ( *((type*) (idxdata + i*idxstep)) ); \ curval = (float*) (data + idx * datastep); \ /* for debug purpose */ \ if( i > 0 ) assert( (*prevval) <= (*curval) ); \ \ wyr = *sumwy - wyl; \ wr = *sumw - wl; \ \ if( wl > 0.0 ) curleft = wyl / wl; \ else curleft = 0.0F; \ \ if( wr > 0.0 ) curright = wyr / wr; \ else curright = 0.0F; \ \ error \ \ if( curlerror + currerror < (*lerror) + (*rerror) ) \ { \ (*lerror) = curlerror; \ (*rerror) = currerror; \ *threshold = *curval; \ if( i > 0 ) { \ *threshold = 0.5F * (*threshold + *prevval); \ } \ *left = curleft; \ *right = curright; \ found = 1; \ } \ \ do \ { \ wl += *((float*) (wdata + idx * wstep)); \ wyl += (*((float*) (wdata + idx * wstep))) \ * (*((float*) (ydata + idx * ystep))); \ wyyl += *((float*) (wdata + idx * wstep)) \ * (*((float*) (ydata + idx * ystep))) \ * (*((float*) (ydata + idx * ystep))); \ } \ while( (++i) < num && \ ( *((float*) (data + (idx = \ (int) ( *((type*) (idxdata + i*idxstep))) ) * datastep)) \ == *curval ) ); \ --i; \ prevval = curval; \ } /* for each value */ \ \ return found; \ }
当时觉得很奇怪,内部条件宏ICV_DEF_FIND_STUMP_THRESHOLD括号内明明只有 suffix, type, error 三个参数,怎么调用传递的时候
ICV_DEF_FIND_STUMP_THRESHOLD( sq_##suffix, type, \ /* calculate error (sum of squares) */ \ /* err = sum( w * (y - left(rigt)Val)^2 ) */ \ curlerror = wyyl + curleft * curleft * wl - 2.0F * curleft * wyl; \ currerror = (*sumwyy) - wyyl + curright * curright * wr - 2.0F * curright * wyr; \
里面却是上面这个样子,前面两个参数,外加两句代码行?
后来弄明白了,我们注意看ICV_DEF_FIND_STUMP_THRESHOLD中的error的相关使用就知道了,在ICV_DEF_FIND_STUMP_THRESHOLD中间,孤零零的一句代码
\ error \ \
原来error不能说的上是条件宏的一个参数,他就是一个代码段,调用的时候,相当于直接把代码段粘贴到上面的位置!
为啥要这么用呢,原因就是error代表的代码段,复用率十分高,所以索性直接写成这样的形式,C语言,真的是灵活异常哎。。。。
类似的宏还有:
ICV_DEF_FIND_STUMP_THRESHOLD_MISC( 16s, short ) ICV_DEF_FIND_STUMP_THRESHOLD_MISC( 32s, int ) ICV_DEF_FIND_STUMP_THRESHOLD_MISC( 32f, float ) ICV_DEF_FIND_STUMP_THRESHOLD_GINI( 16s, short ) ICV_DEF_FIND_STUMP_THRESHOLD_GINI( 32s, int ) ICV_DEF_FIND_STUMP_THRESHOLD_GINI( 32f, float ) ICV_DEF_FIND_STUMP_THRESHOLD_ENTROPY( 16s, short ) ICV_DEF_FIND_STUMP_THRESHOLD_ENTROPY( 32s, int ) ICV_DEF_FIND_STUMP_THRESHOLD_ENTROPY( 32f, float )
此外,sq_##suffix起到了连接字符串的功能,如果suffix是16s,那么sq_##suffix实际上就是sq_16s,再然后,直接指向相关函数。
本文转自:http://www.itnose.net/detail/6183849.html
相关文章推荐
- Linux
- 第十四周项目3-OOP版电子词典
- centos7 通过kvm+vnc 实现远程桌面虚拟化和创建windows、Linux虚拟机
- OpenGL glLightfv 函数的应用以及光源的相关知识
- 使用Apache Commons-email邮件客户端发邮件
- linux的日志管理
- Linux 设备模型之 (kobject、kset 和 Subsystem)(二)
- Linux环境数据备份Python脚本
- 如何开始学习ADF和Jdeveroper 11g
- 对视图有时为什么使用select top 100 percent * 而不使用 select * 呢?
- centos7下配置postfix
- Linux 文件查找命令find,xargs详述
- linux -- Ubuntu network-manager
- 菜鸟学Linux
- Properties文件不在项目目录下的一种读取方法
- Intel CPU 历代微架构名称
- Hadoop 实现Rackawareness
- Centos 6.5 install caffe+Nvidia driver+cuda 6.5
- linux下overcommit_memory的问题
- 将ImageMagic库编译进nginx