OpenCV训练分类器制作xml文档
OpenCV训练分类器制作xml⽂档
opencv 2.1⽹上查的另⼀种资料
训练分类器成功,在此与⼤家分享。
样本训练要求
1、杯⼦的背景要统⼀吗,因为有些背景是⽩⾊,有些是淡淡的背景⾊,还有些深⾊的背景⾊
答:背景⾊要统⼀
2、整个图的⼤⼩就是最外⾯⼀个框框起来那么⼤,
问题是:我需要在原图基础上截图吗,如:只把红框框起来的那部分截出来
答:不⽤的
3、那图⽚是256⾊的还是彩⾊的呢?
答:灰度最佳
5、⼀般来说,训练分类器⽤的什么图⽚就⽤什么图⽚作测试
即来源图⽚分别⽤于训练和测试
6、那正样本选择⽅⾯有没有要求,如玻璃杯
当然有要求。
全世界手语是一样的吗最好各种形状的玻璃杯都有样本,每种玻璃杯从不同⾓度拍摄的样本都有
7、那⽹上截些有关玻璃杯的图可以吗?⼤⼩是要归⼀化的
可以的。⽹上的图像实际上也来源于⽣活或科研拍摄的
其实可以不是图⽚的归⼀化,还可以是特征的归⼀化
归⼀化的话可以根据缓需求,不同应⽤场合就有不同的归⼀化⽅法
8、那关于杯⼦这个正样本,我要弄⼤约多少张图⽚呀?
样本要多,当然并不是越多越好,⽽是每⼀张都有代表性,能反映⼀定意义
9、负样本最好含有正样本中的背景部分
训练失败的原因很多:
1、负样本数⽬太少,导致Adaboost算法汉有跳出死循环,
2、负样本之间重复部分过多,或正样本尺⼨过⼤,导致训练分类器时内在溢出。
.vec⽂件⾥的东西是⽤⼆进制的形式表⽰的。
⾸先写的是样本的数量,然后是样本⼤⼩width*height,后⾯就是图⽚像素值。
在opencv下的cvsamples.cpp就能看的很清楚了。
本⽂现在正在做⼈头检测。视频中的⼈头尺⼨,光照,⾓度都很不相同。
1. 请问haar训练中正样本是不是只能是在光照尺⼨和⾓度都⼀致的情况下进⾏训练?
正樣本的光照可以是有變化的,正樣本應該保留⼀些樣本以外的背景,但不能過⼤,⾓度的話,⼈臉轉90度都還可以接受。
其實你正樣本的種類(不同⾓度.不同光照.不同⼈臉)越多,就需要更多的矩形特徵來作分類。
2.正负样本需要⼀样的⼤⼩么?
⼈臉建議使⽤20*20,⼤⼩要盡量統⼀,這樣在做Description txt file時,⽐較⽅便。⼈臉在圖⽚中的位置盡量也相同。
3.有⼈说正负样本数量⽐例最好是7:3,也有⼈说正负样本须⼀样多。这是怎么回事?
我怎麼聽說正:負=1:3⽐較好。建議你可以先試試看1000:3000應該不⽤花太多時間訓練。
4.在训练中,本⼈发现了⼀种情况:如果正负样本差别较⼩,即负样本从待检测视频图像中的背景获取,并且与正样本⼀样⼤的话,训练就会在某⼀个节点上停下来,并且⼏天也过不了这个节点;⽽如果负样本与正样本差别很⼤(尺⼨与取样上都差别很⼤)的话,训练结束⽐较快,但是⽤得到的xml⽂件去做检测的话,效果很不好。请问这是不是⽭盾,该怎么解决?正負樣本照理說應該不會差別不⼤,除⾮你是要偵測笑臉/⾮笑臉,另外可能是你負樣本太少,所以false alarm數值太⾼,所以haartraining 沒有正常terminate
5.参数stage⼀般设置多⼤?
我⽬前使⽤如下指令
-data "d:\training0421\20s" -vec "d:\training0421\positive\positives.vec" -bg "d:\training0421\" -npos 1681 -nneg 3406 -nstages 20 -nsplits 2 -minhitrate 0.995 -maxfalsealarm 0.5 -mode ALL -mem 2000 -w 20 -h 20
使⽤profermance來測試原始訓練樣本(200*200p)可以有⼋成的hitrate,false⼤概幾⼗個。
整个过程分为两步:
初五能出门吗1.      创建样本
2.      训练分类器
3、利⽤训练好的分类器进⾏⽬标检测。
现在让我⼀⼀讲述。
1.      创建样本
◆样本分两种:正样本与负样本(也有⼈翻译成:正例样本和反例样本),其中正样本是指待检⽬标样本(例如⼈脸,汽车,⿐⼦等),负样本指其它任意图⽚。
◆所有样本图⽚都应该有同⼀尺⼨,如20 * 20,并放在相应⽂件⽬录下,
◆集合⽂件格式(collection file format)和描述⽂件格式(description file format)
集合⽂件格式(collection file format)就是如下形的描述⽂件:
[filename]
[filename]
[filename]
描述⽂件格式(description file format)就是如下形的描述⽂件:
[filename] [# of objects] [[x y width height] [... 2nd object] ...]
[filename] [# of objects] [[x y width height] [... 2nd object] ...]
[filename] [# of objects] [[x y width height] [... 2nd object] ...]
.
(x, y) 指左上⾓的坐标,width和 height 分别是样本的宽和⾼,这⾥我的图⽚是20*20的,所以两个值都是20
◆负样本⽤集合⽂件格式描述,正样本⽤描述⽂件格式描述!(这点⽹上很多⽂章都搞错了!)
▼创建样本步骤:
⼀.把所有正样本图⽚放在posdata的⽂件夹下,把所有负样本图⽚放在negdata⽂件夹下
(这⾥我以⼈脸图⽚样本为例)
(注:以上这些 20*20 的图⽚均来⾃MIT⼈脸库,可以在csdn下载)
⼆.分别为正样本和负样本创建描述⽂件
A.为正样本创建描述⽂件格式⽂件,并且把这个⽂件放在与样本图⽚同⼀⽬录下,例如我的⽬录为C:/OpenCV2.1/bin/posdata
a)      在命令⾏下输⼊以下命令: dir /b >
b)      打开, 按ctrl+h, 把所有的bmp 换成 bmp 1 0 0 20 20
c)      删除最后⼀⾏的 “”
d)      结果如下:(1代表⼀个⽂件,0 0 20 20表⽰这个⽂件的2个顶点位置坐标)
B.为负样本创建集合⽂件格式⽂件bg.txt, 并且把这个⽂件放在与样本图⽚同⼀⽬录下,例如我的⽬录为I:/negdata
a)      在命令⾏下输⼊以下命令: dir /b > bg.txt
b)      删除bg.txt最后⼀⾏的 “bg.txt”
c)      结果如下:
三.创建样本。
Opencv ⾃带有创建样本的exe ⽂件,在 …/OpenCV2.1/bin ⽬录下,这⾥我创建120个sample:
命令是: -info e:\test\ -vec e:\test\posdata0\pos.vec -num 120 -w 20 -h 20
如图:
结果如图:
需要说明的是,我这⾥⽤的参数并没有 –bg,因为根据那份⽂档,有了 –vec 和 –info 之后,就表⽰:Create training samples from some (从很多正样本中创建sample, 没有distortions)
经历千⾟万苦,我们终于看到sample被创建成功了,接下来的⼯作就简单多了
▼训练分类器
还是在…/OpenCV2.1/bin⽬录下,输⼊命令:
-data e:\test\data0\cascade0 -vec e:\test\posdata0\pos.vec -bg e:\test\ -npos 120 -nneg 120 -nsplits 2 -mem 512 -nonsym -w 20 -h 20 -minpos 100 -nstages 4
回车
(注意:
留学法国
1.      参数-vec ⼀定要是刚刚创建样本产⽣的a.vec,且把完整路径也写上去,我试过⽤相对路径,但总会训练失败; bg.txt 也要⽤绝对路径;
.vec⽂件⾥的东西是⽤⼆进制的形式表⽰的。
⾸先写的是样本的数量,然后是样本⼤⼩width*height,后⾯就是图⽚像素值。
在opencv下的cvsamples.cpp就能看的很清楚了。
2.      –w 和 –h 都要写上与样本⼤⼩的⼀致的尺⼨
3.      若遇到“内存什么不能read”的问题,很有可能是bg.txt的格式有误,回去
结果如下:
(可能实际结果与上图有出⼊,但看到最后的,就说明训练成功了。
在E:\test\data0⽬录会⽣成⼀份l⽂档,这个就是我们想要的结果了!
============================================================================
OpenCV训练分类器制作xml⽂档之⼀
我的问题:有了opencv⾃带的那些xml⼈脸检测⽂档,我们就可以⽤cvLoad()这个函数加载他们,让他们对我们的⼈脸进⾏检测,但是,现在⽣活中的计算机视觉并不远远是检测⼈脸,还有很多物品需要识别,所以,能不能⾃⼰做个xml的检测⽂档,⽤它来检测⾃⼰需要的东西呢?例如,检测⼀个可乐瓶!
问题解决:
⾸先了解下,⽬标检测分为三个步骤:
1、样本的创建
2、训练分类器
3、利⽤训练好的分类器进⾏⽬标检测。
⼀,样本的创建:
(1)收集训练样本:
训练样本包括正样本和负样本。正样本,通俗点说,就是图⽚中只有你需要的⽬标。⽽负样本的图⽚只要其中不含有⽬标就可以了。但需要说明的是,负样本也并⾮随便选取的。例如,你需要检测的⽬标是汽车,那么正样本就应该是仅仅含有汽车的图⽚,⽽负样本显然不能是⼀些包含天空的,海洋的,风景的图⽚。因为你最终训练分类器的⽬的是检测汽车,⽽汽车应该出现在马路上。也就是说,分类器最终检测的图⽚应该是那些包含马路,交通标志,建筑物,⼴告牌,汽车,摩托车,三轮车,⾏⼈,⾃⾏车等在内的图⽚。很明显,这⾥的负样本应该是包含摩托车、三轮车、⾃⾏车、⾏⼈、路⾯、灌⽊丛、花草、交通标志、⼴告牌等。
另外,需要提醒的是,adaboost⽅法也是机器学习中的⼀个经典算法,⽽机器学习算法的前提条件是,测试样本和训练样本独⽴同分布。所谓的独⽴同分布,可以简单理解为:训练样本要和最终的应⽤场合⾮常接近或者⼀致。否则,基于机器学习的算法并不能保证算法的有效性。此外,⾜够的训练样本(⾄少得⼏千张正样本、⼏千张负样本)也是保证训练算法有效性的⼀个前提条件。
训练样本分为正例样本和反例样本,其中正例样本是指待检⽬标样本(例如可乐瓶,⼈脸等),反例样本指其它任意图⽚,所有的样本图⽚都被归⼀化为同样的尺⼨⼤⼩(例如,20x20)。
1 、负样本(反例样本)可以来⾃于任意的图⽚,但这些图⽚不能包含⽬标特征。
负样本由背景描述⽂件来描述。背景描述⽂件是⼀个⽂本⽂件,每⼀⾏包含了⼀个负样本图⽚的⽂件
名(基于描述⽂件的相对路径)。该⽂件必须⼿⼯创建。2,正样本
现在,我们来看正样本的创建步骤:
正样本由程序createsample程序来创建。该程序的源代码由OpenCV给出,并且在bin⽬录下包含了这个可执⾏的程序。
正样本可以由单个的⽬标图⽚或者⼀系列的事先标记好的图⽚来创建。
createsamples程序的命令⾏参数:
命令⾏参数:
-vec <vec_file_name>
训练好的正样本的输出⽂件名。
-img<image_file_name>
源⽬标图⽚(例如:⼀个公司图标)
-bg<background_file_name>
背景描述⽂件。
-num<number_of_samples>
要产⽣的正样本的数量,和正样本图⽚数⽬相同。-maxidev<max_intensity_deviation>
背景⾊最⼤的偏离度。页眉横线怎么去掉
-maxangel<max_x_rotation_angle>
-maxangle<max_y_rotation_angle>,
-maxzangle<max_x_rotation_angle>
最⼤旋转⾓度,以弧度为单位。
-show
如果指定,每个样本会被显⽰出来,按下"esc"会关闭这⼀开关,即不显⽰样本图⽚,⽽创建过程继续。这是个有⽤的debug选项。
-w<sample_width>
输出样本的宽度(以像素为单位)
-h<sample_height>
输出样本的⾼度,以像素为单位。
注:正样本也可以从⼀个预先标记好的图像集合中获取。这个集合由⼀个⽂本⽂件来描述,类似于背景描述⽂件。每⼀个⽂本⾏对应⼀个图⽚。每⾏的第⼀个元素是图⽚⽂件名,第⼆个元素是对象实体的个数。后⾯紧跟着的是与之匹配的矩形框(x , y ,宽度,⾼度)。
下⾯是⼀个创建样本的例⼦:
假定我们要进⾏⼈脸的检测,有18个正样本图⽚⽂件face00001.bmp,…face00100.bmp;有45个背景图⽚⽂件:B1_00001.bmp, …
B1_00200.bmp,⽂件⽬录结构如下:
e:\test\negdata\
face0001.bmp
明明就歌词…
face0018.bmp
<
e:\test\posdata
B1_001.bmp
……
B1_0045.bmp
negdata.dat
正样本描述⽂件的内容如下:
face00001.bmp 1 0 0 20 20
……
face00100.bmp 1 0 0 20 20
背景(负样本)描述⽂件的内容如下:
B1_00001.bmp      ……
B1_00200.bmp
图⽚imag1.bmp包含了单个⽬标对象实体,矩形为(0,0,20,20)。
注意:要从图⽚集中创建正样本,要⽤-info参数⽽不是⽤-img参数。
-info <collect_file_name>
标记特征的图⽚集合的描述⽂件。在cmd窗⼝下来进⾏样本的创建:
C:\Program Files\OpenCV\bin>createsamples -info e:\test\ -vec e:\test\posdata\pos.vec -num 18 -w 20 -h 20【解释下】。。。。
⼩贴⼠1:
可以采⽤Dos命令⽣成样本描述⽂件(⼀般样本图⽚上万幅),在Dos下进⼊图⽚⽬录,输⼊dir /b *.bmp > , 则会在此⽬录中产⽣⼀个,⽂件中包含所有当前⽬录下的⽂件名,就可以建成负样本描述⽂件。对于正样本描述⽂件,⽅法同负样本,只要把bmp替换
成1 0 0 20 20即可。如果样本图⽚太多,在txt中替换会导致程序⽆法响应,可以先把内容拷贝到word中替换后再拷贝回来。
⼩贴⼠2:
三、训练分类器
样本创建之后,接下来要训练分类器,这个过程是由haartraining程序来实现的。该程序源码由OpenCV⾃带,且可执⾏程序在OpenCV安装⽬录的bin⽬录下。
Haartraining的命令⾏参数如下:
无什么无什么的词语-data<dir_name>
存放训练好的分类器的路径名。
-vec<vec_file_name>
正样本⽂件名(由trainingssamples程序或者由其他的⽅法创建的)
-bg<background_file_name>
背景描述⽂件。
-npos<number_of_positive_samples>,
-nneg<number_of_negative_samples>
⽤来训练每⼀个分类器阶段的正/负样本。合理的值是:nPos = 7000;nNeg = 3000
-nstages<number_of_stages>
训练的阶段数。
-nsplits<number_of_splits>
决定⽤于阶段分类器的弱分类器。如果1,则⼀个简单的stump classifier被使⽤。如果是2或者更多,则带有number_of_splits个内部节点的CART分类器被使⽤。
-mem<memory_in_MB>
预先计算的以MB为单位的可⽤内存。内存越⼤则训练的速度越快。
-sym(default)
-nonsym
指定训练的⽬标对象是否垂直对称。垂直对称提⾼⽬标的训练速度。例如,正⾯部是垂直对称的。
-minhitrate<min_hit_rate>
每个阶段分类器需要的最⼩的命中率。总的命中率为min_hit_rate的number_of_stages次⽅。
-maxfalsealarm<max_false_alarm_rate>
没有阶段分类器的最⼤错误报警率。总的错误警告率为max_false_alarm_rate的number_of_stages次⽅。
-weighttrimming<weight_trimming>
指定是否使⽤权修正和使⽤多⼤的权修正。⼀个基本的选择是0.9
-eqw
-mode<basic(default)|core|all>
选择⽤来训练的haar特征集的种类。basic仅仅使⽤垂直特征。all使⽤垂直和45度⾓旋转特征。
-w<sample_width>
-h<sample_height>
训练样本的尺⼨,(以像素为单位)。必须和训练样本创建的尺⼨相同。
⼀个训练分类器的例⼦:
C:\Program Files\OpenCV\bin>haartraining -data e:\test\data\cascade -vec e:\test\posdata\pos.vec -bg e:\test\ -
npos 18 -nneg 45 -nsplits 1 -mem 512 -mode ALL -w 20 -h 20 -minhitrage 0.998 -maxfalsealarm 0.5 -nstages
训练开始,如下图,可能会⼀⼩段时间才训练完成。
(可能实际结果与上图有出⼊,但看到最后的,就说明训练成功了。
在bin⽬录会⽣成⼀份可爱的l⽂档,这个就是我们想要的结果了!
训练结束后,会在⽬录data下⽣成⼀些⼦⽬录,即为训练好的分类器。
训练结束后,还要使⽤⽣成xml⽂件,可以通过下列⽹页下载。
重要!可能遇到的问题:
1.如果跑到某⼀个分类器时,⼏个⼩时也没有反应,⽽且显⽰不出训练百分⽐,这是因为你的负样本数量太少,或者负样本的尺⼨太⼩,所有的负样本在这个分类器都被reject了,程序进⼊不了下⼀个循环,果断放弃吧。解决⽅法:负样本尽量要⼤⼀些,⽐如我的正样本是
40*15,共300个,负样本是640*480,共500个。(我当时的错误就出现在这,把负本改⼤后,就成功了)
2.读取样本时报错:Negative or too large argument of CvAlloc function,⽹上说这个错误是因为opencv规定单幅iplimage的内存分配不能超过10000,可是我的每个负样本都不会超过这个⼤⼩,具体原因不明。后来我把负样本的数量减少,尺⼨加⼤,这个问题就解决了。
3.训练的过程可能经常出错,耐⼼下来不要着急,我在训练MRI分类器的时候失败了⽆数次。失败的时候有两件事可以做,第⼀,调整正负样本的数量,再试。第⼆,调整负样本的⼤⼩,祝⼤家好运。
=============================================================================================

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。