使用OpenCV训练自己的级联分类器,生成可用的xml文件

级联分类器包括两部分:训练和检测。 这个指南是描述如何训练分类器:准备训练数据和运行训练程序。
[官网]:http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/user_guide/ug_traincascade.html

重点注意事项

OpenCV中有两个程序可以训练级联分类器: opencv_haartraining and opencv_traincascadeopencv_traincascade 是一个新程序,使用OpenCV 2.x API 以C++ 编写。这二者主要的区别是 opencv_traincascade 支持 Haar [Viola2001] 和 LBP [Liao2007] (Local Binary Patterns) 两种特征,并易于增加其他的特征。与Haar特征相比,LBP特征是整数特征,因此训练和检测过程都会比Haar特征快几倍。LBP和Haar特征用于检测的准确率,是依赖训练过程中的训练数据的质量和训练参数。训练一个与基于Haar特征同样准确度的LBP的分类器是可能的。

opencv_traincascade and opencv_haartraining 所输出的分类器文件格式并不相同。注意,新的级联检测接口(参考 objdetect 模块中的 CascadeClassifier 类)支持这两种格式。 opencv_traincascade 可以旧格式导出选练好的级联分类器。但是在训练过程被中断后再重启训练过程, opencv_traincascade and opencv_haartraining 不能装载与中断前不同的文件格式。

opencv_traincascade 程序使用TBB来处理多线程。如果希望使用多核并行运算加速,请使用TBB来编译OpenCV。

还有一些与训练相关的辅助程序。

opencv_createsamples 用来准备训练用的正样本数据和测试数据。 opencv_createsamples 能够生成能被 opencv_haartraining 和 opencv_traincascade 程序支持的正样本数据。它的输出为以 *.vec 为扩展名的文件,该文件以二进制方式存储图像。
opencv_performance 可以用来评估分类器的质量,但只能评估 opencv_haartraining 输出的分类器。它读入一组标注好的图像,运行分类器并报告性能,如检测到物体的数目,漏检的数目,误检的数目,以及其他信息。

既然 opencv_haartraining 是一个将被弃用的程序,下面将不再介绍,而会主要介绍 opencv_traincascade 。 opencv_createsamples 程序用来为 opencv_traincascade 准备训练样本,因此也会介绍它。

准备训练数据

训练需要一些列样本。样本分两类:负样本和正样本。负样本是指不包括物体的图像。正样本是待检测的物体的图像。负样本必须手工准备,正样本使用 opencv_createsamples 创建。

(1).负样本
负样本可以是任意图像,但是这些图像中不能包含待检测的物体。用于抠取负样本的图像文件名被列在一个文件中。这个文件是纯文本文件,每行是一个文件名(包括相对目录和文件名)。负样本和样本图像也叫做背景样本,或者背景样本图像,本文档中对之不予区分。这些图像可以是不同的尺寸,但是图像尺寸应该比训练窗口的尺寸大,因为这些图像将被用于抠取负样本,并将负样本缩小到训练窗口大小。

下面是一个描述文件的例子:
假如目录结构如下:

/img
  img1.jpg
  img2.jpg
bg.txt

则bg.txt文件中的内容将如下所示:

img/img1.jpg
img/img2.jpg

(2).正样本
正样本由 opencv_createsamples 生成。正样本可以由包含待检测物体的一张图片生成,也可由一系列标记好的图像生成。

请注意你需要一个很大的负样本库送给训练程序进行训练。如果是绝对刚性的物体,如OpenCV的标志,你只有一张正样本图像;如果是人脸,你需要几百甚至几千个正样本。在待检测物体是人脸的情况下,你需要考虑所有的人种、年龄、表情甚至胡子的样式。

如果只有一张包含物体的图像,如一个公司的标志,那么可以通过对物体图像的随机旋转、改变标志亮度以及将标志放在任意的背景上而获得大量的正样本。生成的正样本数目以及随机的程度都可以通过 opencv_createsamples 的命令行参数控制。

