ubuntu20+dlib19.22+0pencv4.5.0的机器视觉算法之路(三)
ubuntu20+dlib19.22+0pencv4.5.0的非特定目标识别之手势识别算法
项目简介:
该项目包括训练和识别过程。
1. 训练模型
(1) 找到 imglab 工具源码目录进行配置编译
imglab位于dlib源码包的tools里面。
cd tools/imglab/
cmake .
make
- 1
- 2
- 3
编译完成后将生成的 imglab 可执行文件,将其拷贝到样本照片所在目录。
(2) 在dlib源码包找到 examples/train_object_detector.cpp 样本训练工具,将其拷贝出来单独进行编译,并生成 train_object_detector 可执行文件
(3) 图像采集:
dlib 对样本照片并没有太多要求,会做二次处理,样本拍摄建议在光线充足的情况下完成采集,样本数量越多越好,并将拍好的照片统一放在一个目录,比如 img 下面等待处理。
(4) 生成 xml 描述文件:
./imglab -c data.xml img
- 1
(5) 生成 xml 描述文件:
手动标记检测目标或特征点。在弹出的图形化工具上面对需要检测的特征进行标记,通过 shift 画框选择识别对象(这一步是必须的,不然训练不了,会报std::bad_array_new_length的错误),双击选中对象以后,右键可以标记特征点,标记完成点 File->save 保存结果到 xml 中。
命令如下:
./imglab data.xml
- 1
如果要标记特征点,需要增加参数
./imglab mydataset.xml --parts "1 2 3 4 5 6 7 8 9 10"
- 1
打开 xml 可以查看目标或特征的标记坐标,同时还生成了一个 image_metadata_stylesheet.xsl 样式文件。
(6) 训练样本
./train_object_detector -tv data.xml
- 1
训练结束后会生成 object_detector.svm 模型序列,这个模型就可以用于对象检测了。
训练效果比较好的话,要求数据多,而且标记的特征点要多要好。
2. 测试模型
一般先从训练样本中随便找张照片进行测试,测试如果能够成功找出目标后,再用于实际的目标识别。识别命令:
./train_object_detector photo.png
- 1
本实验我们先简单地只用三张图片进行测试:
其中:
识别:
3. 训练代码解析
train_object_detector.cpp,这里提供注释的代码下载:
https://download.csdn.net/download/weixin_39735688/35876581
在准备好训练集和测试集之后,便可以开始训练人脸检测模型。
大量的研究和实验表明,在物体检测的领域中,与HOG一起使用的算法中,SVM算法的效果是最好的。由于人脸检测也是物体检测的一种,所以我们的训练模型也会基HOG+SVM。
一个完整的训练流程:
- 设置SVM的参数;
- 读取用于训练的xml文件;
- 获取用于训练集中图片的人脸区域;
- 将人脸区域转为HOG特征;
- 将生成的HOG特征作为SVM的输入;
- SVM训练数据生成模型
我们从main函数看起,这里使用try和catch来检测代码是否有异常。
1.前部分使用command_line_parser指令,进行命令行解析。
2.加载目录的图片:
ignore = load_image_dataset(images, object_locations, parser[0]);
3.是否对图像进行上采样处理:
这里补充知识点:链接: 图像的上采样(upsampling)与下采样(subsampled).
4.训练参数
(1) C: 对误差的宽容度
在SVM中,C是惩罚系数,即对误差的宽容度。
C越高,说明越不能容忍出现误差,容易过拟合;
C越小,容易欠拟合。C过大或过小,泛化能力变差。
在本例中我们将C的值设置为5。
trainer.set_c(C)
- 1
(2) add_left_right_image_flips:对图片做镜像处理
对用于训练的图片做镜像处理,从而将训练集扩大一倍。一般都会设置为True。
add_image_left_right_flips(images, object_locations, ignore);
- 1
(3) be_verbose :输出训练的过程中的相关信息
是否输出训练的过程中的相关信息。我们设置为True。
trainer.be_verbose();
- 1
(4) num_threads:设置训练时使用的cpu的核数
设置训练时使用的cpu的核数。在这里我们设置为4。
trainer.set_epsilon(eps);
- 1
4.训练函数
object_detector<image_scanner_type> detector = trainer.train(images, object_locations, ignore);