当前位置: 代码迷 >> 综合 >> opencv-019-Haar,LBP级联分类器的训练
  详细解决方案

opencv-019-Haar,LBP级联分类器的训练

热度:58   发布时间:2023-12-18 19:17:31.0

级联分类器就是通过一步步过滤图片的特征,经过第一个分类器如果不满足图片的此级联特征就判断该图片不为目标值,如果满足该特征,则继续往下通过另一个或多个分类器进行判断,这就是级联分类器的基本原理
? HAAR特征数据
? LBP特征数据
? 数据格式XML

HAAR与LBP的区别

  1. HAAR特征是浮点数计算
  2. LBP特征是整数计算
  3. LBP训练需要的样本数量要比HAAR大
  4. 同样的样本空间,HAAR训练出来的数据检测结果 要比LBP准确
  5. 扩大LBP的样本数据,训练结果可以跟HAAR一样
  6. LBP的速度一般可以比HAAR快几倍
  7. HAAR比LBP要准确

一,基本流程

  1. 收集样本数据 – 包括正负样本
  2. 样本集合与描述
  3. 生成vec文件与负样本列表文本文件
  4. 使用OpenCV自动的级联分类器训练工具,训练样 本数据
  5. 得到最终的级联分类器数据(XML格式)

一,收集样本数据

对图片进行训练首先需要准备数据:
1.正样本 包含待检测目标的图片 要统一尺寸,即长宽比例要相同(1:1)(1:2)
2.负样本 不包含待检测目标的图片

二,样本集合与描述

1,正样本与描述文件
在这里插入图片描述
需要在正向样本中添加info.dat描述文件,其中包含:
图片的相对地址 图片中目标图像的个数 图片中目标图像的x坐标 y坐标 图片的长 图片的宽
img\01\s1.png 1 0 0 176 176
在这里插入图片描述
2,负样本与描述文件
在这里插入图片描述
负样本的描述文件中只包括每个图片的地址
在这里插入图片描述
我的总体目录结构为:
在这里插入图片描述
这里我自己写了个python脚本来生成这两个描述文件,可以参考下:

#coding:utf-8
from PIL import Image
import os
path = os.getcwd()
#path = "F:\\opencv\\InputImg\\face"
path_p = os.path.join(path, "positive")
path_n =os.path.join(path, "negative")
pos_list = list()
neg_list = list()
def get_pos(filepath):
#遍历filepath下所有文件,包括子目录files = os.listdir(filepath)with open("info.data", "w") as f:for fi in files:fi_d = os.path.join(filepath,fi)if os.path.isdir(fi_d):get_pos(fi_d)else:img_path = os.path.join(filepath, fi_d)pos_list.append(img_path)
def get_ne(filepath):
#遍历filepath下所有文件,包括子目录files = os.listdir(filepath)with open("info.data", "w") as f:for fi in files:fi_d = os.path.join(filepath,fi)if os.path.isdir(fi_d):get_ne(fi_d)else:img_path = os.path.join(filepath,fi_d)neg_list.append(fi_d)#获取positive路径
get_pos(path_p)
#获取negative路径
get_ne(path_n)
print(path)
#存放pos
with open("positive/info.dat","w") as f:for i in pos_list:try:im = Image.open(i)except Exception:continueinfo_data =i[33:]+ " 1 0 0 " + str(im.size[0]) + " " + str(im.size[1])f.write(info_data + "\n")
#存放neg
with open("negative/bg.txt","w") as f:for i in neg_list:try:im = Image.open(i)except Exception:continuef.write(i[33:]+"\n")

三,生成vec文件与负样本列表文本文件

打开opencv的安装目录:

F:\opencv\opencv\build\x64\vc14\bin

bin文件夹下有一个opencv_createsamples.exe文件,这个文件用来生成vec文件
在此目录打开shell窗口:
输入.\opencv_createsamples.exe 就可以看见他的使用帮助:
在这里插入图片描述
输入以下命令进行创建:

 .\opencv_createsamples.exe -info F:\opencv\InputImg\face\positive\info.dat -vec F:\opencv\InputImg\face\mysamples.vec -bg F:\opencv\InputImg\face\negative\neg.txt -num 185 -bgcolor 0 -w 24 -h 24

命令解析:

-info   后面填写刚刚创建的正样本描述文件的地址
-vec  后面填写你要生成的vec文件存放的地址及文件名
-bg    填写你刚刚生成的负样本描述文件的地址
-num 填写你正样本的个数 
-bgcolor 填写你要去除的背景的颜色
-w 填写图片的宽度 训练器会自动将所有训练图片改为此宽度
-h 填写图片的高度 训练器会自动将所有训练图片改为此高度

创建完成后会生成vec文件

四,使用OpenCV自动的级联分类器训练工具,训练样本数据

打开opencv的安装目录:

F:\opencv\opencv\build\x64\vc14\bin

bin文件夹下有一个opencv_traincascade.exe文件,这个文件用来生成vec文件
在此目录打开shell窗口:
输入opencv_traincascade.exe 就可以看见他的使用帮助:
在这里插入图片描述
输入以下命令进行训练:

.\opencv_traincascade.exe -data F:\opencv\InputImg\face\ -vec F:\opencv\InputImg\face\mysamples.vec -bg bg.txt -numPos 170 -numNeg 500 -numStages 12 -featureType LBP -w 24 -h 24 -minHitRate 0.995 -maxFalseAlarmRate 0.5
-data 后面填写训练后的数据存放地址
-vec 填写第三步生成的vec文件的地址
-bg   填写负样本描述文件的地址
-numPos 填写要进行训练的正样本的数量  注意,这个数要小于实际的正样本的数量,否则训练过程中会导致溢出
-numNeg 在每个阶段用来训练的负样本数目 这个值可以设置大于真正的负样本图像 数目,程序可以自动从负样本图像中切割出和正样本大小一致的,这个参数一半 设置为正样本数目的1~3倍-numStages  指定训练层数,推荐15~20,层数越高,耗时越长。 
-numsplits 分裂子节点数目,选取默认值 2 
-featureType 填写训练的算法 LBP | HAAR
-minHitRate  训练结束的条件:训练的最小准确率
-maxFalseAlarmRate 最大虚警(误检率),每一层训练到这个值小于0.5时训练结束, 进入下一层训练
-mem 程序可使用的内存,这个设置为256即可,实际运行时根本就不怎么耗内 存,以MB为单位 -mode ALL指定haar特征的种类,BASIC仅仅使用垂直特征,ALL表示使用垂直 以及45度旋转特征  -w与-h表示样本的宽与高,必须跟vec中声明保持一致 

注意:在HARR训练是要加上-model ALL
** 注意:**
注意事项,在训练时要将负样本文件和描述文件放到训练器的文件夹下,不然会报错,找不到bg.txt的路径
不知道为啥,可能是opencv的bug吧

在这里插入图片描述
此时训练时传入的参数-bg的地址要写:bg.txt

.\opencv_traincascade.exe -data F:\opencv\InputImg\face\ -vec F:\opencv\InputImg\face\mysamples.vec -bg bg.txt -numPos 170 -numNeg 500 -numStages 12 -featureType LBP -w 24 -h 24 -minHitRate 0.995 -maxFalseAlarmRate 0.5

训练效果

在这里插入图片描述
训练结果:
在这里插入图片描述