0
点赞
收藏
分享

微信扫一扫

IDA Pro *(_QWORD *)和*(_BYTE *)表达式解释

先峰老师 04-02 19:00 阅读 2
qtopencv

服务端

.pro

QT       += core gui network sql

#window平台opencv,seetaface环境
win32{
LIBS +=C:\opencv452\x64\mingw\lib\libopencv*
LIBS +=C:\SeetaFace\lib\libSeeta*
INCLUDEPATH +=C:\opencv452\include
INCLUDEPATH += C:\opencv452\include\opencv2
INCLUDEPATH += C:\SeetaFace\include
INCLUDEPATH += C:\SeetaFace\include\seeta
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

#include <QTcpServer>
#include <QTcpSocket>

#include <qfaceobject.h>
#include <QDebug>

#include <QSqlTableModel>
#include <QSqlRecord>
#include <QSqlQuery>
#include <QSqlError>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

signals:
    void query(cv::Mat& image);
protected slots:
    void accept_client();

    void read_data();

    void recv_faceid(int64_t faceid);
private:
    Ui::MainWindow *ui;

    QTcpServer mserver;
    QTcpSocket *msocket;

    quint64 bsize;

    qFaceObject fobj;
    QSqlTableModel model;

};
#endif // MAINWINDOW_H

qfaceobject.h

#ifndef QFACEOBJECT_H
#define QFACEOBJECT_H

#include <QObject>

#include <seeta/FaceEngine.h>
#include <opencv.hpp>
#include <QDebug>

// 人脸数据存储,人脸检测,人脸识别
class qFaceObject : public QObject
{
    Q_OBJECT
public:
    explicit qFaceObject(QObject *parent = nullptr);

    ~qFaceObject();

public slots:
    int64_t face_register(cv::Mat& faceImage);   // 人脸注册
    int face_query(cv::Mat& faceImage);   // 人脸查询

signals:
    void send_faceid(int64_t faceid);
private:
    seeta::FaceEngine *fengineptr;


};

#endif // QFACEOBJECT_H

registerwin.h

#ifndef REGISTERWIN_H
#define REGISTERWIN_H

#include <QWidget>

#include <opencv.hpp>

namespace Ui {
class RegisterWin;
}

class RegisterWin : public QWidget
{
    Q_OBJECT

public:
    explicit RegisterWin(QWidget *parent = nullptr);
    ~RegisterWin();

    void timerEvent(QTimerEvent *e);

private slots:
    void on_resetButton_clicked();

    void on_addpicButton_clicked();

    void on_registerButton_clicked();

    void on_videoswitchButton_clicked();

    void on_cameraButton_clicked();

private:
    Ui::RegisterWin *ui;

    int timerid;
    cv::VideoCapture cap;
    cv::Mat image;
};

#endif // REGISTERWIN_H

selectwin.h

#ifndef SELECTWIN_H
#define SELECTWIN_H

#include <QWidget>

#include <QSqlTableModel>

//#include <QSqlQueryModel>
//#include <QSortFilterProxyModel>

#include <QDebug>

namespace Ui {
class SelectWin;
}

class SelectWin : public QWidget
{
    Q_OBJECT

public:
    explicit SelectWin(QWidget *parent = nullptr);
    ~SelectWin();

private slots:
    void on_pushButton_clicked();

private:
    Ui::SelectWin *ui;

    QSqlTableModel *model;

//    QSqlQueryModel *model;
//    QSortFilterProxyModel  *proxyModel;
};

#endif // SELECTWIN_H

sqlite数据库存储数据

main.cpp

#include "mainwindow.h"

#include <QApplication>

#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>

#include <registerwin.h>
#include <selectwin.h>

#include <opencv.hpp>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    qRegisterMetaType<cv::Mat>("cv::Mat&");
    qRegisterMetaType<cv::Mat>("cv::Mat");
    qRegisterMetaType<int64_t>("int64_t");



    // RegisterWin ww;
    // ww.show();

    // SelectWin sw;
    // sw.show();

    // 连接数据库
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    // 设置数据库名称
    db.setDatabaseName("server.db");
    // 打开数据库
    if(!db.open())
    {
        qDebug() <<db.lastError().text();
        return  -1;
    }

    // 创建员工信息表格
    QString createsql = "create table if not exists  employee(employeeID integer primary key autoincrement, name varchar(256), sex varchar(32),"
            "birthday text, address text, phone text, faceID integer unique, headfile text)";
    QSqlQuery query;
    if(!query.exec(createsql))
    {
        qDebug() << query.lastError().text();
        return -1;
    }

    // 考勤表格
    createsql = "create table if not exists  attendance(attendanceID integer primary key autoincrement, employeeID integer,"
                "attendanceTime TimeStamp NOT NULL DEFAULT(datetime('now','localtime')))";
    if(!query.exec(createsql))
    {
        qDebug() << query.lastError().text();
        return -1;
    }


    MainWindow w;
    w.show();


    return a.exec();
}





