opencv之莫名其妙的条件宏ICV_DEF_FIND_STUMP_THRESHOLD_SQ解释~
来源:互联网 发布:域名国外备案 编辑:程序博客网 时间:2024/05/06 20:08
本博转载自: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
0 0
- opencv之莫名其妙的条件宏ICV_DEF_FIND_STUMP_THRESHOLD_SQ解释~
- Opencv研读笔记:haartraining程序之莫名其妙的条件宏ICV_DEF_FIND_STUMP_THRESHOLD_SQ解释~
- Opencv研读笔记:haartraining程序之莫名其妙的条件宏ICV_DEF_FIND_STUMP_THRESHOLD_SQ解释~
- maven 之莫名其妙的问题
- 条件变量 pthread_cond_wait () 之解释~
- opencv meanStdDev的解释
- IE 条件解释的语句
- opencv之HoughCircle参数解释
- mybatis配置中sql莫名其妙报错,多半是条件中小于符号捣的鬼
- 有关opencv光流法的解释
- 莫名其妙的配置错误之解决方案!!!(终于解决了)
- 每日点滴之贰零壹壹年拾壹月贰拾叁日-莫名其妙缺少的磁盘空间
- Hadoop执行报错之莫名其妙的问题
- 优酷视频解析之莫名其妙的钻空子
- 《SVM笔记系列之三》拉格朗日乘数法和KKT条件的直观解释
- 莫名其妙的CSDN BLOG
- 莫名其妙的热血
- ASP 莫名其妙的错误
- Ubuntu 系统 Update-rc.d 命令
- 单向链表删除节点
- struts2使用session 的三种方式
- 32位和64位系统区别及int字节数
- cgi php-cgi,PHP底层原理
- opencv之莫名其妙的条件宏ICV_DEF_FIND_STUMP_THRESHOLD_SQ解释~
- Ubuntu Server下建立VPN服务器的方法
- LightOJ1010---Knights in Chessboard (规律题)
- C# 判断系统空闲(键盘、鼠标不操作一段时间)
- 引用的意义与本质
- jQuery表单验证插件jQueryValidationEngine使用
- Access violation reading location 0xD15965C4
- 第十四周项目4(1)-处理C++源代码的程序
- 在web.xml中为Struts2配置拦截器