Qt 数据库,人脸识别

数据库

头文件

cpp 复制代码
#ifndef WIDGET_H
#define WIDGET_H

#include <QMainWindow>
#include<QSqlDatabase>
QT_BEGIN_NAMESPACE
namespace Ui { class widget; }
QT_END_NAMESPACE

class widget : public QMainWindow
{
    Q_OBJECT

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

private slots:
    void on_addbtn_clicked();

    void on_showedit_clicked();

    void on_deledit_clicked();

    void on_sortbtn_clicked();

private:
    Ui::widget *ui;
    QSqlDatabase db;
};
#endif // WIDGET_H

源文件

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"
#include <QMessageBox>
#include <QSqlQuery>
#include <QSqlError>
#include <QDebug>
#include <QSqlRecord>

widget::widget(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::widget)
{
    ui->setupUi(this);

    // 检查是否已经存在名为 "stu.db" 的数据库连接
    if (!db.contains("stu.db")) {
        // 通过 QSQLITE 驱动创建或连接数据库
        db = QSqlDatabase::addDatabase("QSQLITE");
        db.setDatabaseName("stu.db");
    }

    // 尝试打开数据库,若打开失败则显示提示信息并返回
    if (!db.open()) {
        QMessageBox::information(this, "提示", "数据库打开失败: " + db.lastError().text());
        return;
    }

    // 创建数据表的 SQL 语句
    QSqlQuery query;
    QString sql = "CREATE TABLE IF NOT EXISTS stu (num INT PRIMARY KEY, name CHAR(50), sex CHAR(1), score DOUBLE)";

    // 执行创建表的 SQL 语句,若执行失败则显示错误信息并返回
    if (!query.exec(sql)) {
        QMessageBox::information(this, "提示", "数据表创建失败: " + query.lastError().text());
        return;
    }
}

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

void widget::on_addbtn_clicked()
{
    // 从界面获取用户输入的数据
    int num = ui->numedit->text().toUInt();
    QString ui_name = ui->nameedit->text();
    QString ui_sex = ui->genderedit->text();
    double ui_score = ui->scoreedit->text().toDouble();  // 将文本转换为 double 类型

    // 检查输入数据是否完整,若不完整则提示用户并返回
    if (num == 0 || ui_name.isEmpty() || ui_sex.isEmpty() || ui_score == 0) {
        QMessageBox::information(this, "提示", "数据不完整");
        return;
    }

    // 生成插入数据的 SQL 语句
    QString sql = QString("INSERT INTO stu (num, name, sex, score) "
                          "VALUES (%1, '%2', '%3', %4);")
                          .arg(num)
                          .arg(ui_name)
                          .arg(ui_sex)
                          .arg(ui_score);

    QSqlQuery query;
    // 执行插入数据的 SQL 语句,若执行失败则显示错误信息,否则提示数据插入成功
    if (!query.exec(sql)) {
        QMessageBox::information(this, "提示", "插入数据失败: " + query.lastError().text());
    } else {
        QMessageBox::information(this, "提示", "数据插入成功");
    }
}

void widget::on_showedit_clicked()
{
    // 查询数据库中的所有数据
    QSqlQuery query("SELECT num, name, sex, score FROM stu");

    // 检查查询是否成功执行,若失败则显示提示信息并返回
    if (!query.exec()) {
        QMessageBox::information(this, "提示", "查询数据失败");
        return;
    }

    // 清空表格中的所有行
    ui->tableWidget->setRowCount(0);

    // 遍历查询结果并将每行数据插入到表格中
    int row = 0;
    while (query.next())
    {
        QSqlRecord record = query.record(); // 获取当前行的记录
        ui->tableWidget->insertRow(row); // 在表格中插入新行
        for (int j = 0; j < record.count(); j++)
        {
            // 将查询到的数据填入表格
            ui->tableWidget->setItem(row, j, new QTableWidgetItem(query.value(j).toString()));
        }
        row++; // 更新行索引
    }
}

