OpenCV训练自己的人脸检测级连分类器并测试

0. 概述

分为如下几步:

step1. 制作训练数据集

step2. 训练分类器

step3. 使用分类器进行分类

1. 准备工作

建立一个项目目录objection_detection/

$ mkdir objection_detection/
$ cd objection_detection/

建立一个训练数据集目录train_img_set/用于存放训练图片

$ mkdir train_img_set/

下载MIT_Face数据集,并将训练图片的face/和non-face/图片集拷贝到train_img_set/中

MIT_Face下载地址: http://cbcl.mit.edu/software-datasets/FaceData2.html

制作info.dat文件和bg.txt文件:

$ cd train_img_set/
$ subl info.dat
$ subl bg.txt

info.dat文件内容如下(1 表示样本标签,0 0 18 18表示在图片0,0,宽18,长18的矩形型区域):

face/cmu_0000.pgm 1 0 0 18 18
face/cmu_0001.pgm 1 0 0 18 18
face/cmu_0002.pgm 1 0 0 18 18
            ...
face/cmu_0471.pgm 1 0 0 18 18

bg.txt文件内容如下, 为了避免路径错误,建议使用绝对路径:

/Users/liuweijie/workspace/objection_detection/train_img_set/non-face/cmu_0000.pgm
/Users/liuweijie/workspace/objection_detection/train_img_set/non-face/cmu_0001.pgm
/Users/liuweijie/workspace/objection_detection/train_img_set/non-face/cmu_0002.pgm
                                                ...
/Users/liuweijie/workspace/objection_detection/train_img_set/non-face/cmu_9999.pgm

生成以上两个文件可以通过如下python脚本实现, 该脚本放置在train_img_set/目录下:

#! /usr/local/bin/python
import os
import cv2 as cv

POSTIVE_DIR = ‘face/‘
NEGATIVE_DIR = ‘non-face/‘
INFO_FILENAME = ‘info.dat‘
BG_FILENAME = ‘bg.txt‘

this_dir = os.path.abspath(os.path.dirname(__file__))
postive_url = os.path.join(this_dir, POSTIVE_DIR)
negative_url = os.path.join(this_dir, NEGATIVE_DIR)

# create info.dat
img_list = os.listdir(postive_url)
with open(os.path.join(this_dir, INFO_FILENAME), ‘wb‘) as file:

    for img_name in img_list:

        img_url = os.path.join(postive_url, img_name)
        img = cv.imread(img_url)
        cols, rows = img.shape[:2]

        file.write(POSTIVE_DIR + img_name + ‘ 1 0 0 %s %s\n‘ % (cols - 1, rows - 1))

# create bg.txt
img_list = os.listdir(negative_url)
with open(os.path.join(this_dir, BG_FILENAME), ‘wb‘) as file:

    for img_name in img_list:

        file.write(negative_url + img_name + ‘\n‘)

此时准备工作完毕,项目目录结构如下

objection_detection/
└── train_img_set/
    ├── face/
    │   ├── cmu_0000.pgm
    │   ├── ...
    │   └── cmu_0471.pgm
    ├── non-face/
    │   ├── cmu_0000.pgm
    │   ├── ...
    │   └── cmu_9999.pgm
    ├── info.dat/
    ├── bg.txt
    └── create_info_bg.py

2. 制作训练数据集

负样本图片就是bg.txt描述,不用制作。正类样本要用opencv_createsamples命令制作

它会从face/中根据info.dat的描述截取图片区域,并以*.vec二进制的形式保存正样本训练集。

这个命令的详细介绍参考如下:

http://docs.opencv.org/2.4/doc/user_guide/ug_traincascade.html

我们写成run_create_samples.sh脚本,放在train_img_set目录下:

#!/usr/bin/env sh

OUTPUT=./train_set.vec
INFO_FILE=./info.dat
BG_FILE=./bg.txt
NUM=472
WEIGHT=18
HIGHT=18

opencv_createsamples     -vec $OUTPUT     -info $INFO_FILE     -bg $BG_FILE     -num $NUM     -show     -w $WEIGHT     -h $HIGHT 