线程:处理识别face任务

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QDateTime>
#include <opencv.hpp>
#include <QThread>

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

    this->setWindowIcon(QIcon(":/z2.jpg"));

    //qtcpServer 当有客户端连会发送newconnection信号
    connect(&mserver, &QTcpServer::newConnection, this, &MainWindow::accept_client);

    mserver.listen(QHostAddress::Any, 9898); // 监听 启动服务器

    bsize = 0;

    // 给sql模型绑定表格
    model.setTable("employee");

    // 创建一个线程
    QThread *thread = new QThread();
    // 把qFaceObject fobj对象移动到thread线程中执行
    fobj.moveToThread(thread);
    thread->start(); // 启动线程

    connect(this, &MainWindow::query, &fobj, &qFaceObject::face_query);

    // 关联QFaceObject对象里面的send_faceid信号
    connect(&fobj, &qFaceObject::send_faceid, this, &MainWindow::recv_faceid);
}

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

// 接受客户端连接
void MainWindow::accept_client()
{
    qDebug() << "新客户端连上了";
    // 获取与客户端通信的套接字
    msocket = mserver.nextPendingConnection();

    // 当客户端有数据到达会发送readyRead信号
    connect(msocket, &QTcpSocket::readyRead, this, &MainWindow::read_data);
}

// 读取客户端发送的数据
void MainWindow::read_data()
{
    //读取所有的数据
    // QString msg = msocket->readAll();
    // qDebug() <<msg;


    QDataStream stream(msocket);  // 套接字绑定到数据流
    stream.setVersion(QDataStream::Qt_5_14);

    if(bsize == 0){
        if(msocket->bytesAvailable() < (qint64)sizeof(bsize)) return;
        // 采集数据的长度
        stream>>bsize;
    }

    if(msocket->bytesAvailable() <(qint64)bsize) // 说明数据还没有发送完成,返回继续等待
    {
        return;
    }

    QByteArray data;
    stream>>data;
    bsize = 0;
    if(data.size() == 0)  // 没有读到数据
    {
        return;
    }

    // 显示图片
    QPixmap mmp;
    mmp.loadFromData(data,"jpg");
    mmp = mmp.scaled(ui->piclb->size());
    ui->piclb->setPixmap(mmp);

    // 识别人脸   QByteArray转Mat格式
    cv::Mat faceImage;
    std::vector<uchar> decode;
    decode.resize(data.size());
    memcpy(decode.data(), data.data(), data.size());
    faceImage = cv::imdecode(decode, cv::IMREAD_COLOR);


    // int faceid = fobj.face_query(faceImage);   // 消化资源较多
    emit query(faceImage);



}


void MainWindow::recv_faceid(int64_t faceid)
{
    // qDebug() << "人脸id是:"<<faceid;

    // 从数据库中查询faceid对应的个人信息
    qDebug() <<"识别到的人脸-> id:" <<faceid;
    if(faceid < 0)
    {
        QString sdmsg = QString("{\"employeeID\": \"\" , \"name\": \"\", \"department\": \"\", \"time\": \"\"}");
        msocket->write(sdmsg.toUtf8());  // 把打包好的 空 数据发送给客户端
        return ;
    }

    // 给模型设置过滤器
    model.setFilter(QString("faceID=%1").arg(faceid));
    // 查询
    model.select();
    // 判断是否查询到数据
    if(model.rowCount() == 1)
    {
        // 工号,姓名,部门,时间
        // {employeeID:%1, name:%2, department:软件, time:%3}
        QSqlRecord record = model.record(0);
        QString sdmsg = QString("{\"employeeID\":\"%1\", \"name\":\"%2\", \"department\":\"软件\", \"time\":\"%3\"}")
                .arg(record.value("employeeID").toString()).arg(record.value("name").toString())
                .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));

        // msocket->write(sdmsg.toUtf8());  // 把打包好的数据发送给客户端

        // 把数据写入数据库--考勤表 attendance
        QString insertSql = QString("insert into attendance(employeeID) values('%1')").arg(record.value("employeeID").toString());
        QSqlQuery query;
        if(!query.exec(insertSql))
        {
            QString sdmsg = QString("{\"employeeID\": \"\" , \"name\": \"\", \"department\": \"\", \"time\": \"\"}");
            msocket->write(sdmsg.toUtf8());  // 把打包好的 空 数据发送给客户端
            qDebug() <<query.lastError().text();
            return ;
        }else
        {
            msocket->write(sdmsg.toUtf8());  // 把打包好的数据发送给客户端
        }

    }
}




封装识别、注册功能

qfaceobject.cpp

#include "qfaceobject.h"

qFaceObject::qFaceObject(QObject *parent) : QObject(parent)
{
    // 初始化
    seeta::ModelSetting FDmode("C:/SeetaFace/bin/model/fd_2_00.dat",seeta::ModelSetting::CPU,0);
    seeta::ModelSetting PDmode("C:/SeetaFace/bin/model/pd_2_00_pts5.dat",seeta::ModelSetting::CPU,0);
    seeta::ModelSetting FRmode("C:/SeetaFace/bin/model/fr_2_10.dat",seeta::ModelSetting::CPU,0);
    this->fengineptr = new seeta::FaceEngine(FDmode, PDmode, FRmode);

    // 导入已有的人脸数据库
    this->fengineptr->Load("./face.db");

}


// 析构函数
qFaceObject::~qFaceObject()
{
    delete  fengineptr;
}

int64_t qFaceObject::face_register(cv::Mat &faceImage)
{
    // 把OpenCV的Mat数据转为seetaface的数据
    SeetaImageData simage;
    simage.data = faceImage.data;
    simage.width = faceImage.cols;
    simage.height = faceImage.rows;
    simage.channels = faceImage.channels();
    int64_t faceid = this->fengineptr->Register(simage);   // 注册返回一个人脸id
    qDebug() << "faceid是:" <<faceid;

    if(faceid >= 0){
        fengineptr->Save("./face.db");
    }

    return faceid;

}

