【Arm+Qt+Opencv】基于人脸识别考勤系统实战

1.编译时问题汇总

windows下编译opencv-4.5.4

opencv-4.5.4编译
问题1:配套使用opencv-4.5.4,opencv_contrib-4.5.4,cmake3.22.3问题会少一点
问题2:在windows下哪里执行该命令
在这里插入图片描述
解决:
在这里插入图片描述
问题3:在对应cmake中搜索不到要修改的配置
解决:自己添加
在这里插入图片描述
在这里插入图片描述

windows下编译Seetaface2

看这个

ubuntu下编译opencv-4.5.4

问题1:
出现在编译库的时候使用make -j4 make出错时
解决:
扩大虚拟机内存
在这里插入图片描述
调整后重启虚拟机
问题2:
在这里插入图片描述
1.没连接摄像头 2.在cmake 之前必须安装依赖库
解决:
看这篇
连接摄像头
在这里插入图片描述
问题3:
在这里插入图片描述
找不到这两个cmake文件路径
在这里插入图片描述
在这里插入图片描述

ubuntu下编译安装opencv_contrib-4.5.4

未出现问题

ubuntu下编译安装Seetaface2

看老师讲的直接
也会出现两个cmake文件找不到,添加cmake路径即可

2.Windows下测试opencv和Seetaface

头文件路径/库文件路径
在这里插入图片描述
测试代码
在这里插入图片描述

验证成功
在这里插入图片描述

3.ubuntu下测试opencv和seetaface

将windows下刚才的qt文件复制到共享目录下面去
在这里插入图片描述

共享目录在ubuntu中会放到ubuntu的/mnt/hgfs下

ubuntu下库文件/头文件路径指明
在这里插入图片描述

测试代码
在这里插入图片描述
问题1:
terminate called after throwing an instance of ‘cy::xception’
what(): 0penc!(4.5.4) /home/xyd/face/opencv-4.5.4/modules/core/src/array.cp:2494: error: (-206:Bad flag (paraneter or structure field)) unrecognized or umsuported array
type in function ‘cvGetMat’
解决:
将资源路径改为绝对路径(测试代码中已经修改)
问题2:
ubuntu安装完qt后找不到图标
解决:
ubuntu安装完qt后找不到图标

问题3:
在ubuntu下测试opencv和seetaface时如果出现cannot find -lgl问题
解决:
cannot find -lgl问题
问题4:
在ubuntu下qt测试opencv和seetaface的时候不知道指定opencv的哪个库
解决:
在这里插入图片描述
在这里插入图片描述

验证成功
在这里插入图片描述

4.摄像头数据在Qt界面上实时显示

头文件/库路径包含
在这里插入图片描述

face.h
在这里插入图片描述
face.cpp
在这里插入图片描述

摄像头数据在Qt界面实时显示

5.opencv检测人脸,并跟随

使用到opencv中的级联分类器,通过导入训练好的级联分类器文件,将从摄像头读取的一帧视频数据使用detectMultiScale函数来检测人脸,如果检测到人脸的话,就会用一个矩形来表示人脸的位置,并把该矩形位置信息放到vector中,如果该容器中有数据,就说明检测到了人脸
在这里插入图片描述
如果第一个参数为灰度图像的话会加快检测速度,第二个参数是检测到人脸的位置信息就会放到该容器中,后面的参数都可以缺省不用管。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们可以先将srcimage转化为灰度图像就可以加快检测速度
在这里插入图片描述
在这里插入图片描述

6.考勤中断网络编程实现断线重连

使用到网络编程,添加network
在这里插入图片描述
使用QTimer定时器实现断线重连,使用tcp连接服务器
需要添加头文件
在这里插入图片描述
定义两个变量
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
使用ipconfig指令查看ip地址(192.168.0.109)
在这里插入图片描述
使用该软件来做测试

在这里插入图片描述
在这里插入图片描述
作为tcp服务器对7777端口做监听,等待客户端连接
在这里插入图片描述

测试:

客户端断线重连服务器

7.人脸识别服务器网络基础实现

在Qt下建立tcp服务器,新建一个工程,因为要用到网络编程,所以用到网络模块,添加netwok
在这里插入图片描述
需要要建立tcp服务器以及网络编程,用到的头文件有
QTcpServer, QTcpSocket
在这里插入图片描述
创建两个变量来使用到网络编程
在这里插入图片描述
首先服务器进行监听任意ip地址上的7777端口,如果有客户端连接服务器的话,server变量会发送一个newconnection的信号,然后通过server.nextPendingConnection();将服务端发过来的信息通过tsocket套接字来访问,当客户端有信息发过来,tsocket会发出readyread信号,如果接收到该信号的话,我们就来处理数据,通过tsocket

