背景

学习了一下OpenCV,熟悉了一点基础概念,就寻找了一下单片机上能否支持人脸识别,用来做一些小玩意。
结果还真发现了一个模块叫ESP32-CAM。ESP32-CAM算得上是一款最便宜的支持人脸识别的单片机开发板了,性能算是单片机里相当不错的了,虽然也只是勉强支持了人脸识别。但是它的优势也是巨大的,就是价格,太便宜了!!

并且在B站上看到了这位大佬的作品:

基于esp32cam人脸识别开锁完整教程&独家教程

于是也来学一下这个模块的使用。顺便问一下
几十块钱的人脸识别门锁,你敢不敢用。

不过可以拿来给孩子做个玩具。

软硬件准备

  • 硬件方面

淘宝了一个带底座的ESP32-CAM模块,这个底座主要就是解决了供电和烧录,直接插上就能连接电脑了。

  • 软件方面

参照使用手册,搭建了arduino的开发环境,安装了最新的ESP32支持包,可以跑一下官方的范例,能够进行人脸识别。买开发板都会赠送这个教程,这里就不细说了。

不过官方的范例,代码有些混乱,还是大佬开源的这版代码看着逻辑比较清晰。

详解人脸识别门锁

视频中的大佬将他的代码都奉献出来了,在此表达感谢,大家可以去支持一下。

代码可以下载下来,自己进行一下理解。

不过大佬的代码在我这里运行的时候,会报错,fr_flash的错误,这个我还没找到问题原因,可能就是无法将识别出来的人脸数据,存储起来,导致,每次重启都需要重新录入人脸。

先讲一下人脸识别的关键点。
首先是获取视频,使用的是下面的接口

fb = esp_camera_fb_get();

然后将视频转化为RGB888,使用的是下面的接口

fmt2rgb888(fb->buf, fb->len, fb->format, out_res.image);

人脸的操作,分为了检测(查看有没有人脸),录入(将人脸的特征值存储下来),和识别(识别摄像头拍摄到的人脸是不是在库中)。三种操作都需要进行人脸检测。使用到的接口是

out_res.net_boxes = face_detect(image_matrix, &mtmn_config);

然后将人脸对齐

align_face(out_res.net_boxes, image_matrix, aligned_face)

提取特征值

out_res.face_id = get_face_id(aligned_face);

注意,这个face_id就是最最核心的数据,是你人脸的特征值。有了这个数据,你就可以进行人脸的判断了。
如果是录入,就需要将这个数据进行存储;
如果是识别,就需要将这个数据与已经存储的特征进行对比,符合就说明拍摄到了对的人。
特征对比的核心函数如下

face_id_node *f = recognize_face_with_name(&st_face_list, out_res.face_id);

其中st_face_list就是一个链表,里面的数据就是已经存储好的face_id。

整个代码思路理清之后,就容易修改了。我们来看一下这个face_id的数据是什么结构。

typedef struct tag_face_id_node
{struct tag_face_id_node *next;           /*!< next face id node */char id_name[ENROLL_NAME_LEN];           /*!< name corresponding to the face id  */dl_matrix3d_t *id_vec;                   /*!< face id */
} face_id_node;typedef struct
{int w;        /*!< Width */int h;        /*!< Height */int c;        /*!< Channel */int n;        /*!< Number of filter, input and output must be 1 */int stride;   /*!< Step between lines */fptp_t *item; /*!< Data */
} dl_matrix3d_t;

可以看出来这个特征值,就是下面那个结构。
我尝试着打印了一个组数据,发现item为一个512长度的float数组。这就是你人脸的特征,应该也算是你的生物指纹之一吧,这么轻松就能获取到了。

flash问题解决

那么就来解决一下flash中没有成功存储face_id的问题吧,
启动的时候,系统调用了这个函数

read_face_id_from_flash_with_name(&st_face_list);

应该就是报错的原因,那么我们不用这个flash存储了,改用数组或者文件直接存储即可。
正好有内存卡可以使用。参考的代码就是SD_MMC这个范例代码。
大概原理就是将用户数据建成目录,每个用户录入一组特征值,即faceID,录入的时候,分别存储到对应目录中。
开机启动的时候,通过读取每个目录,形成核心对比数据,放在st_face_list变量中。

两个核心函数,保存ID

void SD_save_face_id(char* name,int number,dl_matrix3d_t *face_id)
{int num=0;char filename[32]={0};unsigned char* data=NULL;num=(face_id->w)*(face_id->h)*(face_id->c)*(face_id->n);sprintf(filename,"/%s",name);SD_createDir(SD_MMC,filename);sprintf(filename,"/%s/1.txt",name);data=(unsigned char*)face_id->item;SD_writeFile(SD_MMC, filename, data,num*4);
}