int qFaceObject::face_query(cv::Mat &faceImage)
{
    // 把OpenCV的Mat数据转为seetaface的数据
    SeetaImageData simage;
    simage.data = faceImage.data;
    simage.width = faceImage.cols;
    simage.height = faceImage.rows;
    simage.channels = faceImage.channels();
    float similarity = 0;
    int64_t faceid = fengineptr->Query(simage,&similarity);  // 运行时间比较长
    qDebug() <<"查询:"<<faceid <<similarity;
    // if(similarity > 0.85)   // 相似度
    if(similarity > 0.7)
    {
        emit send_faceid(faceid);
    }else {
        emit send_faceid(-1);
    }

    return faceid;
}








registerwin.cpp

#include "registerwin.h"
#include "ui_registerwin.h"

#include <QFileDialog>
#include <qfaceobject.h>
#include <QSqlTableModel>
#include <QSqlRecord>
#include <QMessageBox>

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

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

void RegisterWin::timerEvent(QTimerEvent *e)
{
    Q_UNUSED(e);

    // 获取摄像头数据,并且显示在界面上

    if(cap.isOpened())
    {
        cap>>image;
        if(image.data == nullptr) return;
    }
    // Mat --> QImage
    cv::Mat rgbImage;
    cv::cvtColor(image, rgbImage, cv::COLOR_BGR2RGB);
    QImage qImg(rgbImage.data, rgbImage.cols, rgbImage.rows, rgbImage.step1(), QImage::Format_RGB888);
    // 在qt界面上显示
    QPixmap mmp = QPixmap::fromImage(qImg);
    mmp = mmp.scaledToWidth(ui->pichead->width());
    ui->pichead->setPixmap(mmp);
}

void RegisterWin::on_resetButton_clicked()
{
    // 清空数据
    ui->nameEdit->clear();
    // ui->birthdaydateEdit->clear();
    ui->birthdaydateEdit->setDate(QDate::currentDate());
    ui->addressEdit->clear();
    ui->phoneEdit->clear();
    ui->picfileEdit->clear();

}

void RegisterWin::on_addpicButton_clicked()
{
    // 通过文件对话框,选择文件路径
    QString filepath = QFileDialog::getOpenFileName(this);
    ui->picfileEdit->setText(filepath);
    // 显示图片
    QPixmap mmp(filepath);
    mmp = mmp.scaledToWidth(ui->pichead->width());   // 根据框的宽度,设置图片的宽度,图片高度自适应
    ui->pichead->setPixmap(mmp);

}



void RegisterWin::on_registerButton_clicked()
{
    // 1、通过照片,结合faceObject模块,得到faceID
    qFaceObject faceobj;
    cv::Mat image = cv::imread(ui->picfileEdit->text().toUtf8().data());
    int faceID = faceobj.face_register(image);

    // 把头像保存到一个固定路径下
    QString headfile = QString("./data/%1.jpg").arg(QString(ui->nameEdit->text().toUtf8().toBase64()));
    cv::imwrite(headfile.toUtf8().data(), image);

    // 2、把个人信息存储到数据库表employee
    QSqlTableModel model;
    model.setTable("employee");  // 设置表名
    QSqlRecord record = model.record();
    // 设置数据
    record.setValue("name", ui->nameEdit->text());
    record.setValue("sex", ui->manradioButton->isChecked()?"男":"女");
    record.setValue("birthday",ui->birthdaydateEdit->text());
    record.setValue("address",ui->addressEdit->text());
    record.setValue("phone",ui->phoneEdit->text());
    record.setValue("faceID",faceID);
    // 头像路径
    record.setValue("headfile",headfile);
    // 把记录插入到数据库表格中
    bool ret = model.insertRecord(0,record);


    // 3、提示注册成功
    if(ret)
    {
        QMessageBox::information(this,"注册提示","注册成功");
        // 提交
        model.submitAll();
    }else {
        QMessageBox::information(this,"注册提示","注册失败");
    }

}



void RegisterWin::on_videoswitchButton_clicked()
{
    if(ui->videoswitchButton->text() == "打开摄像头")
    {
        // 打开摄像头
        if(cap.open(0))
        {
            ui->videoswitchButton->setText("关闭摄像头");

            timerid = startTimer(100);     // 启动定时器事件
        }
    }else
    {
        killTimer(timerid);  // 关闭定时器事件
        ui->videoswitchButton->setText("打开摄像头");
        // 关闭摄像头
        cap.release();
    }
}


void RegisterWin::on_cameraButton_clicked()
{
    // 保存数据
    // 把头像保存到一个固定路径下
    QString headfile = QString("./data/%1.jpg").arg(QString(ui->nameEdit->text().toUtf8().toBase64()));
    ui->picfileEdit->setText(headfile);
    cv::imwrite(headfile.toUtf8().data(), image);

    killTimer(timerid);  // 关闭定时器事件
    ui->videoswitchButton->setText("打开摄像头");
    // 关闭摄像头
    cap.release();
}







selectwin.cpp

#include "selectwin.h"
#include "ui_selectwin.h"

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

    //model = new QSqlTableModel();

}

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

