OPENCV 人脸识别

4 篇文章 0 订阅

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <opencv2/opencv.hpp>
#include "opencv2/objdetect.hpp"
#include "opencv2/face.hpp"
#include <qimage.h>
#include <QTimer>
#include "opencv2/face/facerec.hpp"
using namespace cv;
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    void Delay_MSec(unsigned int msec);
    void OpenCamera();
    QImage Mat2QImage(Mat cvImg);
    bool Train();
private slots:
    void on_pushButton_2_clicked();//open
    void on_pushButton_4_clicked();//capture
    void on_pushButton_clicked();//quit

private:
    bool bLoad;
    Mat imageMat;
    VideoCapture _videoCapture;
    CascadeClassifier cascade;
    std::vector<Rect> rect;
    Ptr<cv::face::EigenFaceRecognizer> modelEigenFace = nullptr;
private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTime>
#include <QDebug>
#include <QDir>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{

    //级联分类器对象
    //读取级联分类器
    bLoad = cascade.load("../untitled/etc/haarcascades/haarcascade_frontalface_alt.xml");
    modelEigenFace = cv::face::EigenFaceRecognizer::create();
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

//Mat转化为QImage
QImage MainWindow::Mat2QImage(Mat cvImg)
{
    QImage qImg;
    if(cvImg.channels()==3)                             //3 channels color image
    {
        //Converts an image from one color space to another
        cv::cvtColor(cvImg,cvImg,COLOR_BGR2RGB);
        qImg =QImage((const unsigned char*)(cvImg.data),
                    cvImg.cols, cvImg.rows,
                    cvImg.cols*cvImg.channels(),
                    QImage::Format_RGB888);
    }
    else if(cvImg.channels()==1)                    //grayscale image
    {
        qImg =QImage((const unsigned char*)(cvImg.data),
                    cvImg.cols,cvImg.rows,
                    cvImg.cols*cvImg.channels(),
                    QImage::Format_Indexed8);
    }
    else
    {
        qImg =QImage((const unsigned char*)(cvImg.data),
                    cvImg.cols,cvImg.rows,
                    cvImg.cols*cvImg.channels(),
                    QImage::Format_RGB888);
    }
    return qImg;
}

void MainWindow::OpenCamera()
{
    if (_videoCapture.isOpened())
           return;
    _videoCapture.open(0);
    if(_videoCapture.isOpened())
    {
        bool bTrain = this->Train();
        while(1)
        {
            _videoCapture >> imageMat;
            //画面翻转 参数3为1 代表Y轴翻转
            flip(imageMat, imageMat, 1);
            if (!imageMat.empty())
            {

                Mat imageMat_gray;
                Mat predictImage;
                Mat temp_gray;
                cvtColor(imageMat, imageMat_gray, COLOR_BGR2GRAY);//转为灰度图
                equalizeHist(imageMat_gray, imageMat_gray);//均衡化

                cascade.detectMultiScale(imageMat_gray, rect, 1.1, 3, 0);//人脸检测
                for (int i = 0; i < rect.size(); i++)
                {
                    //取灰色人脸图像
                    Mat temp = imageMat(rect[i]);
                    cvtColor(temp, temp_gray, COLOR_BGR2GRAY);
                    cv::resize(temp_gray, predictImage, Size(100, 120));
                    //predict返回人脸 label
                    int predicted_label = -1;
                    if(bTrain)
                        predicted_label = modelEigenFace->predict(predictImage);
                    //框出人脸
                    rectangle(imageMat, rect[i], Scalar(0, 0, 255));
                    putText(imageMat, format("%s", (predicted_label == 12345 ? "PASS" : "FAIL")),
                            rect[i].tl(), FONT_HERSHEY_PLAIN, 1.0, Scalar(0, 0, 255));

                }
                //显示
                QImage image = Mat2QImage(imageMat);
                ui->label->setPixmap(QPixmap::fromImage(image));

            }
            Delay_MSec(10);
        }
    }
}


void MainWindow::on_pushButton_2_clicked()
{
    if(bLoad && modelEigenFace != nullptr)
        OpenCamera();
}


bool MainWindow::Train()
{
    std::vector<int> labels;
    std::vector<Mat> images;
    QString path = "../untitled/myFace.jpg";
    QFileInfo info(path);
    if(!info.exists())
        return false;
    Mat temp = imread(path.toStdString(),0);
    labels.push_back(12345);
    images.push_back(temp);
    modelEigenFace->train(images,labels);
    modelEigenFace->save("../untitled/my_eigen_face_modelEigenFace.xml");
    return true;
}

void MainWindow::on_pushButton_4_clicked()
{
    Mat cap;
    bool bWrite = false;
    for (int i = 0; i < rect.size(); i++)
    {
       cv::resize(imageMat(rect[i]), cap, Size(100, 120));
       cvtColor(cap,cap,COLOR_BGR2RGB);
       bWrite = imwrite("../untitled/myFace.jpg", cap);
    }
    if(bWrite)
    {
        qDebug("videoCapture imwrite success,start train!");
        this->Train();
    }

}

void MainWindow::on_pushButton_clicked()
{
    _videoCapture.release();
}

void MainWindow::Delay_MSec(unsigned int msec)
{
   QEventLoop loop;//定义一个新的事件循环
   QTimer::singleShot(msec, &loop, SLOT(quit()));//创建单次定时器,槽函数为事件循环的退出函数
   loop.exec();//事件循环开始执行,程序会卡在这里,直到定时时间到,本循环被退出
}

编译OpenCV+OpenCV_contrib见

QT + OPENCV + OpenCV_contrib + MINGW编译_weixin_44270564的博客-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值