读出ID

void SD_read_all_face_id(fs::FS &fs)
{st_face_list.count=0;st_face_list.head=NULL;st_face_list.tail=NULL;st_face_list.confirm_times=5;face_id_node* faceidnode_now=NULL;File root = fs.open("/");if(!root){Serial.println("Failed to open directory");return;}if(!root.isDirectory()){Serial.println("Not a directory");return;}File file = root.openNextFile();while(file){if(file.isDirectory()){face_id_node* faceidnode=NULL;char fullname[64]={0};Serial.printf("find user:[%s]\n",file.name());sprintf(fullname,"%s/1.txt",file.name());File tryopen = fs.open(fullname);if(!tryopen){Serial.printf("user has no face id[%s]\n",fullname);file = root.openNextFile();continue;}else{faceidnode = (face_id_node*)dl_lib_calloc(1, sizeof(face_id_node), 0);if(faceidnode){dl_matrix3d_t* id_vec;strcpy(faceidnode->id_name,file.name()+1);id_vec= (dl_matrix3d_t*)dl_lib_calloc(1, sizeof(dl_matrix3d_t), 0);if(id_vec){float* face=NULL;faceidnode->id_vec=id_vec;faceidnode->next=NULL;id_vec->w=1;id_vec->h=1;id_vec->c=512;id_vec->n=1;id_vec->stride=512;face= (float*)dl_lib_calloc(512, sizeof(float), 0);tryopen.read((unsigned char*)face,512*4);id_vec->item=face;if(st_face_list.head==NULL){st_face_list.head=faceidnode;st_face_list.tail=faceidnode;faceidnode_now = faceidnode;}else{st_face_list.tail=faceidnode;faceidnode_now->next=faceidnode;faceidnode_now=faceidnode;}st_face_list.count++;}}}} file = root.openNextFile();}
}

其他操作函数最终见下载,都放上来就太多了。

来吧 展示

烧录好之后,访问web。

可以先录入人脸
输入名字,点击ADD USER,我这里用一个图片代替一下。

然后点击ACCESS CONTROL,进行人脸识别


识别成功,会提示DOOR OPEN FOR test。
重启之后,信息不会再丢失。
有人问,这个美女是谁啊,那有点不好意思了,这是个男的。

卡顿问题

这个模块的信号可能不太好,距离路由器远了之后,就会很卡,很奇怪的是,我家用了一个路由器进行了信号的增强覆盖,这个模块接到扩展的路由器上,一样也会变的卡顿。
所以我就单独用了一个路由器,将摄像头模块和电脑组成了一个局域网,而且得把模块放在路由器附近,这样就不再卡顿了。

后续考虑是不是改一下用外置天线,看看是不是天线的问题导致的。

用灯代替门锁

这个模块RST按钮旁边有一个板载红色LED。该LED内部连接到GPIO 33。您可以使用此LED指示正在发生的事情。例如,如果连接了Wi-Fi,则LED为红色,反之亦然。
该LED具有反向逻辑,因此您发送了一个 LOW 信号打开它 HIGH 信号将其关闭。

所以可能模拟红灯亮起,表示开锁,同理这个GPIO可以让你用来触发一些别的操作而不仅限于开锁,开灯,开水龙头,想开啥开啥。

代码下载

大佬的代码,还请去B站观看一下,然后在评论区即可看到下载链接。
我的代码下载
改这个存储用了一天的时间,所以还是用了点小心机。

结束语

你们知道人生的意义是什么吗?分享给你们一张图吧

其实我觉得人生有意义,我们的意义,存在于我们对别人的意义。