void SelectWin::on_pushButton_clicked()
{
    model = new QSqlTableModel();
    if(ui->radioButton->isChecked())
    {
        model->setTable("employee");

    }
    if(ui->radioButton_2->isChecked())
    {
        model->setTable("attendance");

    }

    // 设置过滤器
    // model->setFilter("name='张三'");

    //查询
    model->select();
    ui->tableView->setModel(model);

    //    qDebug()<< model->rowCount();
    //     qDebug() << "查询";


    /*
    QString cmd;

    model = new QSqlQueryModel(this);
    cmd += "select * from employee ";

    model->setQuery(cmd);

    proxyModel = new QSortFilterProxyModel(this);
    proxyModel->setSourceModel(model);

    ui->tableView->setModel(proxyModel);
*/

}

mainwindow.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>664</width>
    <height>420</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>服务端</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QGridLayout" name="gridLayout">
    <item row="0" column="0">
     <widget class="QTabWidget" name="tabWidget">
      <property name="currentIndex">
       <number>0</number>
      </property>
      <widget class="QWidget" name="tab">
       <attribute name="title">
        <string>考勤</string>
       </attribute>
       <widget class="QLabel" name="piclb">
        <property name="geometry">
         <rect>
          <x>20</x>
          <y>40</y>
          <width>321</width>
          <height>271</height>
         </rect>
        </property>
        <property name="styleSheet">
         <string notr="true">background-color: rgb(255, 170, 127);</string>
        </property>
        <property name="text">
         <string>考勤图像</string>
        </property>
       </widget>
      </widget>
      <widget class="RegisterWin" name="tab_2">
       <attribute name="title">
        <string>注册</string>
       </attribute>
      </widget>
      <widget class="SelectWin" name="tab_3">
       <attribute name="title">
        <string>查询</string>
       </attribute>
      </widget>
     </widget>
    </item>
   </layout>
  </widget>
 </widget>
 <customwidgets>
  <customwidget>
   <class>RegisterWin</class>
   <extends>QWidget</extends>
   <header location="global">registerwin.h</header>
   <container>1</container>
  </customwidget>
  <customwidget>
   <class>SelectWin</class>
   <extends>QWidget</extends>
   <header location="global">selectwin.h</header>
   <container>1</container>
  </customwidget>
 </customwidgets>
 <resources/>
 <connections/>
</ui>

registerwin.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>RegisterWin</class>
 <widget class="QWidget" name="RegisterWin">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>525</width>
    <height>344</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <layout class="QHBoxLayout" name="horizontalLayout_8">
   <item>
    <layout class="QVBoxLayout" name="verticalLayout">
     <item>
      <layout class="QHBoxLayout" name="horizontalLayout">
       <item>
        <widget class="QLabel" name="label">
         <property name="font">
          <font>
           <pointsize>15</pointsize>
          </font>
         </property>
         <property name="text">
          <string>姓名:</string>
         </property>
        </widget>
       </item>
       <item>
        <widget class="QLineEdit" name="nameEdit">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
           <horstretch>0</horstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
        </widget>
       </item>
      </layout>
     </item>
     <item>
      <layout class="QHBoxLayout" name="horizontalLayout_2">
       <item>
        <widget class="QLabel" name="label_2">
         <property name="font">
          <font>
           <pointsize>15</pointsize>
          </font>
         </property>
         <property name="text">
          <string>性别:</string>
         </property>
        </widget>
       </item>
       <item>
        <widget class="QRadioButton" name="manradioButton">
         <property name="font">
          <font>
           <pointsize>15</pointsize>
          </font>
         </property>
         <property name="text">
          <string>男</string>
         </property>
        </widget>
       </item>
       <item>
        <widget class="QRadioButton" name="womanradioButton_2">
         <property name="font">
          <font>
           <pointsize>15</pointsize>
          </font>
         </property>
         <property name="text">
          <string>女</string>
         </property>
        </widget>
       </item>
      </layout>
     </item>
     <item>
      <layout class="QHBoxLayout" name="horizontalLayout_5">
       <item>
        <widget class="QLabel" name="label_5">
         <property name="font">
          <font>
           <pointsize>15</pointsize>
          </font>
         </property>
         <property name="text">
          <string>生日:</string>
         </property>
        </widget>
       </item>
       <item>
        <widget class="QDateEdit" name="birthdaydateEdit">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
           <horstretch>0</horstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
         <property name="font">
          <font>
           <pointsize>15</pointsize>
          </font>
         </property>
        </widget>
       </item>
      </layout>
     </item>
     <item>
      <layout class="QHBoxLayout" name="horizontalLayout_3">
       <item>
        <widget class="QLabel" name="label_3">
         <property name="font">
          <font>
           <pointsize>15</pointsize>
          </font>
         </property>
         <property name="text">
          <string>地址:</string>
         </property>
        </widget>
       </item>
       <item>
        <widget class="QLineEdit" name="addressEdit">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
           <horstretch>0</horstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
        </widget>
       </item>
      </layout>
     </item>
     <item>
      <layout class="QHBoxLayout" name="horizontalLayout_4">
       <item>
        <widget class="QLabel" name="label_4">
         <property name="font">
          <font>
           <pointsize>15</pointsize>
          </font>
         </property>
         <property name="text">
          <string>电话:</string>
         </property>
        </widget>
       </item>
       <item>
        <widget class="QLineEdit" name="phoneEdit">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
           <horstretch>0</horstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
        </widget>
       </item>
      </layout>
     </item>
     <item>
      <layout class="QHBoxLayout" name="horizontalLayout_6">
       <item>
        <widget class="QPushButton" name="registerButton">
         <property name="font">
          <font>
           <pointsize>15</pointsize>
          </font>
         </property>
         <property name="text">
          <string>注册</string>
         </property>
        </widget>
       </item>
       <item>
        <widget class="QPushButton" name="resetButton">
         <property name="font">
          <font>
           <pointsize>15</pointsize>
          </font>
         </property>
         <property name="text">
          <string>重置</string>
         </property>
        </widget>
       </item>
      </layout>
     </item>
    </layout>
   </item>
   <item>
    <layout class="QVBoxLayout" name="verticalLayout_2" stretch="4,1,0">
     <item>
      <widget class="QLabel" name="pichead">
       <property name="styleSheet">
        <string notr="true">background-color: rgb(255, 170, 255);</string>
       </property>
       <property name="text">
        <string/>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QLineEdit" name="picfileEdit"/>
     </item>
     <item>
      <layout class="QHBoxLayout" name="horizontalLayout_7">
       <item>
        <widget class="QPushButton" name="addpicButton">
         <property name="font">
          <font>
           <pointsize>7</pointsize>
          </font>
         </property>
         <property name="text">
          <string>添加头像</string>
         </property>
        </widget>
       </item>
       <item>
        <widget class="QPushButton" name="videoswitchButton">
         <property name="font">
          <font>
           <pointsize>7</pointsize>
          </font>
         </property>
         <property name="text">
          <string>打开摄像头</string>
         </property>
        </widget>
       </item>
       <item>
        <widget class="QPushButton" name="cameraButton">
         <property name="font">
          <font>
           <pointsize>7</pointsize>
          </font>
         </property>
         <property name="text">
          <string>拍照</string>
         </property>
        </widget>
       </item>
      </layout>
     </item>
    </layout>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections/>