服务器测试

8.考勤终端人脸数据的压缩与发送

当考勤机客户端检测到人脸的时候
在这里插入图片描述
也就是faceRects.size()>0的时候,在这个if语句里面,将视频一帧数据做编码,
使用到cv::imencode函数

 std::vector<uchar>buf;// 存放转化后的jpg格式的视频一帧数据cv::imencode(".jpg",srcimage,buf);//编码转化----->将srcimage图像编码转化为jpg结构,存放在buf中

srcimage变量中保存的是视频一帧数据的Mat格式,第一个参数为要编码为的格式,第二个参数为要被编码的图片变量,第三个参数为转化为jpg格式后输出到buf中
然后将buf的vector< uchar >转化为QByteArray ,并获取编码后数据大小

QByteArray byte((const char*)buf.data(),buf.size());//将字符串转化为QByteArray放在Byte中quint64 backsize=byte.size();//获取编码 后数据的大小

然后通过QDataStream,相当于一个缓冲区,可以理解为一个序列化过程,该缓冲区前面是编码后数据的大小,后面是编码后的数据

QByteArray senddata;
QDataStream stream(&senddata,QIODevice::WriteOnly);//以写 字节流方式打开 senddatastream.setVersion(QDataStream::Qt_5_14);//设置版本,不同版本有不同的序列方式stream<<backsize<<byte;//构建写入格式相当于sprintf

然后发送出去

msocket.write(senddata);//向服务器发送视频数据

在这里插入图片描述

9.服务器端接收人脸数据并且显示

上一步我们将数据从客户端发送到服务端,发送到服务端这边(数据大小+数据)

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

