1.准备工作目录
准备好如下工作目录
OpenCV版本较高(大概4.以上)时可能没有opencv_createsamples和opencv_traincascade的exe文件需要下载cmake自己生成,过程较复杂。这里建议使用低版本,我用的是3.4.16。
neg目录: 放负样本的目录
pos目录: 放正样本的目录
xml目录: 新建的一个目录,为之后存放分类器文件使用
neg.txt: 负样本路径列表
pos.txt: 正样本路径列表
pos.vec: 后续自动生成的样本描述文件
opencv_createsamples.exe: 生成样本描述文件的可执行程序(opencv自带)
opencv_haartraining.exe: 样本训练的可执行程序(opencv自带)
2.收集正样本和负样本
样本图片最好使用灰度图,且最好根据实际情况做一定的预处理;样本数量越多越好,尽量高于1000,样本间差异性越大越好正负样本比例为1:3最佳;尺寸为20x20最佳。
正样本:训练样本的尺寸为20*20(opencv推荐的最佳尺寸),且所有样本的尺寸必须一致。如果不一致的或者尺寸较大的,可以先将所有样本统一缩放到20*20。
负样本:虽然负样本就是样本中不存在正样本的内容。但也不能随意的找些图片来作为负样本,比如什么天空,大海,森林等等。最好是根据不同的项目选择不同的负样本,比如一个项目是做机场的人脸检测,那么就最好从现场拍摄一些图片数据回来,从中采集负样本。其实正样本的采集也应该这样。不同的项目,就采集不同的正样本和负样本。因为项目不同,往往相机的安装规范不同,场景的拍摄角度就不同。
样本图片的命名一定要注意格式,会影响步骤3。
图片尺寸处理代码:
path = "D:/3D/tennis/"#图片所在文件夹路径
for i in range(1, 141):
print(path+str(i)+'.jpg')
img = cv2.imread(path+str(i)+'.jpg', cv2.IMREAD_GRAYSCALE)
img5050 = cv2.resize(img, (50, 50))
cv2.imshow("img", img5050)
cv2.waitKey(20)
cv2.imwrite('D:/3D/tennis/pos/'+str(i)+'.jpg', img5050)
3.生成样本描述文件
1.按下“开始+r”键打开运行窗口,输入cmd打开命令提示符
2.然后进入pos文件下输入'dir/s/b>pos.txt',pos文件下会生成pos.txt文件,打开后如下:
删除此类,只保留图像的信息,否则执行第四步时会出错。
3.将生成的pos.txt文件修改为如下格式:
文本修改代码:
import cv2
import os
def save_imginfo_to_txt(filepath, txtpath):
files = os.listdir(filepath)
res = []
for file in files:
filename = filepath + "\\" + file
img = cv2.imread(filename)
# 数据的格式
res.append([filename, 1, 0, 0, img.shape[0], img.shape[1]])
save_txt = txtpath + "\\" + "file_name.txt"
file = open(save_txt, 'a')
for i in res:
file.write(' '.join([str(j) for j in i]))
file.write("\n")
file.close()
# 主函数
filepath = "D:/3D/tennis/pos/"#info正
txtpath = "D:/3D/tennis/pos/"
save_imginfo_to_txt(filepath, txtpath)
4.将修改后的pos.txt文件与 opencv_createsamples.exe放在同一目录下,生成pos.vec样本描述文件,执行代码:
opencv_createsamples.exe -vec pos.vec -info pos.txt -num 18500 -w 50 -h 50 #生成正样本使用
opencv_createsamples.exe -vec neg.vec -info neg.txt -num 10500 -w 50 -h 50 #生成负样本使用
这样才是生成成功。注意即使有报错目录下也会生成.vec文件,应该是不能用的。
-num,-w,-h自己修改,与样本保持一致 。“重复”上述操作(怎么重复大家懂的哈)生成neg.vec负样本描述文件。
4.训练样本
完成样本描述文件的生成后,修改最初的pos/neg.txt文件为最初的格式,如下:
然后进行样本训练,执行代码:
opencv_traincascade.exe -data xml -vec pos.vec -bg neg.txt -numPos 500 -numNeg 656 -numStages 20 -w 20 -h 20 -mode ALL
等。。。时间会较长,要好多个小时。
-numPos :正样本的数目,这个数值一定要比准备正样本时的数目少,不然会报can not get new positive sample.
-numNeg :负样本数目,数值可以比负样本大
-numStages :训练分类器的级数
-w 50:必须与opencv_createsample中使用的-w值一致
-h 50:必须与opencv_createsample中使用的-h值一致
第一次写,参考了以下两个优秀博主的内容,希望对大家有帮助,不足之处望指正。
(11条消息) Opencv训练自己分类器_我惠依旧的博客-CSDN博客_opencv训练自己的分类器https://blog.csdn.net/qq_21454973/article/details/115193780(11条消息) Opencv分类器的训练(内含文件批量改名工具及负样本图包下载地址)_Uncle__Ww的博客-CSDN博客_opencv 负样本
https://blog.csdn.net/uncle__ww/article/details/121536923