目录
1.3.1使用Haar Cascades进行对象检测的基本流程
2-4主要内容
1. 导入级联分类器文件cascade.load
2. 矩形框图检测人脸cascade.detectMultiScale(grayImage, faceRects);
3. 转为灰度图加快检测速度cvtColor(SrcImage, grayImage, COLOR_BGR2GRAY);
//haar-- 级联分类器
cv::CascadeClassifier cascade;
//导入级联分类器文件
cascade.load("C:/opencv452/etc/haarcascades/haarcascade_frontalface_alt2.xml");
void FaceAttendence::timerEvent(QTimerEvent *e) //定时器事件一直采集数据
{
// 采集数据
Mat SrcImage;
if(cap.grab()){
cap.read(SrcImage);// 读取一帧数据
}
// 加快检测速度,转为灰度图
Mat grayImage;
cvtColor(SrcImage, grayImage, COLOR_BGR2GRAY);
//检测人脸数据
std::vector<Rect> faceRects;//检测结果(人脸矩形框)存储在一个 std::vector<cv::Rect> 容器中
cascade.detectMultiScale(grayImage, faceRects);
if(faceRects.size()>0)
{
Rect rect = faceRects.at(0); //第一个人脸矩形框,faceRects.at(0) 返回 faceRects 容器中的第一个元素,也就是检测到的第一个人脸的矩形框
//rectangle(SrcImage, rect, Scalar(0, 0, 255));
//移动人脸认证图片
ui ->headpicLb->move(rect.x, rect.y);
}else
{
// 把人脸认证框移动到中心位置
ui->headpicLb->move(110,60);
//把Mat数据转化为QbyteArray, 编码成JPG格式
std::vector<uchar> buf;
cv::imencode(".jpg", SrcImage, buf); // 存到buf中
//将vector<uchar> 类型强制转化为数组
QByteArray byte((const char*)buf.data(), buf.size());
//准备发送
quint64 backsize = byte.size();
QByteArray sendData;
QDataStream stream(&sendData,QIODevice::WriteOnly);//把数据打包为数据流
stream.setVersion(QDataStream::Qt_5_14);
stream<<backsize<<byte;
//发送
msocket.write(sendData);
}
//读取不到摄像头数据,返回
if(SrcImage.data == nullptr) return;
//把opencv的Mat格式数据(BGR)转换为QT的QImage(RGB)
cvtColor(SrcImage, SrcImage, COLOR_BGR2RGB);
QImage image(SrcImage.data, SrcImage.cols, SrcImage.rows, SrcImage.step1(), QImage::Format_RGB888);
QPixmap mmp = QPixmap::fromImage(image);
ui->videoLb->setPixmap(mmp);
}
1 Haar级联分类器
参考博文
级联分类器原理级联分类器原理 - wumh7 - 博客园 (cnblogs.com)
haar特征机器学习 之 Haar特征-CSDN博客
haarcacades模型OpenCV中 haarcascades 级联分类器各种模型.xml文件介绍-CSDN博客
1.1 人脸检测算法分类
1.1.1基于知识
主要方法:模板匹配,人脸特征,形状与边缘,纹理特征,颜色特征
基于知识的方法将人脸看成不同特征的特定组合,即通过人脸的眼睛、嘴巴、鼻子、耳朵等特征及其组合关系来检测人脸
1.1.2基于统计
主要方法:主成分分析与特征脸法,神经网络模型,隐马尔可夫模型,支持向量机,Adaboost算法
基于统计的方法将人脸看成统一的二维像素矩阵,通过大量的样本构建人脸子空间,通过相似度的大小来判断人脸是否存在
1.2 Haar分类器算法
Haar算法实际上是运用了boosting算法中的Adaboost算法。
Haar分类器利用Adaboost算法构建一个强分类器进行级联,而在底层特征抽取上采用的是高效的矩形特征以及积分图方法。
Haar分类器=类Haar特征+积分图法+Adaboost算法+级联
Haar分类器主要步骤如下:1. 提取类Haar特征;2. 利用积分图法对类Haar特征提取进行加速;3. 使用Adaboost算法训练强分类器,区分出人脸和非人脸;4. 使用筛选式级联把强的分类器级联在一起,从而提高检测准确度。
1.2.1人脸检测流程
用一个小的窗口在一幅图片中不断的滑动,每滑动到一个位置,就对该小窗口内的图像进行特征提取,若提取到的特征通过了所有训练好的强分类器的判定,则我们判定该小窗口的图片内含有人脸
1.2.2Haar-like特征
将Haar-like特征在图片上进行滑动,在每个位置计算白色区域对应的像素值的和减去黑色区域对应的像素值的和,从而提取出该位置的特征,人脸区域与非人脸区域提取出的特征值不同,从而区分出人脸区域和非人脸区域
1.2.3Adaboost算法
Adaboost算法是一种一般性的分类器性能提升算法。
Adaboost算法可以用来更好地选择矩形特征的组合,而这些矩形特征的组合就构成了分类器,分类器以决策树的方式存储这些矩形特征组合。
Adaboost是基于boosting算法的,而boosting算法涉及到弱分类器和强分类器的概念。
1.2.4分类器构建
我们可以用决策树来构建一个简单的弱分类器, 将提取到的特征与分类器的特征进行逐个比较,从而判断该特征是否属于人脸,如下图所示
强分类为的构造:
(1)首先选出部分样本,给它们赋予权重1/N,其中N为总的样本的个数;(2)用选出的样本训练弱分类器;(3)提高错误分类的样本的权重,并舍弃正确分类的样本,加入新的样本,新的样本的权重还是之前的1/N,进行新一轮的弱分类器的训练;(4)经过T轮后,训练出T个弱分类器;(5)将这T个弱分类器根据他们的分类错误率加权求和构成一个强的分类器
1.3haarcascades 级联分类器模型.xml文件
Haar Cascades 是一种用于对象检测的机器学习模型,特别是在OpenCV库中广泛使用。这些模型通过训练大量的正样本(包含目标对象的图像)和负样本(不包含目标对象的图像)来识别图像中的对象。Haar Cascades 模型通常以XML文件的形式提供,可以直接加载到OpenCV程序中使用。
1.3.1使用Haar Cascades进行对象检测的基本流程
- 加载Haar Cascades分类器XML文件。
- 读取图像并将其转换为灰度图像,因为Haar Cascades主要在灰度图像上工作。
- 使用detectMultiScale函数在图像中检测对象。
- 根据检测结果在原始图像上绘制矩形框或其他标记。
2 detectMultiScale函数
参考博文
人脸识别原理说明及示例opencv 进阶10-人脸识别原理说明及示例-cv2.CascadeClassifier.detectMultiScale()-CSDN博客
detectMultiScale函数详解简单人脸检测_detectmultiscale函数详解-CSDN博客
opencv2中人脸检测使用的是 detectMultiScale函数。它可以检测出图片中所有的人脸,并将人脸用vector保存各个人脸的坐标、大小(用矩形表示),函数由分类器对象调用:
void detectMultiScale(
const Mat& image,
CV_OUT vector<Rect>& objects,
double scaleFactor = 1.1,
int minNeighbors = 3,
int flags = 0,
Size minSize = Size(),
Size maxSize = Size()
);
函数介绍:
参数1:image--待检测图片,一般为灰度图像加快检测速度;
参数2:objects--被检测物体的矩形框向量组;
参数3:scaleFactor--表示在前后两次相继的扫描中,搜索窗口的比例系数。默认为1.1即每次搜索窗口依次扩大10%;
参数4:minNeighbors--表示构成检测目标的相邻矩形的最小个数(默认为3个)。如果组成检测目标的小矩形的个数和小于 min_neighbors - 1 都会被排除。如果min_neighbors 为 0,则函数不做任何操作就返回所有的被检候选矩形框, 这种设定值一般用在用户自定义对检测结果的组合程序上;
参数5:flags--要么使用默认值,要么使用CV_HAAR_DO_CANNY_PRUNING,如果设置为CV_HAAR_DO_CANNY_PRUNING,那么函数将会使用Canny边缘检测来排除边缘过多或过少的区域,因此这些区域通常不会是人脸所在区域;
参数6、7:minSize和maxSize用来限制得到的目标区域的范围。
3 move函数
move
函数是一个简单但非常有用的函数,用于动态调整窗口部件的位置。在你的人脸识别应用中,它用于将一个标签移动到检测到的人脸的位置,使得 UI 可以实时反映检测结果。
//检测人脸数据
std::vector<Rect> faceRects;//检测结果(人脸矩形框)存储在一个 std::vector<cv::Rect> 容器中
cascade.detectMultiScale(grayImage, faceRects);
if(faceRects.size()>0)
{
Rect rect = faceRects.at(0); //第一个人脸矩形框,faceRects.at(0) 返回 faceRects 容器中的第一个元素,也就是检测到的第一个人脸的矩形框
//rectangle(SrcImage, rect, Scalar(0, 0, 255));
//移动人脸认证图片
ui ->headpicLb->move(rect.x, rect.y);
}
使用了 Haar 分类器来检测灰度图像中的人脸,检测结果存储在一个 std::vector<cv::Rect>
容器中。cv::Rect
是 OpenCV 用于表示矩形的类。
cascade.detectMultiScale
是 OpenCV 中用于对象检测的函数,这里用于检测灰度图像中的人脸。它的输出是一个 std::vector<cv::Rect>
,其中每个 cv::Rect
表示一个检测到的对象(在这里是人脸)的矩形框。faceRects
保存了所有检测到的人脸的矩形框。
faceRects.at(0)
返回 faceRects
容器中的第一个元素,也就是检测到的第一个人脸的矩形框。cv::Rect
是一个矩形对象,包含了四个主要属性:x
, y
, width
, height
,分别表示矩形框左上角的坐标和矩形框的宽度与高度。
将 headpicLb
移动到检测到的人脸矩形框的左上角位置,从而使标签显示在检测到的人脸位置。
3.1 cv::Rect 的属性
- x: 矩形框左上角的横坐标。
- y: 矩形框左上角的纵坐标。
- width: 矩形框的宽度。
- height: 矩形框的高度。