基于opencv的haar训练自己的识别器
环境准备
所需的环境非常简单,如下:
-
操作系统: Windows
-
opencv 【opencv版本随意,但最好是较低版本的,像opencv3.4.1这样,因为后面所需的一些文件高版本的opencv是不自带的,当然想必看这篇文章的都已经下好opencv了,那么对于已经下了高版本opencv的同志也不要着急,本文会告诉你解决方法】
-
opencv_createsamples.exe 和 opencv_traincascade.exe
重点来说一下这两个文件,有的博客上不是用 opencv_traincascade.exe,而是用opencv_haartraining.exe,我觉得这两个没什 么区别,都可以达到效果。在很多博客中都说这两个exe文件时opencv自带的,这是没错的,但是低版本的opencv中有这两个文件,高版本的opencv中没有,这也是我前面说推荐低版本opencv的原因。寻找这两个文件真是要了我们命,而且他们还需要 各种依赖,而网上的很多这个包还需要某某积分下载,着实让人头疼。好吧,不说这些糟心事,下面给出这些文件的下载链接:https://gitee.com/wsj-create/csdn/tree/master/bin。
当然,大家也可以看看自己的opencv中有没有这两个文件,文件路径如下:
数据准备
首先我们需要创建一些文件夹来管理我们的数据,文件结构如下:
来简单介绍一下这三个文件夹:
- neg: 存放负样本图片【如我们需要进行人脸检测,即这个文件夹就存放除人脸的各种图片】
- pos: 存放正样本图片【如我们需要进行人脸检测,即这个文件夹就存放各种人脸的图片】
- xml: 存放最后程序运行结构文件
建立好这些文件夹后我们就需要在neg和pos文件夹中存放我们想训练的图片了。【这里需要注意一下,我们在pos中的图片,即正样本的图片,应尽量保持图片大小一致,如都设置为(20,20)的大小。批量处理文件夹中图片大小的程序到处可见,这里给出一个链接:批量处理图片尺寸;而在neg中的图片,可不做处理】
数据预处理✨✨✨
建立正样本的描述文件
首先我们通过windows的cdm进入到pos文件夹中,如下:
然后我们在cmd中输入代码:dir /b > pos.txt
,这时候在pos文件夹会产生一个pos.txt的文件,这个文件记录了该文件夹中所有图片的名称。
打开pos.txt文件,去除pos.txt最后一行的pos文件夹,将所有png
替换成 png 1 0 0 20 20
。这里1表示当前图片重复出现的次数是1, 0 0 20 20表示目标图片大小是矩形框从(0,0)到(20,20)。最终pos.txt文件中的内容应具有如下的格式。
建立负样本的描述文件
同样的方法,现在我们先进入neg文件夹,然后在cmd中输入dir /b/s/p/w *.png > neg.txt
,这时候会在neg文件夹中生成一个neg.txt文件,这时产生的文件不做任何修改。最终neg.txt文件中的内容应具有如下的格式。【注意:这里的路径确保是绝对路径,否则后面训练时可能会出错】
生成正样本的.vec文件
需要注意的是,生成.vec需要opencv_createsamples.exe,这个文件我在环境准备时已经给出,其放置位置如下:【黄框框住的才是我们真正需要的,其他有的是这俩所依赖的,有的可能不是,所幸我把opencv里面的文件都放进来了,这样多了文件也不会错】
首先我们进入到circle_detect目录,即pos、neg文件夹所在目录,在此目录输入以下指令:
opencv_createsamples.exe -vec pos.vec -info pos\pos.txt -bg neg\neg.txt -w 20 -h 20 -num 1500 ;
对指令参数进行简要介绍:
-vec pos.vec:指定生成的文件,最终生成的就是pos.vec;
-info pos\pos.txt:目标图片描述文件,在pos\pos.txt;
-bg neg\neg.txt:背景图片描述文件,在neg\neg.txt;
-w 20:输出样本的宽度,20;
-h 20:输出样本的高度,20;
-num 1500:要产生的正样本数量,1500;
最终,我们会在circle_detect文件夹下产生一个pos.vec文件
训练模型✨✨✨
同样的,我们进入到circle_detect目录,并输入以下命令:
opencv_traincascade.exe -vec pos.vec -bg neg\neg.txt -data xml -w 20 -h 20 -mem 1024 -numPos 1000 -numNeg 3000 -nstages 2 -nsplits 5
对指令参数进行简要介绍:
-vec pos.vec:正样本文件名;
-bg neg\neg.txt:背景描述文件;
-data xml:指定存放训练好的分类器的路径名,也就是前面建立的xml文件夹;
-w 20:样本图片宽度,20;
-h 20:样本图片高度,20;
-mem 1024:提供的以MB为单位的内存,很明显,这个值越大,提供的内存越多,运算也越快;
-numPos1000:取1000个正样本,这个数值一定要比准备正样本时的数目少,不然会报 can not get new positive sample。
-numNeg3000:取3000个负样本
-nstages 2:指定训练层数,层数越高耗时越长;
-nsplits 5:分裂子节点数目, 默认值 为2;
训练成功之后在xml目录下会生成cascade.xml文件,这个文件就是最终训练成功的文件,这时候我们就可以用代码来测试自己的模型。
模型测试
直接上代码:
# 导入opencv-python
import cv2
#上一步得到的cascade.xml路径,注意这里我换了个路径
path = 'D://cascade.xml'
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + path)
face_cascade.load(path)
#读取一张图像
img = cv2.imread('warped.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 用人脸级联分类器引擎进行人脸识别,返回的faces为人脸坐标列表,1.3是放大比例,5是重复识别次数
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.3,minNeighbors=5)
for (x,y,w,h) in faces:
# 画出人脸框,蓝色(BGR色彩体系),画笔宽度为2
img = cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
# 在"img2"窗口中展示效果图
cv2.imshow('img2',img)
# 监听键盘上任何按键,如有按键即退出并关闭窗口,并将图片保存为output.jpg
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite('output.png',img)
在对模型进行训练时,也有一些需要注意的,具体可以看我的这篇博客:haar测试注意事项
参考链接:https://blog.csdn.net/hongbin_xu/article/details/74203215
如若文章对你有所帮助,那就🛴🛴🛴
咻咻咻咻~~duang~~点个赞呗
- 点赞
- 收藏
- 关注作者
评论(0)