将tsocket和stream绑定说明tsocket接收到的数据会放在stream的缓冲区

 if(bsize==0){if(tsocket->bytesAvailable()<(qint64)sizeof(bsize)) return ;   //如果数据有丢包,就不接收该图片数据stream>>bsize;//相当于反序列化取出数据大小放在bsize中}
  if(tsocket->bytesAvailable()<bsize)//如果接收数据大小<实际数据大小{return ;//不接收}
 QByteArray data;//接收来自客户端的一帧视频放在data中stream>>data;bsize=0;if(data.size()==0)//发送来的没数据{return ;}

接着通过Qpixmap来显示出来

       QPixmap mp;mp.loadFromData(data,"jpg");//data的格式为jpgmp=mp.scaled(ui->buffer->size());//调整大小和标签大小一样ui->buffer->setPixmap(mp);//显示

在这里插入图片描述

10.人脸识别模块封装(注册和查询)

上一个步骤将人脸发到了服务端这边并且进行了显示,该步骤是要封装一个引擎库方便注册和查询
创建一个c++类,继承QObeject
在这里插入图片描述
包含头文件FaceEngine.h,该头文件如果找不到的话去
在这里插入图片描述
将其复制一份
在这里插入图片描述
在这里插入图片描述
在构造函数中初始化引擎库模型
在这里插入图片描述
在这里插入图片描述
在析构函数中将new的空间释放掉,防止内存泄漏
在这里插入图片描述
人脸注册
在这里插入图片描述
人脸查找
在这里插入图片描述
在这里插入图片描述
人脸库中只保存了人脸信息与人脸id的对应关系,当注册时,simage中保存的人脸信息在人脸库中如果没有,就进行注册,id和人脸信息对应,而这个人脸信息只包含图像信息,而个人的姓名,性别信息,需要我们自己创建一个数据库来保存这些
在这里插入图片描述
三个模型下载链接
链接
在该链接中的readme.md文件里面

11.Qt数据库和表格创建

上一主题创建的人脸库中只有人脸库和人脸id,我们还要创建两个数据库来更完善员工信息,第一个是员工信息表,第二个为考勤表,员工信息表中包含下面内容
在这里插入图片描述

考勤表包括下面内容

在这里插入图片描述
在这里插入图片描述
在.pro中记得加sql
在这里插入图片描述

在调用界面的时候就开始创建这两个数据库
在这里插入图片描述
在这里插入图片描述
我们可以使用sqlite expert软件看一下建表情况
在这里插入图片描述
点击file
在这里插入图片描述
打开该路径下的server.db
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
创建成功

12.员工信息注册界面设计

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

13.员工信息录入到数据库

重置按钮的实现:
将所以的输入框内容全部都清除对按钮转到槽,
实现对所有的输入框全部清除
在这里插入图片描述
添加头像按钮实现:
使用QFiledialog中的getOpenFileName获取头像路径放在QString中,然后通过setText函数将头像路径显示出来,然后通过QPixmap进行显示在标签上
在这里插入图片描述
注册按钮的实现
在注册按钮中需要实现以下步骤
在这里插入图片描述

1.通过照片,结合qobjectface模块得到faceid,并且把所以注册进人脸库中的人脸图片都保存在当前目录下的data命令下
对应的代码为
在这里插入图片描述

2.将个人信息存储到 数据库中employee表
在这里插入图片描述

QSqlTableModel用来充当一个表模型,该表使用数据库中的哪个表,QSqlRecord作为要插入表数据的记录,然后将记录插入到数据库表中,如果成功就进行提交插入记录,即可在数据库表中查看到记录
对应代码如下
在这里插入图片描述
问题1图片路径中不能有中文,如果有中文的话就读不到图片使用imread,imwrite函数,导致识别不到人脸,注册就会返回-1
问题2在构造函数需要加载人脸库,要不然每次注册人脸库,人脸库就是空的
返回0,并且注册失败
在这里插入图片描述

问题3如果注册的时候只返回1的话,可能是封装好的注册函数没有return
在这里插入图片描述
效果演示:

员工信息插入数据库

14.员工信息注册模块头像采集

该部分包括打开摄像头按键实现以及拍照按键的实现
打开摄像头按键实现思路,当按下一次摄像头时,该按键上的字修改为关闭摄像头,使用opencv中的cv::VideoCapture来打开摄像头,并且启动定时器,定时器里完成(),当按下该按钮(此时按钮上的字为关闭摄像头),按钮上的字变成打开摄像头,关闭摄像头,关闭定时器,显示图片的地方清除掉
在这里插入图片描述
在这里插入图片描述
定时器的中断函数中需要完成获取摄像头一帧图像,然后把opencv里面的Mat格式数据(BGR)转化为qt中的Qimage(RGB),通过QPixmap显示在标签上
在这里插入图片描述

拍照按键的实现:
实现思路,将cv::Mat image变量定义为类内私有变量,当点击拍照的时候,定义图片要保存的路径,将image保存到该路径下,关闭摄像头,关闭定时器,将保存路径显示在图片路径dir下
在这里插入图片描述
演示:

员工信息注册模块头像采集

15.接收客户端人脸数据并且识别出人脸id

在这里插入图片描述
在之前我们已经将从客户端接收到的编码过的图片信息放在data中,此时我们需要对data进行解码,然后调用封装好的face_query函数即可。
在这里插入图片描述
根据这个构建我们要填的参数
flag的话和imread的flag是一样的
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这里使用查找函数速度会非常的慢,会占用服务端的主线程,导致很卡,后面优化将该查找函数用多线程来完成。

16.识别人脸ID查询数据个人信息

上一个步骤已经查找出人脸ID,这一步我们根据人脸ID在数据库中查找该人脸ID对应的基本信息,并且返回到客户端,
使用#include <QSqlTableModel> #include <QSqlRecord>
这两个头文件
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
需要发送给客户端这几个信息
在这里插入图片描述
发送信息给客户端
在这里插入图片描述
客户端接收该信息:
在这里插入图片描述
在这里插入图片描述

信息打印出来
在这里插入图片描述
识别并接收到数据

在这里插入图片描述

17.考勤机人脸采集发送次数优化

在之前说过在服务端将客户端传过来的人脸进行在人脸库中查找时会很费时间,并且出现阻塞,因为考勤机人脸每次捕捉到人脸的话,就会发送到服务端,就直接查找,如果我们能减少发送次数的话就会减少查找次数,来进一步优化
通过定义一个变量来表示识别到人脸的次数
客户端:
在这里插入图片描述
对flag赋值
在这里插入图片描述
在这里插入图片描述

18.服务器优化用线程实现人脸识别

因为查找函数很费时间,如果在主线程中完成的话,就会造成卡顿,所以创建一个线程来进行查找
1.创建一个线程,并把能使用人脸查找的对象传到创建的线程中去
在这里插入图片描述

2.创建一个信号
如果this发出调用查找函数的信号的话,收到信号的就可以去执行查找函数
在这里插入图片描述
使用connect进行关联
在这里插入图片描述

调用该函数
在这里插入图片描述
该函数如何将faceid返回回去呢?
也可以通过信号
在这里插入图片描述

当识别成功了并且人脸辨识度大于你设置的值
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

19.考勤机终端json数据接收与json解析和显示

之前已经debug出该人脸的需要显示的信息,现在我们只需要通过json进行解析即可
需要的头文件
在这里插入图片描述
在这里插入图片描述

先隐藏认证成功
在这里插入图片描述

在这里插入图片描述
还要显示图片
我们可以在发送图片到服务端的时候,将图片保存在当前目录下,也就是在下面这个地方
在这里插入图片描述
在这里插入图片描述
演示:

json解析

20.考勤信息和员工信息查询模块设计与实现

服务端新添加一个qt设计师类
在这里插入图片描述

使用数据库使用下面头文件
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

21.考勤数据实时录入到数据库

当服务端调用线程去查找人脸时,如果返回faceid大于0,我们就返回其相关信息,同时往考勤表中插入数据步骤如下
在这里插入图片描述
注意:这里识别一个人的人脸只需要进行一次打卡
在这里插入图片描述
修改flag=-2
考勤数据库演示:

22.服务端用QTabWidget整合

在这里插入图片描述
注释掉注册界面和查询界面
界面这样设置
在这里插入图片描述
将注册和考勤提升,类名为对应qt设计界面的类名即可
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
整体联调:

整体联调

后面可以在板子上跑,等我买板子!!!!!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/39178.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux与HTTP中的Cookie和Session

HTTP中的Cookie和Session 本篇介绍 前面几篇已经基本介绍了HTTP协议的大部分内容&#xff0c;但是前面提到了一点「HTTP是无连接、无状态的协议」&#xff0c;那么到底有什么无连接以及什么是无状态。基于这两个问题&#xff0c;随后解释什么是Cookie和Session&#xff0c;以…

【Tauri2】001——安装及运行

前言 笔者其实不想写教程&#xff0c;写教程很麻烦。 但是网上关于Tauri2的教程&#xff0c;要么不全&#xff0c;要么是Tauri1的&#xff0c;真的太少了&#xff0c;虽然有官网&#xff0c;还是太少了。 问Ai&#xff0c;也感觉比较离谱&#xff0c;有很多时候&#xff0c;…

【DFS】羌笛何须怨杨柳,春风不度玉门关 - 4. 二叉树中的深搜

本篇博客给大家带来的是二叉树深度优先搜索的解法技巧,在后面的文章中题目会涉及到回溯和剪枝,遇到了一并讲清楚. &#x1f40e;文章专栏: DFS &#x1f680;若有问题 评论区见 ❤ 欢迎大家点赞 评论 收藏 分享 如果你不知道分享给谁,那就分享给薯条. 你们的支持是我不断创作的…

操作系统导论——第13章 抽象:地址空间

一、早期系统 从内存来看&#xff0c;早期的机器并没有提供多少抽象给用户。基本上&#xff0c;机器的物理内存如图13.1所示 操作系统曾经是一组函数&#xff08;实际上是一个库&#xff09;&#xff0c;在内存中&#xff08;在本例中&#xff0c;从物理地址0开始&#xff09;&…

网络爬虫-2:基础与理论

一.同步加载与异步加载 1.1同步加载定义: 页面所有内容一起加载出来,当某一个数据加载有问题,整个页面就不会加载出来(如HiFiNi音乐网站),所以又叫阻塞模式 1.2爬取步骤: 看netword->document 2.1异步加载定义: 数据是分开加载的,当某一份数据有异常时,不影响其他数据…

【Docker系列五】Docker Compose 简介

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

本地安装deepseek大模型,并使用 python 调用

首先进入 ollama 官网 https://ollama.com/点击下载 下载完成后所有都是下一步&#xff0c;就可以 点击搜索 Models &#xff1a; https://ollama.com/search然后点击下载&#xff1a; 选择后复制: ollama run deepseek-r1:32b例如&#xff1a; 让它安装完成后&#xff1…

【CC2530 教程 二】CC2530定时器实现微秒、毫秒、秒延时函数

目录 一、CC2530定时器&#xff1a; 二、CC2530定时器&#xff1a; &#xff08;1&#xff09;定时器1&#xff08;Timer1&#xff09;&#xff1a; &#xff08;2&#xff09;定时器2&#xff08;Timer2&#xff09;&#xff1a; &#xff08;3&#xff09;定时器3和定时…

23种设计模式-创建型模式-工厂方法

文章目录 简介场景问题1. 直接依赖具体实现2. 违反开闭原则3. 条件分支泛滥4. 代码重复风险 解决根本问题完整类图完整代码说明核心优势代码优化静态配置表动态策略 总结 简介 工厂方法是一种创建型设计模式&#xff0c;它提供了在父类中创建对象的接口&#xff0c;但允许子类…

Umi-OCR- OCR 文字识别工具,支持截图、批量图片排版解析

Umi-OCR 是免费开源的离线 OCR 文字识别软件。无需联网&#xff0c;解压即用&#xff0c;支持截图、批量图片、PDF 扫描件的文字识别&#xff0c;能识别数学公式、二维码&#xff0c;可生成双层可搜索 PDF。内置多语言识别库&#xff0c;界面支持多语言切换&#xff0c;提供命令…

【JavaEE】Mybatis基础使用注解 增删改查操作

目录 一、配置日志二、传递参数 #{}三、增(Insert)四、返回主键Options五、删&#xff08;Delete&#xff09;六、改&#xff08;Update&#xff09;七、查&#xff08;Select&#xff09; 一、配置日志 我们加上下面的代码在配置文件中&#xff0c;那么我们在日志中就可以看到…

4.2、网络安全体系与建设内容

目录 网络安全体系架构网络安全组织安全管理网络安全等级保护2.0等保项目流程等保标准变化等保2.0新增内容等保2.0变化智慧城市安全体系应用参考智能交通网络安全体系应用参考 网络安全体系架构 建设网络安全&#xff0c;要体系化&#xff0c;要从一个整体去做考虑&#xff0c…

TCP协议原理

TCP协议原理 本篇介绍 前面已经基本介绍了TCP编程的接口以及基本的步骤&#xff0c;但是并没有其中的原理进行解释。本篇主要聚焦于TCP原理部分&#xff0c;对TCP中重要的内容进行解释 TCP协议报格式 基本示意图如下&#xff1a; 下面针对每一个字段的作用进行简要的概括&a…

go中的文件、目录的操作

1.文件的概念 文件是数据源(保存数据的地方)的一种,比如大家经常使用的word文档,txt文件,excel文件等。文件最主要的作用就是保存数据,它既可以保存一张图片,也可以保存视频,声音等。 文件在程序中以流的形式来操作的。 流:数据在数据源(文件)和程序(内存)之间…

electron js node vscode 调试electron

用npm会下到home里面不知道为什么可能是淘宝源的问题 --------------------------------- 安装cnpm&#xff08;可选&#xff09; sudo npm install -g cnpm --registryhttps://registry.npmmirror.com下下来还没办法直接用 sudo find / -name "cnpm"nano ~/.bashr…

深度解析 BPaaS:架构、原则与研发模式探索

在当今复杂多变的业务环境下&#xff0c;软件开发面临着诸多挑战&#xff0c;如何有效地管理业务复杂性并实现系统的可扩展性成为关键。BPaaS应运而生&#xff0c;它作为一种创新的理念和架构模式&#xff0c;改变着企业研发的方式。本文将深入探讨 BPaaS 是什么&#xff0c;以…

大模型架构记录2 【综述-相关代码】

一 简单聊天机器人搭建 1.1 openai调用 import os from openai import OpenAI from dotenv import load_dotenv, find_dotenvload_dotenv() client OpenAI()# 打印所支持的模型 model_lst client.models.list()for model in model_lst:print (model.id)# 调用API接口 comp…

三个print优雅打印datetime模块的“时间密码”

三个模块&三条print()&#xff0c;玩转python时间的上上下下&#xff0c;优雅打印“时间密码”。 笔记模板由python脚本于2025-03-23 22:50:43创建&#xff0c;本篇笔记适合正确研究时间/日期的coder翻阅。 【学习的细节是欢悦的历程】 博客的核心价值&#xff1a;在于输出…

【Android】VehiclePropertyAccess引起CarService崩溃

VehiclePropertyAccess引起CarService崩溃 VehiclePropertyAccess VehiclePropertyAccess属性&#xff0c;用于定义车辆属性的访问权限。权限包括 读&#xff1a;READ&#xff0c;只可以读取&#xff0c;不能写入。 VehiclePropertyAccess:READ写&#xff1a;WRITE&#xf…

深入理解traceroute命令及其原理

traceroute 是一个网络诊断工具&#xff08;Windows上叫tracert&#xff09;&#xff0c;用于显示数据包从本地主机到远程主机经过的路由&#xff08;跳数&#xff09;。它可以帮助您了解数据包在网络中的传输路径&#xff0c;以及每跳的延迟情况。这对于网络故障排除、分析网络…