文章目录

一、级联分类器训练简介

在深度学习成熟的年代,很少需要级联分类器了,在垂直领域一些简单检测的场景下,还是有点作用的,模型简单,检测速度快。

xml文件精简:使用python脚本处理xml文件,将若分类器的数据float64->float32或float16进一步加快速度。

使用 Haar、LBP、HOG 特征训练级联分类器
关于 ​级联分类器(使用)​ 以及详情查看。
关于 ​​​OpenCV—Python CascadeClassifier(级联分类器)​​ 点击查看。

操作步骤

  1. 收集样本数据 – 包括正负样本
  2. 数据规范化 – 大小、格式
  3. 生成vec文件与负样本列表文本文件
  4. 使用OpenCV自动的级联分类器训练工具,训练样本数据
  5. 得到最终的级联分类器数据(XML格式)

(1)以人脸检测为例 –公开的数据库有

  • 正向样本数目
  • 负样本数目
  • 正向样本的大小 – 统一尺寸
  • 正向样本图片中的背景问题

(2)样本集合与描述:正(负)样本集合与描述文件
(3)使用 opencv_createsamples.exe 正样本VEC文件创建
(4)使用 opencv_traincascade.exe 训练样本数据

这两个文件:opencv_traincascaded.exe 和 opencv_createsamplesd.exe 在opencv3.4以上版本就需要编译。​​https://zhuanlan.zhihu.com/p/109364375​​ 为避免麻烦,我直接下载opencv3.4版本。

OpenCV + CPP 系列(卌七)级联分类器训练_级联分类器


OpenCV + CPP 系列(卌七)级联分类器训练_opencv_02

创建样本

创建 info.dat 文件 (负样本文件同理 bg.txt)
所有正样本文件都在当前目录positive下面, 负样本文件在negative下面

import os
from PIL import Image


def get_write_dat(input_path):
f = open(input_path+"/info.dat", "w")
for root, dirs, files in os.walk(input_path):
for file in files:
if file.endswith((".png", ".bmp", ".jpg")):
print("file: ", file)
try:
img = Image.open(os.path.join(root, file))
w, h = img.size
f.write(" ".join(["positive/"+file, str(1), str(0), str(0), str(w), str(h)])+"\n")
except Exception as e:
print(e)
f.close()


if __name__ == '__main__':
input_path = r"D:\opencv-c++\cascade\positive"
get_write_dat(input_path)

文件info.dat里的内容说明如下:(负样本只需要路径即可)

OpenCV + CPP 系列(卌七)级联分类器训练_级联分类器_03


创建训练样本vec:执行如下命令

opencv_createsamples.exe \
-info D:\opencv-c++\cascade\positive\info.dat \
-vec D:\opencv-c++\cascade\positive\positive_samples.vec \
-num 185 \
-bgcolor 0 \
-bgthresh 0 \
-w 24 \
-h 24

OpenCV + CPP 系列(卌七)级联分类器训练_c++_04

训练样本

opencv_traincascade.exe \
-data D:\opencv-c++\cascade \
-vec D:\opencv-c++\cascade\positive_samples.vec \
-bg bg.txt \
-numPos 170 \
-numNeg 500 \
-numStages 12 \
-featureType LBP \
-w 24 \
-h 24 \
-minHitRate 0.996 \
-maxFalseAlarmRate 0.5

说明:
​​​-numPos 170​​​正样本数小于185(所有正样本)
​​​-numNeg 500​​​正样本数大于224(所有负样本)
​​​-featureType LBP​​ 使用LBP训练快(测试一下)

OpenCV + CPP 系列(卌七)级联分类器训练_级联分类器_05


很快,训练完如下:

OpenCV + CPP 系列(卌七)级联分类器训练_c++_06

其中上面​​cascade.xml​​文件即为训练的模型文件。

关于更多详情:​​查看官方文档​​ 字段说明如下:

  • -data指定生成的文件目录,
  • -vecvec文件名,
  • -bg负样本描述文件名称,也就是负样本的说明文件(.dat)
  • -nstage20 指定训练层数,推荐15~20,层数越高,耗时越长。
  • -nsplits分裂子节点数目,选取默认值 2
  • -minhitrate最小命中率,即训练目标准确度。
  • -maxfalsealarm最大虚警(误检率),每一层训练到这个值小于0.5时训练结束,进入下一层训练,
  • -npos在每个阶段用来训练的正样本数目,
  • -nneg在每个阶段用来训练的负样本数目 这个值可以设置大于真正的负样本图像数目,程序可以自动从负样本图像中切割出和正样本大小一致的,一般设置为正样本数目的1~3倍
  • -mem程序可使用的内存,这个设置为256即可,实际运行时根本就不怎么耗内存,以MB为单位
  • -modeALL指定haar特征的种类,BASIC仅仅使用垂直特征,ALL表示使用垂直以及45度旋转特征
  • -w-h表示样本的宽与高,必须跟vec中声明保持一致