前面介绍分类器检测过程的示例中是以HOG特征为例,那LBP和HAAR特征在xml中是如何表达和测试的呢?
2.3 LBP与HAAR特征
HAAR特征的计算和表达方式与HOG很类似,在OpenCV的haartraining.exe中,feature保存在每个weakclassifier中,而之后的traincascade.exe中则是以LBP、HOG、HAAR三种统一的方式——在stages后面用features节点来统一存储——来保存features的pool。
2.3.1 HAAR特征
在haar特征的训练中(无论是老版本的haartraining还是现在的traincascade),都是有BASIC/CORE/ALL三种特征组合待选的,默认情况为BASIC。三种情况下对应的特征选取分别如下:
BASIC:
(对于最后一种point型特征,在ALL类型中有看到,BASIC中没有看到,但不知是否被选入这种特征)
CORE中的增加项:
ALL中的增加项:
最后,HAAR特征的表达形式是以不止一个rect来表示的。比如
表达的是下图中的特征,tilted表达是否倾斜。
其中第一个矩形是外部最大的矩形,第二个为中间的红色矩形。
其他特征都是以类似的形式表达,矩形后的-1和3是该矩形的weight,也就是3*rect2-rect1;它的统一形式是sumof( rect[i]*weight[i] )。当然这里的rect同样是在维护一系列指向积分图中的指针。
2.3.2 LBP特征
LBP特征的计算与HAAR、HOG有很大不同,在判断某个矩形的LBP特征应当属于左叶子还是右叶子的时候,HAAR和HOG只是用当前节点的threshold来判定就可以了;而LBP的节点结构是图6所示:
图6. LBP节点示意图
节点中同样是有0和-1来做左右节点代码,33是feature ID,也就是所在的矩形,而后面紧跟的8个数将会被保存在vector<int> subset结构中,每个节点有8个这样的数,因而最终subset的size = nodes.size()* 8。
就以上面的这个节点来描述下判定规则:
首先33对应的是下面的矩形
这个矩形将对应到积分图中的16个int型指针,他们的对应关系如图7所示,ID号33中给出的矩形位置就是图中的A矩形。根据图中的关系可以得到9个矩形中的16个指针,每个指针存储的是积分图中该点右上方矩形内的灰度和。这样利用积分图能够快速计算出A~I共9个矩形内的灰度和,然后除E之外的其他矩形与E矩形内的结果作对比,大小将被标记为0或1,这样8个矩形将得到一个8位数c。
图7. Rect与LBP特征计算位置的关系示意图
接下来就是关键的如何根据c判断当前矩形应当走向左节点还是右节点了。
sum += cascadeLeaves[subset[c>>5]& (1 << (c & 31)) ? leafOfs : leafOfs+1];
c中的8个位由高到低分别来自于矩形A-B-C-F-I-H-G-D,因而c>>5得到的是上面ABC三个位所代表的0~7范围的一个数,根据此数将得到subset(也就是每个节点中都会存储的8个数)中的一个值,这里命名为X。1<<(c & 31)得到的是2^n,n是F-I-H-G-D共5个矩形的位,这里将2^n这个值命名为Y,可见Y的范围是1~2^31,(它想表达的就是在这5个矩形中的对比情况,因为他们是一一对应的)。最后X和Y做“按位与”运算如果是0就进入右节点,否则进入左节点。
这里的判定规则应该是有更好的诠释的,暂时还没有找到相关资料,以上仅仅是在代码中解析的一些内容。
相比其他两种,LBP的判定规则似乎有点复杂了。