码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2016-07-15 11:14:25      阅读:707      评论:0      收藏:0      [点我收藏+]

标签:

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

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

标签:

原文地址:http://blog.csdn.net/autoliuweijie/article/details/51911289

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!