单片机开发---基于ESP32-CAM的人脸识别应用相关推荐

  1. 基于ESP32 CAM的人脸识别考勤系统

    概述:使用 ESP32 CAM 的人脸识别考勤系统 本教程介绍了使用ESP32 CAM 模组的人脸识别考勤系统.我们将为此应用程序使用OpenCV和Visual Studio .OpenCV 是一个开 ...

  2. 开发基于深度学习的人脸识别【考勤/签到】系统

    开发基于深度学习的人脸识别[考勤/签到]系统 人脸识别介绍 平台环境需求 技术点 系统流程 细节设计 人脸检测 人脸关键点定位 人脸特征提取 模型的训练 模型的部署 MySQL数据库的使用 MFC工程 ...

  3. 手把手教你开发基于深度学习的人脸识别【考勤/签到】系统

    人脸识别介绍 平台环境需求 技术点 系统流程 细节设计 人脸检测 人脸关键点定位 人脸特征提取 模型的训练 模型的部署 MySQL数据库的使用 MFC工程的搭建 软件使用 人脸识别介绍 人脸识别技术是 ...

  4. android人脸识别demo_C#开发实录:基于免费SDK实现人脸识别应用开发

    随着人脸识别技术应用范围不断扩展,如何在Windows C#上基于免费SDK实现人脸识别应用开发,正成为开发者们关心的话题之一. 对于该需求,我推荐虹软视觉开放平台的ArcFace 3.0,免费.离线 ...

  5. 【优秀课设】基于OpenCV-Python的树莓派人脸识别及89C52单片机控制系统设计(指定照片进行识别、遍历目录下所有照片依次识别)

    基于OpenCV-Python的树莓派人脸识别及89C52单片机控制系统设计 (指定照片进行识别) 参照之前的文章所改进 增加视频随时标注功能 https://blog.csdn.net/weixin ...

  6. 【优秀课设】基于OpenCV的Python人脸识别、检测、框选(遍历目录下所有照片依次识别 视频随时标注)

    基于OpenCV的Python人脸识别.检测.框选 (遍历目录下所有照片依次识别 视频随时标注) 移步: https://blog.csdn.net/weixin_53403301/article/d ...

  7. 基于全局信息的人脸识别总结

    一.           课题名称 基于全局信息的人脸识别算法研究 二.           课题的提出 在当今社会中,身份确认具有十分重要的价值.随着网络技术的发展,信息安全也显示出了前所未有的重要 ...

  8. 《繁凡的论文精读》(一)CVPR 2019 基于决策的高效人脸识别黑盒对抗攻击(清华朱军)

    点我一文弄懂深度学习所有基础和各大主流研究方向! <繁凡的深度学习笔记>,包含深度学习基础和 TensorFlow2.0,PyTorch 详解,以及 CNN,RNN,GNN,AE,GAN, ...

  9. 基于PYQT编写一个人脸识别软件

    转载请注明出处:http://blog.csdn.net/hongbin_xu 或 http://hongbin96.com/ 文章链接:http://blog.csdn.net/hongbin_xu ...

  10. 身份验证错误错误指定的句柄无效_基于 Web 端的人脸识别身份验证「实践」

    作者:沫沫 政采云前端团队 转发链接:https://mp.weixin.qq.com/s/fRDpXixnLIy9c0Uh2tMezQ 前言 近些年来,随着生物识别技术的逐渐成熟,基于深度学习的人脸 ...

最新文章

  1. mysql-5.7.24-winx64忘记密码该咋解决
  2. PyQt5教程——组件 Ⅱ(八)
  3. 提高使用比特币的匿名性
  4. 归算法及经典递归例子代码实现
  5. 矩阵分析与多元统计11 广义vec算子与devec算子
  6. Android有返回值的Activity
  7. Android之webview长按超链接类型获取链接文字及url、长按图片链接类型分别获取图片和链接的url
  8. kmp学英语必须设置
  9. 中国移动携手华为完成5G话音的全部功能测试
  10. vscode ---- 插件
  11. validate中remote的用法
  12. Fluter拓展 图标库
  13. python Udp与Tcp
  14. 雷电4模拟器安装xposed框架(2022年)
  15. Excel文本取首字母(包括繁体)VBA开发工具
  16. 明日复明日,明日何其多;我生待明日,万事成蹉跎
  17. 软件开发、软件设计培训笔记
  18. Spring Batch(三) 详细介绍Job Launcher、ItemReader、ItemProcessor、ItemWriter各个实现类和用途
  19. js对内容进行编码(富文本编辑器使用居多)
  20. 同样是IT行业,测试和开发薪资真有这么大差别?

热门文章

  1. 趣谈java工厂模式
  2. 王者荣耀装备测试软件,王者荣耀里有3个“测试仪”,可以测出辅助玩家的真实水平!...
  3. 暴力破解工具Hydra
  4. 在Windows/Linux下调用API函数实现重启系统
  5. 985档次的院校中相对好考,地理位置佳,准备充分可以搏一搏 ! ! !
  6. 后疫情时代中国零售业转型之路
  7. 删除压缩包文件的压缩密码
  8. python 获取文件CRC值
  9. 电子货架标签----部分特性展示
  10. GAMS中导入Excel数据