Lous Blog

opencv 级联分类器训练

这篇文章将会告诉你如何利用OpenCV中自带的程序opencv_createsamples.exe和opencv_traincascade.exe创建样本并训练训练级联Adaboost分类器。(前提需要把OpenCV安装目录下这两个文件的路径加入到系统的环境变量中)

准备工作如下:

  1. 一些魔方的样本,并且样本中只包含魔方,记为正样本

  2. 一些背景的样本,并且背景中不包含有魔方,记为负样本

  3. 把魔方和背景图片从彩色,转换为灰度图像

  4. 并把魔方规范到24x24像素

  5. 背景大小没有特定要求,但是一定要大于24x24

先上结果图

image

image

把所有的正样本放于文件夹pos,所有的负样本放于文件夹neg中。

pos文件夹下,cmd执行dir /b>pos.txt

打开生成的pos.txt去掉第一行或者最后一行的pos.txt。把所有的 jpg 替换成 jpg 1 0 0 24 24。

neg文件夹下,cmd执行dir /b>neg.txt

打开生成的neg.txt去掉第一行或者最后一行的neg.txt。

在每行的开始加入neg/

准备训练样本

Cmd下执行opencv_createsamples.exe -info pos\pos.txt -vec pos.vec -bg neg\neg.txt -num 2681 -w 24 -h 24

Info file name: pos\pos.txt

得到如下的结果,表明成功

Img file name: (NULL) Vec file name: pos.vec BG file name: neg\neg.txt Num: 2681 BG color: 0 BG threshold: 80 Invert: FALSE Max intensity deviation: 40 Max x angle: 1.1 Max y angle: 1.1 Max z angle: 0.5 Show samples: FALSE Width: 24 Height: 24 Max Scale: -1 Create training samples from images collection… Done. Created 2681 samples

直接输入opencv_createsamples.exe显示帮助信息

接下来开始训练样本

Cmd下执行opencv_traincascade.exe -data xml -vec pos.vec -bg neg\neg.txt -numpos 2681 -numneg 1102 -numstages 20 -featureType LBP -w 24 -h 24

得到

PARAMETERS: cascadeDirName: xml vecFileName: pos.vec bgFileName: neg\neg.txt numPos: 2000 numNeg: 1000 numStages: 20 precalcValBufSize[Mb] : 1024 precalcIdxBufSize[Mb] : 1024 acceptanceRatioBreakValue : -1 stageType: BOOST featureType: LBP sampleWidth: 24 sampleHeight: 24 boostType: GAB minHitRate: 0.995 maxFalseAlarmRate: 0.5 weightTrimRate: 0.95 maxDepth: 1 maxWeakCount: 100 Number of unique features given windowSize [24,24] : 8464

静静的等待训练就可以了。在我的笔记本上训练时间大概为25mins。

其中会有一些问题,请参考stackoverflowOpenCV中Adaboost训练的经验总结

打开生成目录xml,其中的cascade.xml就是后面程序中需要的特征分类器。

为了方便区分,重名名为cube_cascade.xml

对自带的人脸识别作简单的修改

import cv2
import os
import os.path

cube=cv2.CascadeClassifier("cube_cascade.xml")
n=0
if n==0:
	cam = cv2.VideoCapture(0)
	while True:
		_, img = cam.read()
		gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
		cubes = cube.detectMultiScale(gray_img, 1.3, 5)
		for cube_x,cube_y,cube_w,cube_h in cubes:
			cv2.rectangle(img, (cube_x, cube_y), (cube_x+cube_w, cube_y+cube_h), (0,255,0), 2)
		cv2.imshow('img', cv2.flip(img,1))			
		key = cv2.waitKey(30) & 0xff
		if key == 27:
			break
	cam.release()
	cv2.destroyAllWindows()
else:
	imgDir='test_img'
	alpha=10
	for parent,dirname,filenames in os.walk(imgDir):
		for filename in filenames:
			print(imgDir+'/'+filename)
			img=cv2.imread(imgDir+'/'+filename)
			res = cv2.resize(img, (0,0), fx=1.0/alpha, fy=1.0/alpha)
			gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
			cubes = cube_haar.detectMultiScale(gray_img, 1.3, 5)
			for cube_x,cube_y,cube_w,cube_h in cubes:
				cv2.rectangle(img, (cube_x, cube_y), (cube_x+cube_w, cube_y+cube_h), (0,255,0), 2)
			cv2.imshow(filename,res)
	while True:
		key = cv2.waitKey(30) & 0xff
		if key == 27:
			cv2.destroyAllWindows()
			break	
	

再加两张图

当然实验结果还是有点问题的,分类器并不是很好。实时的准确率大概只有80~90%。

因为魔方样本不是很多,500多个重复了4次。。。。

如果你对图像识别也感兴趣,可以联系siyaofa@outlook.com标明主题rubikcube+python+opencv+vpython

转载请著名Siyaofa

Siyaofa all copyrights reserves