最近一段在用opencv自带的分类器训练函数训练分类器,遇到了一点问题:
分类器预设的stage=20太深,当训练到第6层时,已经收敛,而由于训练数据非常多,再往下训练非常耗时(已经卡住三天了),因此我就想,如何把目前生成的6层弱分类器连接起来,当做最终的分类器(精度已经达到要求)。然后就查询网络,得到了下面的解决方法:
1.直接根据最终分类器.xml的格式要求,将stagei.xml拼接起来。
这个方法是最直接的,我仿照着opencv3.0自带的分类器haarcascade_eye.xml中的格式,将我生成的stage0.xml、stage1.xml、stage2.xml等依次复制替换进去,然后进行识别的测试,结果报错,分类器格式不对。
然后查阅文献,发现分类器的xml文件组成比较复杂,而关键的问题是stagei.xml中并没有存储每个节点对应的haar特征:字段缺失,所以当然无法直接拼接。 方法1错误。
2.opencv自带的convert_cascade.exe进行拼接。
这个方法是网上能查到的最常见的解决方法,我也进行了测试,
convert_cascade.exe –size=”20x20” D:\Training\cascade D:\CE-5\Training\cascade\haar_adaboost.xml
但依旧报错,因为该函数是opencv2.x对应的,其用的分类器训练函数是opencv_haartraining.exe,和我们3.0的方法不同,生成的stage文件当然不同。
随后我转到opencv3.0中查找opencv-3..0\modules\objdetect\src\cascadedetect_convert.cpp,进行测试,依旧错误。在网上查好像该函数并不是为了拼接用,好像是转换最终生成的分类器.xml文件的。方法2错误。
3.最后的方法。
折腾了有两三天都没搞出来,很无语。突然灵光一闪,我们可以终止原来的训练函数,然后将训练阶数设置成6(与目前训练分类器卡住的位置相同),然后opencv会自动读取之前训练的结果stagei.xml,生成最终的分类器:cascade.xml。
然后bingo,测试后效果也不错,终于搞定了!!!!
PS. 想问题,往往容易陷入死角,这个时候应该跳出来,换个思路去做;国内网站可以搜到的东西很多都是重复无用的,学好英文多搜搜国外的网站,多Google