void widget::on_deledit_clicked()
{
    // 获取当前选中的行号
    int row = ui->tableWidget->currentRow();
    if (row != -1) {
        // 如果选中了行,则删除该行
        ui->tableWidget->removeRow(row);
        QMessageBox::information(this, "提示", "行已经删除");
    } else {
        // 如果没有选中行,则提示用户
        QMessageBox::warning(this, "警告", "没选中行");
    }
}

void widget::on_sortbtn_clicked()
{
    // 查询数据库中的所有数据并按 num 降序排列
    QSqlQuery query("SELECT num, name, sex, score FROM stu ORDER BY num DESC");

    // 检查查询是否成功执行,若失败则显示提示信息并返回
    if (!query.exec()) {
        QMessageBox::information(this, "提示", "查询数据失败");
        return;
    }

    // 清空表格中的所有行
    ui->tableWidget->setRowCount(0);

    // 遍历查询结果并将每行数据插入到表格中
    int row = 0;
    while (query.next())
    {
        QSqlRecord record = query.record(); // 获取当前行的记录
        ui->tableWidget->insertRow(row); // 在表格中插入新行
        for (int j = 0; j < record.count(); j++)
        {
            // 将查询到的数据填入表格
            ui->tableWidget->setItem(row, j, new QTableWidgetItem(query.value(j).toString()));
        }
        row++; // 更新行索引
    }
}

人脸识别

头文件

cpp 复制代码
#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;
#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

源文件

cpp 复制代码
#include "mainwindow.h"
#include "ui_mainwindow.h"

// 构造函数,初始化 MainWindow 并设置 UI
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this); // 设置 UI

    // 创建 VideoCapture 对象,用于打开和读取视频
    VideoCapture video;

    // 打开视频文件 "01.mp4"
    video.open("D:\\opencv\\resource\\01.mp4");

    // 如果视频无法打开,弹出提示信息
    if(!video.open("D:\\opencv\\resource\\01.mp4"))
    {
        QMessageBox::information(this,"提示","视频打开失败");
        return;
    }

    // 定义 Mat 对象,用于存储视频帧、灰度图像和直方图均衡化后的图像
    Mat src;   // 原始帧
    Mat gray;  // 灰度图像
    Mat dest;  // 直方图均衡化后的图像

    // 定义人脸检测的级联分类器对象
    CascadeClassifier c;

    // 定义矩形向量用于存储检测到的面部区域
    vector<Rect> faces;

    // 加载 Haar 级联分类器文件,用于人脸检测
    if(!c.load("D:\\opencv\\resource\\haarcascade_frontalface_alt.xml"))
    {
        QMessageBox::information(this,"提示","加载失败");
        return;
    }

    // 开始读取视频帧
    while(video.read(src))
    {
        // 水平翻转视频帧(镜像效果)
        cv::flip(src, src, 1);

        // 将原始视频帧转换为灰度图像
        cv::cvtColor(src, gray, CV_BGR2GRAY);

        // 对灰度图像进行直方图均衡化,增强图像对比度
        cv::equalizeHist(gray, dest);

        // 检测人脸区域
        c.detectMultiScale(dest, faces);

        // 在每个检测到的人脸区域绘制红色矩形框
        for(uint i=0; i<faces.size(); i++)
        {
            cv::rectangle(src, faces[i], Scalar(0, 0, 255), 2);
        }

        // 显示标记了人脸的原始视频帧
        imshow("src", src);

        // 如果需要,可以打开以下代码,显示灰度图和均衡化后的图像
        // imshow("Gray", gray); // 显示灰度图
        // imshow("Equalized", dest); // 显示直方图均衡化后的图像

        // 按下 "ESC" 键退出
        if(waitKey(30) == 27)
        {
            break;
        }
    }
}

// 析构函数,释放 UI 资源
MainWindow::~MainWindow()
{
    delete ui;
}
相关推荐
Scott9999HH4 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
码智社5 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海5 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖6 小时前
JDK 26 新特性详解
java·开发语言
马优晨6 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
人邮异步社区8 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大9 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai9 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
এ慕ོ冬℘゜9 小时前
前端基础:什么是时间戳?JS获取时间戳三种方法与实战用途
开发语言·前端·javascript
执明wa9 小时前
LayoutInflater详解: XML是如何变成View的?
android·xml·开发语言·android studio