一Cascade classifier 训练
Cascade classifier可以装载两种形式的训练器,但两种形式的训练器不可以互相装载
[1]opencv_traincascade,支持Harr,LBP(整数特性相对Haar更快),Hog,支持TBB多线程
[2]opencv_haartraining
辅助程序:
opencv_createsamples用准备训练用的正样本数据和测试数据,可以生成被两种以上支持的正样本数据,输出*.vec文件,以二进制形式存储
步骤(针对opencv_traincascade):
1>训练数据的准备
正样本,使用opencv_createsamples创建,负样本,手本准备
[1]负样本
图像中不包括需要检测的物体,图像的文件名包含在txt内,图像的尺寸可以不同,但都应该比训练器的窗口大
目录:
/img
img1.jpg
img2.jpg
bg.txt
txt:
img/img1.jpg
img/img2.jpg
[2]正样本
由opencv_createsamples程序生成,通过拥有物体的图像或者之前已经标记的图像集合
2>训练
利用opencv_traincascade
二Cascade classifier 检测
1,CascadeClassifier类
级联分类训练器用于物体检测
1>从文件加载classifier
CascadeClassifier::CascadeClassifier(const string& filename)
bool CascadeClassifier::load(const string& filename)
//filename,文件名
2>从FileStorage node加载classifier
bool CascadeClassifier::read(const FileNode& node)
//从FileStorage的结点FileNode中读取一个级联分类器对象
3>在image中探测物体
void CascadeClassifier
::detectMultiScale(const Mat& image,
vector<Rect>& objects,
double scaleFactor=1.1,
int minNeighbors=3, int flags=0,
Size minSize=Size(),
Size maxSize=Size())
//image,CV_8U
//objects,返回被检测到物体的区域
//scaleFactor,image的缩减因子
//minNeighbors,每个候选矩阵保留的邻域
//flags,在新版本中不使用
//minSize,物体的最小尺寸
//maxSize,物体的最大尺寸
4>setImage
设置一个图像用于检测
bool CascadeClassifier
::setImage(Ptr<FeatureEvaluator>& feval, const Mat& image)
//feval,指向特征计算器的指针,用计算特征
//image,CV_8UC1
//此函数针对每一幅图像调用,detectMultiScale()
5>runAt
在特定的点运行探测器
int CascadeClassifier
::runAt(Ptr<FeatureEvaluator>& feval, Point pt, double& weight)
//feval,指向特征计算器的指针,用计算特征
//pt,需要探测的点的坐标
//此函数返回一,如果在指定位置探测到物体,否则返回负数
//与setImage,结合使用
6>groupRectangles(单独函数)
将探测到的相近矩阵进行合并
void groupRectangles(vector<Rect>& rectList,
int groupThreshold,
double eps=0.2)
//rectList,用来输入和返回
//groupThreshold,rectList中的最小数量
//eps,矩阵之间的差异,当eps=0时不会合并,当eps=无穷时,全部合并
应用:
//从已经训练好的文件中加载face,eye级联分类器
cv::CascadeClassifier face("haarcascade_frontalface_alt.xml");
cv::CascadeClassifier eye("haarcascade_eye_tree_eyeglasses.xml");
//直方图均衡化
cv::equalizeHist(Image,Image);
std::vector<cv::Rect> faces;
//脸部探测
face.detectMultiScale(Image,faces,1.1,3,
0|CV_HAAR_SCALE_IMAGE);
//在每一个探测到脸部的区域探测眼
for(int i=0;i<faces.size();i++)
{
//进行脸部标记
cv::rectangle(result,faces[i],cv::Scalar(255),2);
std::vector<cv::Rect> eyes;
cv::Mat ROI=result(faces[i]);
eye.detectMultiScale(ROI,eyes,1.1,3,
0|CV_HAAR_SCALE_IMAGE);
for(int j=0;j<eyes.size();j++)
{
//进行眼标记
cv::rectangle(ROI,eyes[j],cv::Scalar(255),2);
}
}
效果图: