这两个软件在opencv安装包里是没有的,只有下载opencv以及opencv_contrib源码自己编译才会生成这两个可执行程序,编译opencv和opencv_contrib有很多教程,我就不多说了,这里我也把我编译好的文件放在码云上了,下载下来就可以直接运行,编译的版本是opencv-3.4.1
https://gitee.com/lizaozao/opencv341_bin数据分为正样本和负样本
正样本就是你要识别的部分,负样本就是不包含你要识别的部分,正负样本放在不同的两个文件夹posdata(正样本)和negdata(负样本)文件夹里
例如对于下面的图片:
我们切下正样本放置于正样本文件夹中:
那么除了正样本外的所有背景均可剪切下来当做负样本放置于负样本文件夹中。
这里要注意:正负样本都需要处理成灰度图,所有正样本需要resize到同样的大小,例如20×20,或者24×24,负样本则不需要resize,可以大小不同。
做好的正样本:
做好的负样本:
为正样本创建描述文件格式文件posdata.txt,即在posdata文件夹里新建posdata.txt文件,然后在cmd里cd到posdata文件夹下,执行
dir /b > posdata.txt对于负样本也同样在negdata文件夹里新建negdata.txt文件,然后在cmd里cd到negdata文件夹下,执行
dir /b > negdata.txt生成后还需要一定的修改
对于posdata.txt:
打开posdata.txt, 使用替换功能,把所有的bmp 换成 bmp 1 0 0 20 20(这里bmp是因为我的图片格式为bmp,20 20 是因为我把所有正样本resize成20×20的了,如果你不一样,就需要修改相应的位置)
然后在posdata.txt文件里搜索 ‘posdata.txt’ ,将这一行删除。 修改完以后是这样的:
对于negdata.txt:
首先在negdata.txt文件里搜索 ‘negdata.txt’ ,将这一行删除。然后使用替换功能把相对路径换成绝对路径,例如:
变成:
到这里数据就准备好了,可以开始训练了
1.使用opencv_createsamples.exe创建样本:
在cmd里cd到程序所在的文件夹下,执行指令
opencv_createsamples.exe -info posdata\posdata.txt -vec detect_number.vec -bg negdata\negdata.txt -num 1661 -w 20 -h 20参数解释: -info:就是你之前搞的posdata.txt的位置,可以直接使用绝对地址避免出错,绝对地址就是从C:或者D:开始的地址 -vec 是你生成vec文件的位置和名称 -bg 就是你之前搞的negdata.txt的位置,同样也可以直接使用绝对地址 -num 你正样本的数量,你有多少正样本就写多少 -w -h 是你正样本的宽高
执行以后结果为:
2.使用opencv_traincascade.exe开始训练:
opencv_traincascade.exe -data xml_file -vec detect_number.vec -bg negdata\negdata.txt -numPos 1500 -numNeg 1169 -numStages 20 -featureType HAAR -w 20 -h 20参数解释: -data 就是你存放训练好的xml文件的文件夹,这个一定要事先创建好 -vec 是你之前生成vec文件 -bg 就是你之前搞的negdata.txt的位置 -numPos 你正样本的数量,这里我填的比正样本数量稍微少一点,我有1661个正样本,但是填的的1500,这是为避免训练出错 -numNeg 你负样本的数量,有多少填多少 -numStages 训练步数 -featureType ,就是特征类型,有三种,不过另外两种忘记了,而且也是HAAR最常用 -w -h 是你正样本的宽高
开始训练后如图:
训练完成后在xml_file文件夹里会生成一系列xml文件,最后能用的文件是cascade.xml
最后使用测试程序试试我们训练好的分类器的效果:
import cv2 detector = cv2.CascadeClassifier('cascade.xml')# 分类器位置 cap = cv2.VideoCapture(0) cap.set(3,1920) #设置分辨率 cap.set(4,1080) while True: ret, img = cap.read() gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = detector.detectMultiScale(gray, 1.1, 5) for (x, y, w, h) in faces: cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2) cv2.imshow('frame', img) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()效果如图:
这就OK啦,如果有什么不明白的地方,可以跟我交流 QQ:172561916