OpenCV3.1.0级联分类器训练与使用
OpenCV3.1.0级联分类器训练与使用
级联分类器第一次出现是由Viola-Jones在2001时候提出,其主要用来实现实时人脸检测,通过加载已经训练好的级联分类器数据,实现快速的级联分类器过滤,达到实时检测。这个过程可以表示如下:
其主要思想是首先通过一些简单的HAAR/LBP特征来快速过滤掉大多数非目标区域,然后通过迭代的方式不断添加特征数目从而达到高识别率,低拒绝率。在计算HAAR特征数据时候采用积分图像实现快速计算,最终实现整个过程的实时快速。在整个检测过程中训练好的级联分类器数据作用直接决定着对象检测率。
OpenCV中自带的HAAR/LBP级联检测器的数据多数都是关于人脸检测的,而在实际项目应用中,我们可能需要从不同的场景中检测某个相同对象,这种需求可以通过OpenCV中HAAR/LBP级联分类器训练工具来生成自己的级联分类器数据,然后通过程序实现自定义对象检测。而要想实现这个过程需要如下几步
一:样本数据准备
正样本
正样本要做到格式与大小一致,如果有背景的话,背景尽量统一,建议处理为黑色。正样本最少的集合在200张图片左右,然后必须有一个文本描述文件,总结起来如下图所示:
有了样本数据之后,可以通过OpenCV3.1.0中自带的工具opencv_createsamples.exe来生成正样本的.vec文件,通过命令行调用该工具即可,具体执行步骤如下:
负样本
负样本图像尽量要选取不同尺寸,不同背景的,但是里面不包含检测对象的图像,来源有两个 一是自己从网上获取,下载 二是从本地相册中选择,然后适当的裁剪 最终形成的负样本数据列表文本文件大致如下:
二:训练级联分类器
使用OpenCV3.1中自带的opencv_traincascade.exe工具输入适当的参数即可进行样本训练,在进行样本训练过程中会生成一些列的中间数据,格式均为XML,如果输入的参数适当,最终会完成样本训练得到cascade.xml文件,它就是级联分类器特征数据,通过程序加载它,然后调用OpenCV中级联分类器相关API即可实现对象分类检测。样本训练执行命令如下:
参数说明如下:
-numPos
表示每个Stage的正样本数目,必须小于总正样本数
-numNeg
表示每个Stage的负样本数目,可以大于等于总负样本数目
-featureType
表示特征类型,当前OpenCV3.x只支持HAAR与LBP
-numStages
表示多少个Stage,Stage的多少跟样本有直接关系。Stage数目过多,样本不足会导致训练无法继续进行。
-w
表示正样本的宽度,必须与创建vec文件时声明中保持一致
-h
表示正样本的高度,必须与创建vec文件时声明中保持一致
-minHitRate
表示最小命中率,用来衡量每层训练目标准确度
-maxFalseAlarmRate
最大虚警率(误检率),虚警过小可能导致特征过拟合,训练效果不好。默认是0.5
在正负样本1:1或者1:10的时候训练效果都不会太好,一般负数目应该是正样本数目的3~5倍左右。
三:常见错误分析
-Train dataset for temp stage can not be filled. Branch training terminated
出现这个错误的原因是正样本数据不够,而声明的Stage数目过多,解决这个问题一是增加样本数量,二是减小Stage数目。或者还有可能是负样本数据不足,或者样本数据的路径不正确。
-Traincascade Error: Bad argument (Can not get new positive sample. Themost possible reason is insufficient count of samples in given vec-file)
原因是训练时候-numPos 参数设置的正样本数目超过或者等于了总正样本数
四:使用训练数据的代码演示
小编采集了185个人脸图片,224个负样本图片,都来自互联网上。分别采用HAAR与LBP级联训练得到的级联分类器数据,演示效果如下:
代码如下
#include <opencv2/opencv.hpp>#include <iostream>using namespace cv;using namespace std;String face_cascade_name = "D:/vcprojects/cascadetrain/custom_face_cascade.xml";CascadeClassifier customFaceDetector;String window_name = "Capture - Face detection";int main(int argc, char** argv) { // 加载训练数据 if (!customFaceDetector.load(face_cascade_name)) { printf("could not load face data...n"); } // 加载测试图片 std::vector<Rect> faces; Mat gray_src; Mat src = imread("D:/testface.jpg"); // 转换为灰度图像 cvtColor(src, gray_src, COLOR_BGR2GRAY); equalizeHist(gray_src, gray_src); // 使用自己训练的级联检测器人脸检测 customFaceDetector.detectMultiScale(gray_src, faces, 1.3, 1, 0, Size(24, 24)); for (size_t t = 0; t < faces.size(); t++) { rectangle(src, faces[t], Scalar(0, 0, 255), 3); } // 显示结果 namedWindow(window_name, CV_WINDOW_AUTOSIZE); imshow(window_name, src); // 按任意键退出 waitKey(0); return 0;}
- 域名资讯:昨日域名成交2897个,成交额达300多万元
- 2017年12月编程语言排行榜:C语言再次崛起,有望成为2017年度编程语言
- WordPress 免插件仅代码实现 Gravatar 头像缓存
- Spring JDBCTemplate使用JNDI数据源
- 大家之前是不是误解了DC/OS与Kubernetes之间的关系
- CentOS 7 上部署Mono 4 和Jexus 5.6
- maven学习(下)利用Profile构建不同环境的部署包
- AS3初学者容易迷糊的几个问题
- Spring Security笔记:自定义Login/Logout Filter、AuthenticationProvider、AuthenticationToken
- ASP.NET Web API 2.1支持Binary JSON(Bson)
- Spring Security笔记:自定义登录页
- 浅析 Linux 初始化 init 系统
- 如何提高Python运行效率 超实用的四种提速方法
- 如何让oracle的select强制走索引
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- C++复习笔记——C++ 关键字
- python函数——字典设置默认值 setdefault()
- Day 3:从尾到头打印链表
- python函数——字典get()方法
- Day 4:重建二叉树
- python函数——字典设置默认值get() 与 setdefault()区别
- tensorflow学习笔记——0_零碎问题及解决笔记
- MapReduce工作笔记——Hadoop MR Streaming通用模板
- MapReduce工作笔记——Hadoop shell 常用文件操作命令
- Julia简易教程——4_字符串操作
- MapReduce工作笔记——Job上传普通文件和大文件
- MapReduce工作笔记——Streaming Job中jar包上传与使用指定
- MapReduce工作笔记——Job提交任务中-D和-jobconf的区别
- MapReduce工作笔记——Hadoop Streaming多目录/多路输入
- 矩阵操作试题(C++/Python)——矩阵元素顺时针旋转