</ui>

selectwin.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>SelectWin</class>
 <widget class="QWidget" name="SelectWin">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>569</width>
    <height>408</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <widget class="QTableView" name="tableView">
   <property name="geometry">
    <rect>
     <x>10</x>
     <y>60</y>
     <width>511</width>
     <height>281</height>
    </rect>
   </property>
  </widget>
  <widget class="QWidget" name="layoutWidget">
   <property name="geometry">
    <rect>
     <x>20</x>
     <y>10</y>
     <width>341</width>
     <height>30</height>
    </rect>
   </property>
   <layout class="QHBoxLayout" name="horizontalLayout" stretch="2,2,0">
    <item>
     <widget class="QRadioButton" name="radioButton">
      <property name="font">
       <font>
        <pointsize>15</pointsize>
       </font>
      </property>
      <property name="text">
       <string>员工</string>
      </property>
     </widget>
    </item>
    <item>
     <widget class="QRadioButton" name="radioButton_2">
      <property name="font">
       <font>
        <pointsize>15</pointsize>
       </font>
      </property>
      <property name="text">
       <string>考勤</string>
      </property>
     </widget>
    </item>
    <item>
     <widget class="QPushButton" name="pushButton">
      <property name="font">
       <font>
        <pointsize>15</pointsize>
       </font>
      </property>
      <property name="text">
       <string>查询</string>
      </property>
     </widget>
    </item>
   </layout>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


客户端

facetest.pro

QT       += core gui network

#window平台opencv,seetaface环境
win32{
LIBS +=C:\opencv452\x64\mingw\lib\libopencv*
LIBS +=C:\SeetaFace\lib\libSeeta*
INCLUDEPATH +=C:\opencv452\include
INCLUDEPATH += C:\opencv452\include\opencv2
INCLUDEPATH += C:\SeetaFace\include
INCLUDEPATH += C:\SeetaFace\include\seeta
}

#linux平台opencv seetaface环境
unix{
LIBS += -L/opt/opencv4-pc/lib -lopencv_world \
-lSeetaFaceDetector \
-lSeetaFaceLandmarker \
-lSeetaFaceRecognizer \
-lSeetaFaceTracker \
-lSeetaNet \
-lSeetaQualityAssessor \

INCLUDEPATH += /opt/opencv4-pc/include/opencv4
INCLUDEPATH += /opt/opencv4-pc/include/opencv4/opencv2
INCLUDEPATH += /opt/opencv4-pc/include
INCLUDEPATH += /opt/opencv4-pc/include/seeta
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

#include <opencv.hpp>

#include <QTcpSocket>
#include <QTimer>

using namespace cv;
using namespace std;

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

    // 定时器 事件
    void timerEvent(QTimerEvent *e);

protected slots:
    void recv_data();
private slots:
    void timer_connect();   // 用定时器定时的去连接服务器
    void stop_connect();
    void start_connect();

private:
    Ui::MainWindow *ui;

    // 摄像头
    VideoCapture cap;
    // haar--级联分类器
    cv::CascadeClassifier cascade;

    // 创建网络套接字,定时器
    QTcpSocket msocket;
    QTimer mtimer;

    // 标志是否是同一个人脸进入到识别区域
    int flag;

    // 保存人脸的数据
    cv::Mat faceMat;



};
#endif // MAINWINDOW_H








mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QImage>
#include <QPainter>
#include <QDebug>
#include <QJsonDocument>
#include <QJsonParseError>
#include <QJsonObject>


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

    this->setWindowIcon(QIcon(":/z1.jpg"));

    // 打开摄像头
    cap.open(0);  //  Linux下是/dev/video0-7
    // 启动定时器 事件
    startTimer(100);

    // 导入级联分类器文件   人脸检测
    cascade.load("C:/opencv452/etc/haarcascades/haarcascade_frontalface_alt2.xml");

    // QTcpSocket 当断开连接的时候disconnected信号,连接成功会发送connected信号
    connect(&msocket, &QTcpSocket::disconnected, this, &MainWindow::start_connect);
    connect(&msocket, &QTcpSocket::connected, this, &MainWindow::stop_connect);

    // 关联接收数据的槽函数
    connect(&msocket, &QTcpSocket::readyRead, this, &MainWindow::recv_data);


    // 定时器连接服务器
    connect(&mtimer, &QTimer::timeout, this, &MainWindow::timer_connect);
    // 启动定时器
    mtimer.start(5000); // 每5s连接一次,直到连接成功就不再连接

    flag = 0;

    ui->widget_2->hide();
}

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

void MainWindow::recv_data()
{
    // {employeeID:%1, name:%2, department:软件, time:%3}

    // QString msg = msocket.readAll();
    // qDebug() << msg;

    // Json解析
    QByteArray array  = msocket.readAll();
    qDebug() << array;
    QJsonParseError err;
    QJsonDocument doc = QJsonDocument::fromJson(array, &err);
    if(err.error != QJsonParseError::NoError)
    {
        qDebug() <<"json数据错误";
        return ;
    }

    QJsonObject obj = doc.object();
    QString employeeID = obj.value("employeeID").toString();
    QString name = obj.value("name").toString();
    QString department = obj.value("department").toString();
    QString timestr = obj.value("time").toString();

    ui->label_7->setText(employeeID);
    ui->label_9->setText(name);
    ui->label_11->setText(department);
    ui->label_13->setText(timestr);

    // 把 OpenCV里面的Mat数据格式(BGR),转qt里面的QImage(RGB)
    // cvtColor(faceMat,faceMat, COLOR_BGR2RGB);    // 将一种颜色空间的图像转换为另一种颜色空间的图像
    // QImage image(faceMat.data, faceMat.cols, faceMat.rows, faceMat.step1(), QImage::Format_RGB888);
    // QPixmap mmp = QPixmap::fromImage(image);
    // ui->label_5->setPixmap(mmp);

    // 通过样式显示图片
    ui->label_5->setStyleSheet("border-radius: 50%; border-image: url(./face.jpg);");
    ui->widget_2->show();


}

void MainWindow::timerEvent(QTimerEvent *e)
{
    Q_UNUSED(e);

    // 采集数据
    Mat srcImage;
    if(cap.grab())
    {
        cap.read(srcImage);  // 读取一帧数据
    }

    // 把图片大小设置与显示窗口一样大
    cv::resize(srcImage, srcImage, Size(401,371));

    Mat grayImage;  // 定义灰度图像
    cvtColor(srcImage,grayImage,COLOR_BGRA2GRAY );    // 将一种颜色空间的图像转换为另一种颜色空间的图像
    // 检测人脸数据
    std::vector<Rect> faceRects;
    // cascade.detectMultiScale( srcImage, faceRects, 1.1, 3, 0, cv::Size(200,200));
    // cascade.detectMultiScale( srcImage, faceRects);
    cascade.detectMultiScale( grayImage, faceRects);   // 检测人脸

    if(faceRects.size() > 0  && flag >=0)  // 检测到人脸
    {
        Rect rect = faceRects.at(0);  // 第一个人脸的矩形框
        rectangle(srcImage, rect, Scalar(0,0,255));   // 绘制

        // 移动人脸框
        ui->headpiclb->move(rect.x, rect.y/2);

        if (flag > 2){

            // 把Mat数据转化为QbyteArray   先编码成jpg格式
            std::vector<uchar> buf;
            cv::imencode(".jpg", srcImage, buf);
            QByteArray byte((const char*)buf.data(), buf.size());   // 强转为字节数组
            // 准备发送: 发文件的大小,发文件
            quint64 backsize = byte.size();
            QByteArray sendData;
            QDataStream stream(&sendData, QIODevice::WriteOnly);
            stream.setVersion(QDataStream::Qt_5_14);
            stream<<backsize<<byte;
            // 发送
            msocket.write(sendData);
            flag = -2;

            faceMat = srcImage(rect);
            // 保存
            imwrite("./face.jpg",faceMat);
        }
        flag++;

    }
    if(faceRects.size() == 0)
    {
        // 把人脸框移动到中心位置
        ui->headpiclb->move(100,80);
        ui->widget_2->hide();
        flag = 0;
    }

    /*
    参数1:image--待检测图片,一般为灰度图像加快检测速度;
    参数2:objects--被检测物体的矩形框向量组;
    参数3:scaleFactor--表示在前后两次相继的扫描中,搜索窗口的比例系数。默认为1.1即每次搜索窗口依次扩大10%;
    参数4:minNeighbors--表示构成检测目标的相邻矩形的最小个数(默认为3个)。
            如果组成检测目标的小矩形的个数和小于 min_neighbors - 1 都会被排除。
            如果min_neighbors 为 0, 则函数不做任何操作就返回所有的被检候选矩形框,
            这种设定值一般用在用户自定义对检测结果的组合程序上;
    参数5:flags--要么使用默认值,要么使用CV_HAAR_DO_CANNY_PRUNING,如果设置为
    CV_HAAR_DO_CANNY_PRUNING,那么函数将会使用Canny边缘检测来排除边缘过多或过少的区域,因此这些区域通常不会是人脸所在区域;
    参数6、7:minSize和maxSize用来限制得到的目标区域的范围。
    */

    if(srcImage.data == nullptr) return;
    // 把 OpenCV里面的Mat数据格式(BGR),转qt里面的QImage(RGB)
    cvtColor(srcImage,srcImage, COLOR_BGR2RGB);    // 将一种颜色空间的图像转换为另一种颜色空间的图像
    QImage image(srcImage.data, srcImage.cols, srcImage.rows, srcImage.step1(), QImage::Format_RGB888);
    QPixmap mmp = QPixmap::fromImage(image);



    ui->videolb->setPixmap(mmp);
}

