通过OpenCV自带的特征分类器和函数,实现一个简易版的人脸识别,在程序执行前,先了解一下OpenCV相关知识
haar特征分类器的使用:
1.图像识别理论:知识+经验
2.haar特征分类器
正样本+负样本进行训练
haar特征、卷积算法、分类决策、级联
CascadeClassifier:haar特征分类器,object模块中的类
CascadeClassifier用于加载特征分类器
empty判断是否加载
CascadeClassifier加载方式调用构造函数,CascadeClassifier(const string& cascade);
CascadeClassifier特征分类器在opencv/source目录中,data目录中有部分已经训练完毕的特征分类器。如果是apt下载则在/usr/shar/opencv中
使用detectMultiScale识别物体:
void cv::detectMultiScale(const cv::Mat&image, std::vectoer
double scaleFactor=1.1, int minNeighbors=3, int flags=0, Size minSize=Size(),
Size maxSize=Size());
image:要识别的图片,可以转换成灰度图,提高识别速度
objects:识别结果放置在此容器中
scaleFactor:放大倍数
minNeighbors:相邻扫描次数
flags:识别方式,默认为0, CASCADE_DO_CANNY_PRUNING=1
minSize:识别时,最小从此大小开始扫描maxSize:识别时,最大扫描到此大小
Mat对象标注:
1.rectangle:在图片上画矩形,imgproc模块中的接口
void cv::rectangle(cv::Mat& img, Rect rec, const cv:: Scalar& color, int thickness=1, int lineType=8, int shift=0);
img: 目标图像
rec:矩形范围
color:矩形边界颜色
thickness:边线粗细度,负值则填充
lineType:线类型
shift:坐标点的小数点位数
2.putText:在图片上写字,imgproc模块中的接口
void cv::putText(cv::Mat& img, const std::string& text, cv::Point org, int fontFace,
double fontScale, cv::Scalar color, int thickness=1, int lineType=8,
bool bottomLeftOrigin=false);
img:目标图像
text:文字内容
org:字坐标
fontFace:字体类型 fontScale:字体大小
color:矩形边界颜色
thickness:边线粗细度,负值则填充lineType:线类型
botomLeftOrigin:默认左下对齐
代码实现:
在QT中新建一个项目,然后在widget.cpp中输入以下代码
#include "widget.h"
#include "ui_widget.h"
#include
#include
#include
#include
#include
#include
using namespace cv;
using namespace std;
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
//1.读取图片
Mat img = imread("C:\\Users\\67098\\Desktop\\6.jpg");
//2.加载haar特征分类器,选择opencv中的分类器
CascadeClassifier classifier("C:\\Opencv4.5\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_default.xml");
if(classifier.empty()) //如果分类器为空,输出错误信息
{
qDebug() << "加载特征器失败!" ;
}
vector rects; //设置存放识别结果的容器
clock_t s = clock(); //设置记录物体识别前的时间s
classifier.detectMultiScale(img, rects); //将图片在特征分类器中进行物体识别,结果放置容器中
clock_t e = clock(); //设置记录物体识别后的时间s
qDebug() << "检测时间:" << 1000*(e-s)/CLOCKS_PER_SEC << "ms"; //输出检测时间
for(auto rect : rects) //循环容器中的元素
{ //输出物体识别的属性
qDebug() << "x:" << rect.x << "y:" << rect.y << "width:" << rect.width << "hight:" << rect.height;
rectangle(img, rect, {0,0,255}); //标注出识别范围
putText(img,"face",{30,30},102,1.0,{0,0,255}); //在图片上标注
}
imshow("img",img); //展示图片
}
Widget::~Widget()
{
delete ui;
}
运行结果
如果将其中的特征分类器haarcascade_frontalface_default.xml改为OpenCV另外一个识别眼睛的特征分类器haarcascade_eye.xml,再将最后的图片标注改为eye,得到的结果如下