执行该脚本,就会把正样本的图片训练集以二进制形式保存在train_set.vec文件中。

这一步要注意的是NUM, WEIGHT, HIGHT这三个参数,分别是生成的正样本数量,生成正样本图片的宽,高。

3. 训练分类器

首先在项目目录objection_detection/下建一个output/目录来存放训练结果。

cd ../
$ mkdir output

使用opencv_traincascade命令来进行训练,该命令的具体可查看:

http://blog.csdn.net/giantchen547792075/article/details/7404261

我们写成train_classifier.sh脚本,放在objection_detection/目录下:

#!/usr/bin/env sh

OUTPUT_FILE=./output
VEC_FILE=./train_img_set/train_set.vec
BG_FILE=./train_img_set/bg.txt
NUM_POS=47
NUM_NEG=999
NUM_STAGE=10
VAL_BUFSIZE=1024
IDX_BUFSIZE=1024

STAGE_TYPE=BOOST
FEATURE_TYPE=HAAR
# FEATURE_TYPE=LBP
WEIGHT=18
HEIGHT=18

BT=GAB
MIN_HITRATE=0.995
MAX_FALSE_ALARM_RATE=0.05
WEIGHT_TRIM_RATE=0.95
MAX_DEPTH=1
MAX_WEAK_COUNT=100

MODE=BASIC

opencv_traincascade     -data $OUTPUT_FILE     -vec $VEC_FILE     -bg $BG_FILE     -numPos $NUM_POS     -numNeg $NUM_NEG     -numStages $NUM_STAGE     -precalcValBufSize $VAL_BUFSIZE     -precalcIdxBufSize $IDX_BUFSIZE     -stageType $STAGE_TYPE     -featureType $FEATURE_TYPE     -w $WEIGHT     -h $HEIGHT     -bt $BT     -minHitRate $MIN_HITRATE     -maxFalseAlarmRate $MAX_FALSE_ALARM_RATE     -weightTrimRate $WEIGHT_TRIM_RATE     -maxDepth $MAX_DEPTH     -maxWeakCount $MAX_WEAK_COUNT     -mode $MODE     # -baseFormatSave 

注意:这里存在一个bug, 就是-baseFormatSave的话训练出来的xml格式会错误,所以暂且不加,bug报告在这:

http://code.opencv.org/issues/2387

重点关注如下参数:

-data 结果输出的位置目录;
-numPos 每一级训练时用的正样本数量
-numNeg 每一级训练时用的负样本数量
-numStages 级连的级数
-stageType 每一级用什么分类器
-featureType 每一级选用什么特征
-w 图片的宽,必须与之前一致
-h 图片的高,必须与之前一致
-bt 训练方法
-minHitRate 目标每一级的最小真阳率  真阳数/所有正样本数
-maxFalseAlarmRate 目标每一级的最大勿检率  假阳数/所有负样本数
-maxDepth 每一级的最大深度
-maxWeakCount 每一级的最大弱分类器数量

执行该脚本。

$ chmod 777 train_classifier.sh
$ ./train_classifier.sh

此时就开始训练,会看到如下内容:

PARAMETERS:
cascadeDirName: ./output
vecFileName: ./train_img_set/train_set.vec
bgFileName: ./train_img_set/bg.txt
numPos: 50
numNeg: 200
numStages: 5
precalcValBufSize[Mb] : 1024
precalcIdxBufSize[Mb] : 1024
acceptanceRatioBreakValue : -1
stageType: BOOST
featureType: HAAR
sampleWidth: 18
sampleHeight: 18
boostType: GAB
minHitRate: 0.995
maxFalseAlarmRate: 0.05
weightTrimRate: 0.95
maxDepth: 1
maxWeakCount: 100
mode: BASIC