void MainWindow::timer_connect()
{
    msocket.connectToHost("127.0.0.1",9898);
    qDebug()<<"正在连接服务器";
}

void MainWindow::stop_connect()
{
    mtimer.stop();  // 停止定时器
    qDebug()<<"成功连接服务器";
}

void MainWindow::start_connect()
{
    mtimer.start(5000);  // 启动定时器
    qDebug()<<"断开连接";

}






mainwindow.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>674</width>
    <height>480</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>客户端</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QWidget" name="widget" native="true">
    <property name="geometry">
     <rect>
      <x>0</x>
      <y>0</y>
      <width>401</width>
      <height>371</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true"/>
    </property>
    <widget class="QLabel" name="headpiclb">
     <property name="geometry">
      <rect>
       <x>100</x>
       <y>80</y>
       <width>200</width>
       <height>200</height>
      </rect>
     </property>
     <property name="styleSheet">
      <string notr="true">border-image: url(:/crc2.png);
</string>
     </property>
     <property name="text">
      <string/>
     </property>
    </widget>
    <widget class="QLabel" name="videolb">
     <property name="geometry">
      <rect>
       <x>0</x>
       <y>0</y>
       <width>401</width>
       <height>371</height>
      </rect>
     </property>
     <property name="text">
      <string/>
     </property>
    </widget>
    <zorder>videolb</zorder>
    <zorder>headpiclb</zorder>
   </widget>
   <widget class="QWidget" name="widget_2" native="true">
    <property name="geometry">
     <rect>
      <x>30</x>
      <y>390</y>
      <width>300</width>
      <height>40</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">background-color: rgb(207, 185, 255);
