haartraining实践总结

来源:互联网 发布:实验室洗眼器 淘宝 编辑:程序博客网 时间:2024/06/05 05:42
haartraining实践总结:
1. 构造positive样本和negtive样本set,
        - 一般来说先将图片转成灰度图片
        - resize图片到适合大小,以适于切割下来的pos的样本size最好为20×20的size,且要为正方形图片,且为bmp格式的图片。这样有利于算出最终结果的精确度。
       - bmp的图片不能直接将jpg的图片改一下后缀得到,实际上是没有改变的,需要程序PIL重新保存为bmp格式 
       - neg的样本也是正方形,但要比pos的样本图片要大,选取时最好能覆盖不包含正样本外的其他区域,可以写程序实现随机切割样本。
       - neg的样本数量要尽量多,一般要大于pos样本数量的3倍,越多越好
       -  建立文件夹pos存放pos样本,文件夹neg存放neg样本


2. create 正样本vec文件
        - 在dos中 cd pos;   dir /b > posdata.txt;
       - 打开posdata,删除最后一行“posdata.txt",把里面的数据格式改成下面的形式, 我觉得其中的20 20应该是宽度和高度,0 0是起始的x,y坐标:
pos/8_0.bmp 1 0 0 20 20
pos/8_1.bmp 1 0 0 20 20
pos/8_10.bmp 1 0 0 20 20
pos/8_11.bmp 1 0 0 20 20
pos/8_12.bmp 1 0 0 20 20
       
       - cd neg ; dir /b > negdata.txt; 
       - 打开negdata, 删除最后一行,把目录加在文件名前面,后面不用加位置等信息 
neg/0.bmp
neg/1.bmp
neg/10.bmp
neg/100.bmp
neg/101.bmp
neg/102.bmp
neg/103.bmp
neg/104.bmp
neg/105.bmp 


        - 将保存好的negdata和posdata 剪切 到上层目录
       -  运行opencv命令生成正样本, -num是正样本的数量
D:\python\software\opencv\build\x64\vc11\bin\opencv_createsampl
es.exe -vec D:\JD\card\image\pos.vec -info pos_image.txt -bg neg_image.txt -w 20 
-h 20 -num 38
       - 执行成功后会生成D:\JD\card\image\pos.vec文件


3. haartrain
       - 执行命令:
D:\JD\card\image>D:\python\software\opencv\build\x64\vc11\bin\Opencv_haartraining.exe -data result -vec pos.vec -bg neg_image.txt -nsplits 1 -sym -w 20 -h 20 -mode all -mem 1280 -npos 38 -nneg 127 -nstages 6 
       - 其中 -w 和 -h的值要和创建样本命令的w和h一致,-npos和-nneg的值要填写,否则命令会认为是默认值2000,从而出错。
       - -nstages是 要求算法计算的层数,如不写则默认为14层才停止,但如果本身提供的正样品和负样品的数量不多,尤其是负样品数量,那么算法在没有到达第14层时就已经完全将现有的负样品完全分类正确,就会进入死循环状态,从而生成不了最终的xml文件。解决的办法要么是增加neg样本的数量和多样性,要么指定-nstages,使其在指定层数stage停下来并生成xml文件,因为这个时候算法分类的精度已经很高了。
       - 在 result目录下可以看到算法已经到达的层数。如果想要重新执行需要将下面的目录都删掉,否则会在现有基础上继续执行。
       - 在 D:\JD\card\image下会生成一个result.xml的文件


4. 使用xml文件进行分类
在进行分类识别detectMultiScale之前先将图片转化成切割样本时图片的大小,这样才能进行比较,minSize和maxsize可以设置成包含正样本size的区间
import cv2
import numpy as np
from pylab import *

eight_cascade = cv2.CascadeClassifier(r"D:\JD\card\image\result.xml")
image = r"D:\JD\card\image\card\3.jpg"
print "get eight_cascade"
img = cv2.imread(image)

img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
imgGray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
imgGrayResized = cv2.resize(imgGray, (320,205))
print "get imread image"

eight = eight_cascade.detectMultiScale(imgGrayResized, scaleFactor = 1.3, minNeighbors = 4, minSize = (10,10), maxSize = (40,40), flags = cv2.cv.CV_HAAR_SCALE_IMAGE)
print "after detected"
print eight

for (x, y, w, h) in eight:

    cv2.rectangle(imgGrayResized, (x, y), (x + w, y + h), (255, 0, 0), 2)

plt.subplot(1,1,1), plt.imshow(imgGrayResized), plt.title('Face Image'), plt.xticks([]), plt.yticks([])

plt.show()


结果:
定位不是很理想,因为neg样本较少,且当时切割neg样本时都是围绕着数字周围切割的,卡的周围没有切割neg样本,所以算法匹配到的位置很多都在卡的周边,应该加大neg样本和正样本的数量,在2000以上,也许准确率会好些。





0 0
原创粉丝点击