命令行参数

参数含义
-vec <vec_file_name>输出文件,内含用于训练的正样本
-img <image_file_name>输入图像文件名(例如一个公司的标志)
-bg <background_file_name>背景图像(负样本)的描述文件,文件中包含一系列的图像文件名,这些图像将被随机选作物体的背景
-num <number_of_samples>生成的正样本的数目
-bgcolor <background_color>背景颜色(目前为灰度图);背景颜色表示透明颜色。因为图像压缩可造成颜色偏差,颜色的容差可以由 -bgthresh 指定。所有处于 bgcolor-bgthresh 和 bgcolor+bgthresh 之间的像素都被设置为透明像素
-bgthresh <background_color_threshold>
-inv如果指定该标志,前景图像的颜色将翻转
-randinv如果指定该标志,颜色将随机地翻转
-maxidev <max_intensity_deviation>前景样本里像素的亮度梯度的最大值
-maxxangle <max_x_rotation_angle>X轴最大旋转角度,必须以弧度为单位
-maxyangle <max_y_rotation_angle>Y轴最大旋转角度,必须以弧度为单位
-maxzangle <max_z_rotation_angle>Z轴最大旋转角度,必须以弧度为单位
-show很有用的调试选项。如果指定该选项,每个样本都将被显示。如果按下 Esc 键,程序将继续创建样本但不再显示
-w <sample_width>输出样本的宽度(以像素为单位
-h <sample_height>输出样本的高度(以像素为单位)

创建样本的流程如下:
输入图像沿着三个轴随机旋转。旋转的角度由 -max?angle 限定。然后像素的亮度值位于 [bg_color-bg_color_threshold; bg_color+bg_color_threshold]范围的像素被设置为透明像素。将白噪声加到前景图像上。如果指定了 -inv ,那么前景图像的颜色将被翻转。如果指定了 -randinv ,程序将随机选择是否将颜色进行翻转。任选背景图像,将获得的前景图像放到背景图像上,并将图像调整到 -w 和 -h 指定的大小。最后将图像存入vec文件,vec文件名由命令行参数 -vec 指定。

正样本也可从一系列事先标记好的图像中创建。标记信息可以存储于一个文本文件,与背景描述文件类似。文件中的每行对应一个图像文件。每行的第一个元素为图像文件名,后面是物体的数目,最后是物体位置和大小的描述 (x, y, width, height)。

下面是描述文件的例子:
假设目录结构如下:

/img
  img_with_faces_1.jpg
  img_with_faces_2.jpg
info.dat

文件info.dat里的内容如下:

img/img_with_faces_1.jpg  1  140 100 45 45
img/img_with_faces_2.jpg  2  100 200 50 50   50 30 25 25

图像img_with_faces_1.jpg中包含一个物体实例(如人脸),标示其在图像中的位置和大小的矩形为(140, 100, 45, 45)。图像img_with_faces_2.jpg包含两个物体实例。
从这样的一系列数据中创建正样本,需要在命令行指定 -info 而非前面所用的 -img 参数:

-info <collection_file_name>		#描述物体所在图像以及大小位置的描述文件。

此部分样本创建过程如下:将物体实例从图像中抠取出,然后将之调整尺寸到目标尺寸,然后保存到输出的vec文件。在此过程中不会对图像进行变形,所以有效的命令行参数仅有 -w, -h, -show 和 -num 。

opencv_createsamples 也可以用来查看和检查保存于vec正样本文件中的正样本。这时只需指定 -vec , -w 和 -h 三个参数则可。 opencv_createsamples 将逐一显示正样本图像。

在训练中,训练程序并不关心包含正样本的vec文件如何生成的,你可以自己写程序来生成vec文件。但是OpenCV提供的工具中,只有 opencv_createsamples 程序能够创建包含正样本的vec文件。

一个vec文件的例子位于 opencv/data/vec_files/trainingfaces_24-24.vec 。它可用来训练人脸分类器,窗口大小为: -w 24 -h 24 。

使用Python代码对正负样本类型进行更改(.png格式转为.jpg格式):

# -*- coding:utf-8 -*-
import os
from PIL import Image

def png2jpg():
    #path = "./Negative samples/"
    path = "./Positive/"
    newPath = "./datasets/pos_raw/"
    for filename in os.listdir(path):
    	img = Image.open(path + filename)
        if os.path.splitext(filename)[1] == '.png':
            newfilename = filename.replace(".png", ".jpg")
            print(filename.replace(".png", ".jpg"))
            img.convert('RGB').save(newPath + newfilename)
        elif os.path.splitext(filename)[1] == '.jpg':
            print(filename)
            img.convert('RGB').save(newPath + filename)

png2jpg()

使用Python代码将正负样本转为灰度图并更名:

# -*- coding:utf-8 -*-
import os
import cv2

def img2Gray():
    #path = "./datasets/neg_raw/"
    #newPath = "./datasets/neg_gray/"
    path = "./datasets/pos_raw/"
    newPath = "./datasets/pos_gray/"
    i = 0
    for filename in os.listdir(path):
        img = cv2.imread(path + filename)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        img = cv2.resize(img, (24, 24))
        i += 1
        # print("processing..." + filename)
        newName = str(i) + ".jpg"
        #print("neg/" + newName)
        print("pos/" + newName + " 1 0 0 24 24")
        cv2.imwrite(newPath + newName, img)

    cv2.waitKey(0) & 0xFF

img2Gray()

转换前:
在这里插入图片描述
转换后:
在这里插入图片描述
将打印出的文件名复制保存到对应的txt文件中(pos.txt和neg.txt),去掉首尾。

使用opencv_createsamples.exe创建.vec文件的cmd命令示例:

opencv_createsamples.exe -vec pos.vec -info pos.txt -num 2000 -w 24 -h 24

训练级联分类器

下一步是训练分类器。如前面所述, opencv_traincascade 和 opencv_haartraining 都可用来训练一个级联分类器,但是此处只介绍 opencv_traincascade 。 opencv_haartraining 的用法与 opencv_traincascade 类似。
下面是 opencv_traincascade 的命令行参数,以用途分组介绍:
1.通用参数

参数含义
-data <cascade_dir_name>目录名,如不存在训练程序会创建它,用于存放训练好的分类器
-vec <vec_file_name>包含正样本的vec文件名(由 opencv_createsamples 程序生成)
-bg <background_file_name>背景描述文件,也就是包含负样本文件名的那个描述文件
-numPos <number_of_positive_samples>每级分类器训练时所用的正样本数目。注意:使用时指令的数量应当略小于实际正样本的数量(总数量的80%-90%即可),不然会报如下错误:OpenCV Error: Bad argument (Can not get new positive sample. The most possible reason is insufficient count of samples in given vec-file.) in CvCascadeImageReader::PosReader::get, file C:\build\master_winpack-build-win64-vc14\opencv\apps\traincascade\imagestorage.cpp, line 158
-numNeg <number_of_negative_samples>每级分类器训练时所用的负样本数目,可以大于 -bg 指定的图片数目
-numStages <number_of_stages>训练的分类器的级数
-precalcValBufSize <precalculated_vals_buffer_size_in_Mb>缓存大小,用于存储预先计算的特征值(feature values),单位为MB,默认1024MB
-precalcIdxBufSize <precalculated_idxs_buffer_size_in_Mb>缓存大小,用于存储预先计算的特征索引(feature indices),单位为MB,默认1024MB。内存越大,训练时间越短
-baseFormatSave这个参数仅在使用Haar特征时有效。如果指定这个参数,那么级联分类器将以老的格式存储

2.级联参数

参数含义
-stageType <BOOST(default)>级别(stage)参数。目前只支持将BOOST分类器作为级别的类型
-featureType<{HAAR(default), LBP}>训练时,提取图像特征的类型,目前只支持LBP、HOG、Haar三种特征。但是HAAR训练非常非常的慢,而LBP则相对快很多,因为HAAR需要浮点运算,精度自然比LBP更高,但是LBP的效果也基本能达到HAAR的效果,推荐使用LBP
-w 训练样本的宽度尺寸(单位为像素),默认24。必须跟训练样本创建(使用 opencv_createsamples 程序创建)时的尺寸保持一致
-h 训练样本的高度尺寸(单位为像素),默认24。必须跟训练样本创建(使用 opencv_createsamples 程序创建)时的尺寸保持一致

3.Boosted分类器参数

参数含义
-bt <{DAB, RAB, LB, GAB(default)}>Boosted分类器的类型: DAB - Discrete AdaBoost, RAB - Real AdaBoost, LB - LogitBoost, GAB - Gentle AdaBoost
-minHitRate <min_hit_rate>分类器的每一级希望得到的最小检测率,默认0.995。总的检测率大约为 min_hit_rate^number_of_stages
-maxFalseAlarmRate <max_false_alarm_rate>分类器的每一级希望得到的最大误检率,默认0.5。总的误检率大约为 max_false_alarm_rate^number_of_stages 。在使用LBP特征参数训练时推荐设置成0.2甚至更小
-weightTrimRate <weight_trim_rate>指定是否应使用微调及其权重。默认0.95。
-maxDepth <max_depth_of_weak_tree>弱分类器树最大的深度。默认是1,是二叉树(stumps)
-maxWeakCount <max_weak_tree_count>每一级中的弱分类器的最大数目,默认100。增强的分类器(stage)将有许多弱树(<=maxWeakCount),这是实现给定-maxFalseAlarmRate所需要的。

4.类Haar特征参数

参数含义
-mode <BASIC (default) 、CORE、ALL>选择训练过程中使用的Haar特征的类型。 BASIC 只使用右上特征, ALL 使用所有右上特征和45度旋转特征。更多细节请参考 [Rainer2002]

5.LBP特征参数
LBP特征无参数

当 opencv_traincascade 程序训练结束以后,训练好的级联分类器将存储于文件cascade.xml中,这个文件位于 -data 指定的目录中。这个目录中的其他文件是训练的中间结果,当训练程序被中断后,再重新运行训练程序将读入之前的训练结果,而不需从头重新训练。训练结束后,你可以删除这些中间文件。

opencv_traincascade.exe使用示例:
在这里插入图片描述

opencv_traincascade.exe -data xml -vec pos.vec -bg neg.txt –numPos 6800 –numNeg 24049 -numStages 15 -w 24 -h 24 -mode ALL

或:(推荐)

opencv_traincascade.exe -data xml6 -vec poss2.vec -bg neg24000.txt -numPos 6800 -numNeg 24049 -numStages 20 -w 24 -h 24 -featureType LBP -precalcValBufSize 4096 -precalcldxBufSize 4096 -maxWeakCount 200 -minHitRate 0.999 -maxFalseAlarmRate 0.2

在这里插入图片描述

注意:

(1).没有输入的参数都会使用默认值。
(2).如果训练时没有指定-featureTpye参数为LBP,即使用默认的HAAR,训练速度将超级慢。
(3).POS count : consumed 中的consumed数量每往下一个阶段(Stages)都会增加,故根据训练阶段数预留适当的正样本(即-numPos的数量比总正样本数少一些,80%-90%之间即可)
(4).-w和-h指定的是正样本大小
NHRFA
训练层数击中率虚警,只有当每一层训练的FA低于你的命令中声明的maxfalsealarm数值才会进入下一层训练

训练结束后,你就可以测试你训练好的级联分类器了!

参考文章:
[1].http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/user_guide/ug_traincascade.html
[2].https://blog.csdn.net/u010402786/article/details/52298833
[3].https://blog.csdn.net/qq_32502511/article/details/79010509

  • 6
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
### 回答1: Python对于OpenCV级联分类器训练非常方便,可以通过几个简单的步骤,轻松地完成自己的XML文件训练。 第一步是准备训练数据集。训练集应该包括正面和负面的例子,正面的例子是要识别的目标,负面的例子则是不包含目标的图像。 第二步是进行数据预处理。这包括将图像转为灰度图像,以及对其进行缩小和正规化。这样有助于提高分类器的准确性和效率。 第三步是使用OpenCV提供的Cascade Trainer GUI工具进行分类器训练。这个工具可以通过交互式界面来设置训练参数,例如正负样本的路径、级联深度、检测窗口大小等等。训练完成后,级联分类器就会在指定的.xml文件中保存。 第四步是使用训练好的分类器进行目标检测。可以使用OpenCV提供的Cascade Classifier类来加载分类器文件,并应用于图像或视频数据。这个类可以方便地进行级联分类器的检测和识别。 总的来说,Python对于OpenCV级联分类器训练和应用非常方便和灵活,可以应用于许多实际场景中,如人脸识别、车辆检测等。需要注意的是,训练过程需要耗费大量的计算资源和时间,因此应该选择适当的硬件设备和训练数据集,以获得更好的效果。 ### 回答2: PythonOpenCV级联分类器训练可以实现自己的XML文件级联分类器是一种基于机器学习的图像识别技术,主要用于目标分类、物体检测等。OpenCV是一个开源的计算机视觉库,提供了丰富的图像和视频处理功能。Python是一种高级编程语言,通常用于数据分析和人工智能领域。 PythonOpenCV级联分类器训练可以通过以下步骤实现: 1. 收集样本数据:首先需要收集足够多的正负样本数据,正样本用于训练模型,负样本用于补充训练,提高模型准确率。 2. 特征提取:使用OpenCV中的Haar特征进行图像特征提取,以此确定图像中是否存在目标物体。Haar特征是基于图像亮度和对比度变化的一种特征表示方法。 3. 训练模型使用PythonOpenCV中的级联分类器进行训练,根据样本数据和特征提取结果,训练模型,并反复迭代优化。 4. 测试模型:完成模型训练后,需要对模型进行测试,验证其在测试数据集中的准确率。 5. 生成XML文件:当训练好了模型后,需要将其保存为XML文件XML文件包含了训练好的模型参数,可以通过OpenCV的CascadeClassifier类进行加载和应用。 总的来说,PythonOpenCV级联分类器训练可以帮助用户创建自己的图像识别模型,并将其保存为XML文件,以便后续应用。该技术具有广泛的应用场景,例如人脸识别、车牌识别、物体检测等。 ### 回答3: PythonOpenCV级联分类器训练,可以通过利用分类器训练工具Cascade Trainer GUI和HaarTraining.exe,在windows或者Linux/Mac OS系统下进行相关操作,实现自己的级联分类器训练生成属于自己的xml文件。 通过一系列的步骤操作,可以在OpenCV中准确地训练一个线性分类器。首先,需要进行正样本的收集,这些正样本应该是需要被检测的目标,比如人脸等等。其次,需要进行负样本的收集,这些负样本应该是和目标无关的固定的图像。然后,需要根据正负样本进行训练,选择合适的参数和特征,应用级联分类器,并进行训练,最终训练出一个能够准确判断图像中是否包含目标的级联分类器。最后,生成与自己训练级联分类器相匹配的XML文件,该XML文件中包含了训练好的特征和参数,可以被导入到其他项目中进行相似的目标检测。 利用级联分类器进行图像检测,可以帮助我们提高检测的准确度和效率。它在训练时,能够自动选择极具区分性的特征来提高处置速度,达到更好的检测效果。 总之,PythonOpenCV级联分类器训练,可以根据需要的检测目标,利用相应的工具和步骤,进行训练生成相应的XML文件。这种方法能够有效地解决图像目标检测的问题,提高识别的准确度和效率,并具有广泛的应用价值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值