===== TRAINING 0-stage =====
<BEGIN
POS count : consumed   50 : 50
NEG count : acceptanceRatio    200 : 1
Precalculation time: 0
+----+---------+---------+
|  N |    HR   |    FA   |
+----+---------+---------+
|   1|        1|        1|
+----+---------+---------+
|   2|        1|     0.31|
+----+---------+---------+
|   3|        1|     0.31|
+----+---------+---------+
|   4|        1|    0.095|
+----+---------+---------+
|   5|        1|    0.055|
+----+---------+---------+
|   6|        1|    0.055|
+----+---------+---------+
|   7|        1|     0.01|
+----+---------+---------+
END>
Training until now has taken 0 days 0 hours 0 minutes 2 seconds.

===== TRAINING 1-stage =====

            ...
            ...

===== TRAINING 4-stage =====
<BEGIN
POS count : consumed   50 : 50
NEG count : acceptanceRatio    200 : 0.000419196
Precalculation time: 0
+----+---------+---------+
|  N |    HR   |    FA   |
+----+---------+---------+
|   1|        1|        1|
+----+---------+---------+
|   2|        1|        1|
+----+---------+---------+
|   3|        1|     0.35|
+----+---------+---------+
|   4|        1|     0.35|
+----+---------+---------+
|   5|        1|    0.055|
+----+---------+---------+
|   6|        1|     0.04|
+----+---------+---------+
END>
Training until now has taken 0 days 0 hours 0 minutes 34 seconds.

此时在output/目录下会得到cascade.xml文件和一些其他中间过程的文件。cascade.xml就是训练好的级连分类器,其他中间过程文件可以删了。

3. 使用分类器进行分类

在项目目录下创建一个test_img_set目录,里面放一些测试图片。

在项目目录下创建test_classifier.py脚本来使用分类器:

‘‘‘
Test the classifier
‘‘‘
import numpy as np
import cv2

face_cascade = cv2.CascadeClassifier(‘./output/cascade.xml‘)

img = cv2.imread(‘./test_img_set/big_masters.jpg‘)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

faces = face_cascade.detectMultiScale(gray, 1.3, 5)

for (x, y, w, h) in faces:
    cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)

cv2.imshow(‘img‘, img)
cv2.waitKey(0)
cv2.destroyAllWindows()

也可以去opencv官方库下载一些训练好的xml文件来,会比自己的效果好很多。

整个项目最终的文件目录结构如下

You can download the project from here:

https://code.csdn.net/autoliuweijie/computervision/tree/master/python/Part.X.ObjectionDetection/51.objection_detection

参考

http://www.cnblogs.com/tornadomeet/archive/2012/03/28/2420936.html

时间: 2024-11-05 23:34:26

OpenCV训练自己的人脸检测级连分类器并测试的相关文章

基于OpenCV读取摄像头进行人脸检测和人脸识别

前段时间使用OpenCV的库函数实现了人脸检测和人脸识别,笔者的实验环境为VS2010+OpenCV2.4.4,opencv的环境配置网上有很多,不再赘述.检测的代码网上很多,记不清楚从哪儿copy的了,识别的代码是从OpenCV官网上找到的:http://docs.opencv.org/trunk/modules/contrib/doc/facerec/facerec_api.html 需要注意的是,opencv的FaceRecogizer目前有三个类实现了它,特征脸和fisherface方法

【从零学习openCV】IOS7根据人脸检测

前言: 人脸检測与识别一直是计算机视觉领域一大热门研究方向,并且也从安全监控等工业级的应用扩展到了手机移动端的app.总之随着人脸识别技术获得突破,其应用前景和市场价值都是不可估量的,眼下在学习openCV,自然不能放过这个领域.于是略微了解了下openCV下人脸检測的一些原理.为之后的人脸识别等研究做个小小的铺垫. 原理: 人脸检測属于目标检測(object detection) 的一部分,主要涉及两个方面 先对要检測的目标对象进行概率统计,从而知道待检測对象的一些特征,建立起目标检測模型.

浅析人脸检测之Haar分类器方法:Haar特征、积分图、 AdaBoost 、级联