background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(9, 41, 4, 255), stop:0.085 rgba(2, 79, 0, 255), stop:0.19 rgba(50, 147, 22, 255), stop:0.275 rgba(236, 191, 49, 255), stop:0.39 rgba(243, 61, 34, 255), stop:0.555 rgba(135, 81, 60, 255), stop:0.667 rgba(121, 75, 255, 255), stop:0.825 rgba(164, 255, 244, 255), stop:0.885 rgba(104, 222, 71, 255), stop:1 rgba(93, 128, 0, 255));</string>
    </property>
    <widget class="QLabel" name="label">
     <property name="geometry">
      <rect>
       <x>60</x>
       <y>5</y>
       <width>30</width>
       <height>30</height>
      </rect>
     </property>
     <property name="styleSheet">
      <string notr="true">border-image: url(:/yes.jpg);</string>
     </property>
     <property name="text">
      <string/>
     </property>
    </widget>
    <widget class="QLabel" name="label_2">
     <property name="geometry">
      <rect>
       <x>110</x>
       <y>5</y>
       <width>80</width>
       <height>30</height>
      </rect>
     </property>
     <property name="font">
      <font>
       <family>Arial</family>
       <pointsize>14</pointsize>
      </font>
     </property>
     <property name="text">
      <string>认证成功</string>
     </property>
    </widget>
   </widget>
   <widget class="QWidget" name="widget_3" native="true">
    <property name="geometry">
     <rect>
      <x>420</x>
      <y>70</y>
      <width>250</width>
      <height>360</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">QWidget{
	border:1px solid #313238;
	background-color: rgb(30, 47, 49);
}
QWidget#label_5 {
    border-radius: 50%;
}</string>
    </property>
    <widget class="QLabel" name="label_4">
     <property name="geometry">
      <rect>
       <x>50</x>
       <y>10</y>
       <width>161</width>
       <height>31</height>
      </rect>
     </property>
     <property name="font">
      <font>
       <family>Arial</family>
       <pointsize>16</pointsize>
      </font>
     </property>
     <property name="cursor">
      <cursorShape>ArrowCursor</cursorShape>
     </property>
     <property name="styleSheet">
      <string notr="true">color: rgb(255, 255, 255);</string>
     </property>
     <property name="text">
      <string>识别测试系统</string>
     </property>
     <property name="alignment">
      <set>Qt::AlignCenter</set>
     </property>
    </widget>
    <widget class="QLabel" name="label_5">
     <property name="geometry">
      <rect>
       <x>60</x>
       <y>40</y>
       <width>145</width>
       <height>145</height>
      </rect>
     </property>
     <property name="styleSheet">
      <string notr="true">background-color: rgb(23, 37, 39);</string>
     </property>
     <property name="text">
      <string/>
     </property>
    </widget>
    <widget class="QWidget" name="layoutWidget">
     <property name="geometry">
      <rect>
       <x>10</x>
       <y>190</y>
       <width>201</width>
       <height>151</height>
      </rect>
     </property>
     <layout class="QVBoxLayout" name="verticalLayout">
      <item>
       <widget class="QWidget" name="widget_4" native="true">
        <property name="styleSheet">
         <string notr="true">color: rgb(255, 255, 255);</string>
        </property>
        <widget class="QWidget" name="layoutWidget">
         <property name="geometry">
          <rect>
           <x>10</x>
           <y>10</y>
           <width>181</width>
           <height>22</height>
          </rect>
         </property>
         <layout class="QHBoxLayout" name="horizontalLayout" stretch="1,3">
          <item>
           <widget class="QLabel" name="label_6">
            <property name="enabled">
             <bool>true</bool>
            </property>
            <property name="styleSheet">
             <string notr="true">color: rgb(82, 25, 255);</string>
            </property>
            <property name="text">
             <string>编号</string>
            </property>
            <property name="alignment">
             <set>Qt::AlignCenter</set>
            </property>
           </widget>
          </item>
          <item>
           <widget class="QLabel" name="label_7">
            <property name="enabled">
             <bool>false</bool>
            </property>
            <property name="styleSheet">
             <string notr="true">font: 12pt &quot;Arial&quot;;</string>
            </property>
            <property name="text">
             <string>010001</string>
            </property>
            <property name="alignment">
             <set>Qt::AlignCenter</set>
            </property>
           </widget>
          </item>
         </layout>
        </widget>
       </widget>
      </item>
      <item>
       <widget class="QWidget" name="widget_5" native="true">
        <property name="styleSheet">
         <string notr="true">color: rgb(255, 255, 255);</string>
        </property>
        <widget class="QWidget" name="layoutWidget">
         <property name="geometry">
          <rect>
           <x>10</x>
           <y>10</y>
           <width>181</width>
           <height>22</height>
          </rect>
         </property>
         <layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,3">
          <item>
           <widget class="QLabel" name="label_8">
            <property name="enabled">
             <bool>true</bool>
            </property>
            <property name="styleSheet">
             <string notr="true">color: rgb(82, 25, 255);</string>
            </property>
            <property name="text">
             <string>姓名</string>
            </property>
            <property name="alignment">
             <set>Qt::AlignCenter</set>
            </property>
           </widget>
          </item>
          <item>
           <widget class="QLabel" name="label_9">
            <property name="enabled">
             <bool>false</bool>
            </property>
            <property name="styleSheet">
             <string notr="true">font: 12pt &quot;Arial&quot;;</string>
            </property>
            <property name="text">
             <string>010001</string>
            </property>
            <property name="alignment">
             <set>Qt::AlignCenter</set>
            </property>
           </widget>
          </item>
         </layout>
        </widget>
       </widget>
      </item>
      <item>
       <widget class="QWidget" name="widget_6" native="true">
        <property name="styleSheet">
         <string notr="true">color: rgb(255, 255, 255);</string>
        </property>
        <widget class="QWidget" name="layoutWidget_2">
         <property name="geometry">
          <rect>
           <x>10</x>
           <y>10</y>
           <width>181</width>
           <height>22</height>
          </rect>
         </property>
         <layout class="QHBoxLayout" name="horizontalLayout_3" stretch="1,3">
          <item>
           <widget class="QLabel" name="label_10">
            <property name="enabled">
             <bool>true</bool>
            </property>
            <property name="styleSheet">
             <string notr="true">color: rgb(82, 25, 255);</string>
            </property>
            <property name="text">
             <string>部门</string>
            </property>
            <property name="alignment">
             <set>Qt::AlignCenter</set>
            </property>
           </widget>
          </item>
          <item>
           <widget class="QLabel" name="label_11">
            <property name="enabled">
             <bool>false</bool>
            </property>
            <property name="styleSheet">
             <string notr="true">font: 12pt &quot;Arial&quot;;</string>
            </property>
            <property name="text">
             <string>010001</string>
            </property>
            <property name="alignment">
             <set>Qt::AlignCenter</set>
            </property>
           </widget>
          </item>
         </layout>
        </widget>
       </widget>
      </item>
      <item>
       <widget class="QWidget" name="widget_7" native="true">
        <property name="styleSheet">
         <string notr="true">color: rgb(255, 255, 255);</string>
        </property>
        <widget class="QWidget" name="layoutWidget_3">
         <property name="geometry">
          <rect>
           <x>10</x>
           <y>10</y>
           <width>181</width>
           <height>22</height>
          </rect>
         </property>
         <layout class="QHBoxLayout" name="horizontalLayout_4" stretch="1,3">
          <item>
           <widget class="QLabel" name="label_12">
            <property name="enabled">
             <bool>true</bool>
            </property>
            <property name="styleSheet">
             <string notr="true">color: rgb(82, 25, 255);</string>
            </property>
            <property name="text">
             <string>时间</string>
            </property>
            <property name="alignment">
             <set>Qt::AlignCenter</set>
            </property>
           </widget>
          </item>
          <item>
           <widget class="QLabel" name="label_13">
            <property name="enabled">
             <bool>false</bool>
            </property>
            <property name="styleSheet">
             <string notr="true">font: 12pt &quot;Arial&quot;;</string>
            </property>
            <property name="text">
             <string>010001</string>
            </property>
            <property name="alignment">
             <set>Qt::AlignCenter</set>
            </property>
           </widget>
          </item>
         </layout>
        </widget>
       </widget>
      </item>
     </layout>
    </widget>
   </widget>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>


在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

举报

相关推荐

0 条评论