案例
基于QT的人脸识别
pro文件需要加以下代码
INCLUDEPATH += E:/opencv/opencv3.4-qt-intall/install/include
INCLUDEPATH += E:/opencv/opencv3.4-qt-intall/install/include/opencv
INCLUDEPATH += E:/opencv/opencv3.4-qt-intall/install/include/opencv2
LIBS += E:/opencv/opencv3.4-qt-intall/install/x86/mingw/lib/libopencv_*.a
widget.h代码
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
#include<opencv2/face.hpp>
#include <vector>
#include <map>
#include <QMessageBox>
#include <QDebug>
#include <QFile>
#include <QTextStream>
#include <QDateTime>
#include <QTimerEvent>
#include<QtSerialPort/QtSerialPort>
#include<QtSerialPort/QSerialPortInfo>
using namespace cv;
using namespace cv::face;
using namespace std;
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
widget.cpp代码
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//1、准备相关容器
Mat src; //用于存储图像
Mat gray; //用于存储灰度图
Mat dest; //用于存储均衡化图像
VideoCapture video; //视频流对象,用于存储视频数据
CascadeClassifier c; //定义级联分类器对象
vector<Rect> faces; //用于存储图像的人脸矩形区域
//给级联分类器装载模型
//函数原型:bool load( const String& filename );
//参数:级联分类器模型,此处使用的是人脸分类模型
//返回值:成功下载返回值真,否则返回假
if(!c.load("E:\\opencv\\resourse\\haarcascade_frontalface_alt2.xml"))
{
QMessageBox::information(this, "提示", "人脸分类模型下载失败");
return;
}
//2、加载视频到对象中来
//函数原型:bool open(String fileNmae);
//功能:打开本地磁盘上的某个文件
//参数:文件路径
//返回值:成功打开返回真,否则返回假
//if(!video.open(0))
//打开给定路径的视频
if(!video.open("E:\\opencv\\resourse\\01.mp4"))
{
QMessageBox::information(this, "提示","视频打开失败");
return;
}
//程序执行至此,表示类 对象中包含了视频
while(video.read(src))
{
//此时src中读取了一张图像
//将图像进行翻转
//函数原型:void flip(InputArray src, OutputArray dst, int flipCode);
//参数1:要翻转的图像
//参数2:翻转后的图像容器
//参数3:翻转码:0表示按x轴翻转,正值表示按y轴翻转,负值表示两个轴都翻转
flip(src, src, 1);
/*src.at<cv::Vec3b>(i,j):表示该图像中的任意一个像素点,都是3字节组成
for(int i=0; i<src.rows; i++) //外层循环遍历行
{
for(int j=0; j<src.cols; j++) //内层循环遍历列数
{
//遍历当前像素的每一个颜色值
for(int k=0; k<3; k++)
{
src.at<cv::Vec3b>(i,j)[k] = 255 - src.at<cv::Vec3b>(i,j)[k]; //获取该颜色的反差值
}
}
}*/
//灰度处理
//函数原型:void cvtColor( InputArray src, OutputArray dst, int code, int dstCn = 0 );
//参数1:要处理的原图像
//参数2:色彩空间转换后的图像容器
//参数3:转换规则:CV_BGR2GRAY表示将BGR图转变成灰度图
cv::cvtColor(src, gray, CV_BGR2GRAY);
//均衡化处理
//函数原型:void equalizeHist( InputArray src, OutputArray dst );
//参数1:要被处理的图像
//参数2:均衡化处理后的图像容器
cv::equalizeHist(gray, dest);
//从灰度图中通过级联分类器获取人脸矩形区域
c.detectMultiScale(dest, faces);
//参数1:要被识别的图像
//参数2:存储图像上的人脸矩形区域的容器
//遍历矩形框数组,将所有的矩形框都绘制到指定图像上
for(uint i=0; i<faces.size(); i++)
{
//该循环中找到任意一个矩形框 faces[i]
cv::rectangle(src, faces[i], Scalar(0,0,255), 2);
cv::rectangle(gray, faces[i], Scalar(0,0,255), 2);
cv::rectangle(dest, faces[i], Scalar(0,0,255), 2);
//参数1:要绘制矩形框的图像
//参数2:要被绘制的矩形框
//参数3:矩形框颜色
//参数4:矩形框的粗细
}
//展示图像
imshow("src", src);
imshow("gray", gray);
imshow("dest", dest);
//调用延时函数
if(waitKey(30) == 27)
{
//如果用户按下了ESC,可以结束循环
break;
}
}
}
Widget::~Widget()
{
delete ui;
}
运行效果