浅析人脸检测之Haar分类器方法 一.Haar分类器的前世今生 人脸检测属于计算机视觉的范畴,早期人们的主要研究方向是人脸识别,即根据人脸来识别人物的身份,后来在复杂背景下的人脸检测需求越来越大,人脸检测也逐渐作为一个单独的研究方向发展起来. 目前的人脸检测方法主要有两大类:基于知识和基于统计. Ø  基于知识的方法:主要利用先验知识将人脸看作器官特征的组合,根据眼睛.眉毛.嘴巴.鼻子等器官的特征以及相互之间的几何位置关系来检测人脸. Ø  基于统计的方法:将人脸看作一个整体的模式——二维像素矩

OpenCV实践之路——人脸检测(C++/Python) 【转】

转自:http://blog.csdn.net/xingchenbingbuyu/article/details/51105159 版权声明:本文为博主原创文章,转载请联系作者取得授权. 本文由@星沉阁冰不语出品,转载请注明作者和出处. 文章链接:http://blog.csdn.net/xingchenbingbuyu/article/details/51105159 微博:http://weibo.com/xingchenbing  之前一直觉得人脸检测是非常麻烦的,即使是用OpenCV,麻

OpenCV实践之路——人脸检测(C++/Python)

之前一直觉得人脸检测是非常麻烦的,即使是用opencv,麻烦到我都不敢去碰.这两天仔细看了下,如果只是调用opencv自带的分类器和函数的话,简直是简单.这不,正好最近也在学习Python,索性就用C++和Python两种语言都实现一下.当然,我现在这个是最简单的版本. 步骤: 调用opencv训练好的分类器和自带的检测函数检测人脸人眼等的步骤简单直接: 1.加载分类器,当然分类器事先要放在工程目录中去.分类器本来的位置是在*\opencv\sources\data\haarcascades(h

浅谈人脸检测之Haar分类器方法

我们要探讨的Haar分类器实际上是Boosting算法(提升算法)的一个应用,Haar分类器用到了Boosting算法中的AdaBoost算法,只是把AdaBoost算法训练出的强分类器进行了级联,并且在底层的特征提取中采用了高效率的矩形特征和积分图方法,这里涉及到的几个名词接下来会具体讨论. 在2001年,Viola和Jones两位大牛发表了经典的<Rapid Object Detection using a Boosted Cascade of Simple Features>和<R

人脸检测和haar分类器视频讲解

刚开始学习人脸检测时,非常郁闷什么是haar分类器,一直是迷迷糊糊的,搞不清楚什么是弱分类器,什么是强分类器,什么是级联分类器,还有检测窗口是如何在待检测图片上运行的,这个小视频会生动形象的展示给你的,想必你会有个直观理解的,快快点击吧  https://vimeo.com/34631229. 点击打开链接 这个小视频是我查找资料中无意中找到的,真实很不容易的,我想如果一开始就看这个小视频的话,再看论文也好,研究opencv源代码也好,会入门更快.对于人脸检测的其他入门方面的小文章,可以参考我的

OpenCV学习代码记录——人脸检测

很久之前学习过一段时间的OpenCV,当时没有做什么笔记,但是代码都还在,这里把它贴出来做个记录. 代码放在码云上,地址在这里https://gitee.com/solym/OpenCVTest/tree/master/OpenCVTest #include <opencv2/core.hpp> #include <opencv2/highgui.hpp> #include <opencv2/objdetect.hpp> #include <opencv2/img

win10+anaconda+cuda配置dlib,使用GPU对dlib的深度学习算法进行加速(以人脸检测为例)

在计算机视觉和机器学习方向有一个特别好用但是比较低调的库,也就是dlib,与opencv相比其包含了很多最新的算法,尤其是深度学习方面的,因此很有必要学习一下.恰好最近换了一台笔记本,内含一块GTX1060的显卡,可以用来更快地跑深度学习算法.以前用公司HP的工作站配置过dlib,GPU是Quadro K420,用dlib自带的人脸识别算法(ResNet)测试过,相比较1060的速度确实要快上很多.dlib.cuda和cudnn的版本经常会更新,每次重新配置环境会遇到一些问题,在这里记下来吧.