WHCSRL 技术网

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。
一个完整的训练流程:

  1. 设置SVM的参数;
  2. 读取用于训练的xml文件;
  3. 获取用于训练集中图片的人脸区域;
  4. 将人脸区域转为HOG特征;
  5. 将生成的HOG特征作为SVM的输入;
  6. 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);

推荐阅读