Qt框架下读取USB无驱摄像头视频流并作人脸识别

复制粘贴即可实现功能

  • MainWindow.h源代码

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QCamera>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <QTimer>
QT_BEGIN_NAMESPACE
namespace Ui {
    
     class MainWindow; }
QT_END_NAMESPACE
using namespace std;
class MainWindow : public QMainWindow
{
    
    
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void Func();

protected:
   bool eventFilter(QObject  *obj, QEvent *event);

private:
    Ui::MainWindow *ui;
    QCamera *m_camera;
    QTimer *timer;
    cv::CascadeClassifier face_cascade;    //载入分类器
};
#endif // MAINWINDOW_H

  • MainWindow.cpp源代码

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "opencv2/imgproc/types_c.h"
#include <QTimer>
#include <QDateTime>
#include <QKeyEvent>
cv::Mat QImage2cvMat(QImage image);
QImage MatToQImage(const cv::Mat& mat);
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    
    
    ui->setupUi(this);
    m_camera = new QCamera(this);//初始化摄像头设备
    m_camera->setCaptureMode(QCamera::CaptureVideo);//设置捕捉模式为视频
    m_camera->setViewfinder(ui->videoWidget);//设置 摄像头画面的显示位置
    m_camera->start();//开启摄像头
    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(Func()));
    timer->start(5);//槽函数每5ms被调用一次
    ui->label_test->installEventFilter(this);//一旦检测对象注册了,事件在被发送到原来的目的地之前, 会先发到eventFilter()函数.
}

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

void MainWindow::Func()
{
    
    
    QDateTime current_date_time =QDateTime::currentDateTime();
    QString current_date =current_date_time.toString("yyyy.MM.dd hh:mm:ss.zzz ddd");
    ui->label->setText(current_date);
    QPixmap pixmap = ui->videoWidget->grab();
    QImage image = pixmap.toImage();
    cv::Mat a = QImage2cvMat(image);
    face_cascade.load("D:/OpenCV_MinGW_Build_x64/etc/haarcascades/haarcascade_frontalface_alt2.xml");
    cv::Mat grayImg;
    std::vector<cv::Rect> faces;
    //图像预处理,转为灰度图
    cv::cvtColor(a, grayImg, cv::COLOR_BGR2GRAY);
   // QImage img_test=QImage((const unsigned char*)(a.data),a.cols,a.rows,a.cols * a.channels(),QImage::Format_RGB888);

    //图像预处理,直方图均衡化,用来增加图像对比度
    equalizeHist(grayImg, grayImg);
    face_cascade.detectMultiScale(grayImg, faces, 1.1, 4,cv::CASCADE_SCALE_IMAGE,cv::Size(70, 70), cv::Size(1000, 1000));
    for (size_t i = 0; i < faces.size(); i++)
    {
    
    
        rectangle(a, faces[i], cv::Scalar(0, 0, 1), 2, 8, 0);      //矩形画出检测到的位置
    }
    //QImage img=QImage((const unsigned char*)(a.data),a.cols,a.rows,a.cols * a.channels(),QImage::Format_RGB888);
   // ui->label->setPixmap(QPixmap::fromImage(img));  // 将图片显示到label上
   ui->label_test->setPixmap(pixmap);  // 将图片显示到label上
}

cv::Mat QImage2cvMat(QImage image)
{
    
    
    cv::Mat mat;
    switch (image.format())
    {
    
    
    case QImage::Format_ARGB32:
    case QImage::Format_RGB32:
    case QImage::Format_ARGB32_Premultiplied:
        mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine());
        break;
    case QImage::Format_RGB888:
        mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine());
        cv::cvtColor(mat, mat, CV_BGR2RGB);
        break;
    case QImage::Format_Indexed8:
        mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine());
        break;
    }
    return mat;
}
int i = 0;
bool MainWindow::eventFilter(QObject  *obj, QEvent *event)
{
    
    
    if (obj == ui->label_test)//当事件发生在u1(为Qlabel型)控件上
        {
    
    
            if (event->type() == QEvent::MouseButtonDblClick)//当为双击事件时
            {
    
    
                i++;
                if (i % 2 == 0) //此处为双击一次全屏,再双击一次退出
                {
    
    
                     ui->label_test->setWindowFlags(Qt::Dialog);
                     ui->label_test->showFullScreen();//全屏显示
                }
                else
                {
    
    
                     ui->label_test->setWindowFlags(Qt::SubWindow);
                     ui->label->setFixedSize(500,350);
                     ui->label_test->showNormal();//退出全屏
                };
            }
            return QObject::eventFilter(obj, event);//如果目标不是label_test, 或者这个event不是一个双击按键, 我们把控制权传回到基类的eventFilter去.
        }

}

猜你喜欢

转载自blog.csdn.net/qq_42308217/article/details/113749559