智能家居项目(八)之树莓派+摄像头进行人脸识别
目录
1、编辑Camera.c
2、编辑contrlDevices.h
3、编辑mainPro.c
4、进行编译:
5、运行结果: ./test1
6、项目图片演示
智能家居项目(七)之Libcurl库与HTTPS协议实现人脸识别_Love小羽的博客-CSDN博客
经过上一篇文章,写的代码是在Ubuntu系统中写的,这回把代码搬到树莓派上进行测试
直接上代码
1、编辑Camera.c
#include <stdio.h>
#include <curl/curl.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "contrlDevices.h"#define true 1
#define false 0typedef typedef unsigned int bool;
char buf[10240] = {'\0'};//全局变量,用来接收从OCR后台返回的数据
char* getFace1();
void postUrl();char* getPicBase64FromFile(char *filePath);
struct Devices *addCameraContrlToDeviceLink(struct Devices *phead);size_t readData(void *ptr,size_t size,size_t nmemb,void *stream) //回调函数
{ strncpy(buf,ptr,1024);
}char *getFace1()
{ printf("Taking pictures...\n"); system("raspistill -q 5 -t 1 -o image.jpg"); //-q 是图片质量,在0~100之间,我们调成5,压缩图片质量,生成的照片名字为imag.jpg //-t 是拍照延时,设定1s后拍照 while (access("./image.jpg", F_OK) != 0) ; //判断是否拍照完毕 printf("拍照完成\n"); char *base64BufFaceRec = getPicFromOCRBase641("./image.jpg"); // system("rm image.jpg"); return base64BufFaceRec; //返回刚才拍照的base64}while (access("./image.jpg", F_OK) != 0); //判断是否拍照完毕printf("Photo taking completed\n");char *base64BufFaceRec = getPicBase64FromFile("./image.jpg");return base64BufFaceRec; //返回刚才拍照的base64
}char* getPicBase64FromFile(char *filePath) //获取图片的base64流
{ char *bufPic; char cmd[128] = {'\0'};sprintf(cmd,"base64 %s > tmpFile",filePath); system(cmd);int fd = open("./tmpFile",O_RDWR); int filelen = lseek(fd,0,SEEK_END); lseek(fd,0,SEEK_SET); bufPic =(char *)malloc(filelen+2); memset(bufPic,0,filelen+2); read(fd,bufPic,filelen); close(fd);system("rm -f tmpFile"); return bufPic;
}void postUrl()
{ CURL *curl; CURLcode res; char *postString;char* key = "自行购买翔云平台购买人脸识别后的key";//翔云平台购买人脸识别后的keychar* secret = "自行购买翔云平台购买人脸识别后的secret";//翔云平台购买人脸识别后的secretint typeId = 21;char* format = "xml";char *bufPic1 = getFace1(); char *bufPic2 = getPicBase64FromFile("./5.jpg");int len = strlen(key)+strlen(secret)+strlen(bufPic1)+strlen(bufPic2)+124; //分配空间不够会导致栈溢出postString = (char *)malloc(len); //因为postString是一个指针,不能用sizeof来计算其指向的大小memset(postString,'\0',len);sprintf(postString,"img1=%s&img2=%s&key=%s&secret=%s&typeId=%d&format=%s", bufPic1,bufPic2,key,secret,typeId,format);curl = curl_easy_init();if (curl) { curl_easy_setopt(curl, CURLOPT_POSTFIELDS,postString); // 指定post内容 curl_easy_setopt(curl, CURLOPT_URL, "https://netocr.com/api/faceliu.do"); // 指定url curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,readData); //将返回的http头输出到fp指向的文件 res = curl_easy_perform(curl); //类似于状态码printf("OK:%d\n",res);if(strstr(buf,"是") != NULL) //判断翔云后台返回的字符串中有没有“是”{ printf("the same Person\n");}else{ printf("diff Person\n"); }curl_easy_cleanup(curl); }
}struct Devices cameraContrl = { .deviceName = "camera", .justDoOnce = postUrl,.getFace = getFace1,.getPicBase64FromFile = getPicBase64FromFile,.readData = readData,.next = NULL
};struct Devices *addCameraContrlToDeviceLink(struct Devices *phead)
{ if(phead == NULL){ return &cameraContrl; }else{ cameraContrl.next = phead; phead = &cameraContrl;} return phead;
}
2、编辑contrlDevices.h
//设备工厂
#include <wiringPi.h>
#include <stdlib.h>struct Devices
{char deviceName[128];int status;int pinNum;int (*open)(int pinNum);int (*close)(int pinNum);void (*justDoOnce)(); //用于摄像头char* (*getFace)(); //用于摄像头char* (*getPicBase64FromFile)(); //用于摄像头size_t (*readData)(); //用于摄像头int (*deviceInit)(int pinNum);int (*readStatus)(int pinNum);int (*changeStatus)(int status);struct Devices *next;
};struct Devices* addBathroomLightToDeviceLink(struct Devices *phead);
struct Devices* addUpstairLightToDeviceLink(struct Devices *phead);
struct Devices* addLivingRoomLightToDeviceLink(struct Devices *phead);
struct Devices* addRestaurantLightToDeviceLink(struct Devices *phead);
struct Devices* addFireToDeviceLink(struct Devices *phead);
struct Devices* addCameraContrlToDeviceLink(struct Devices *phead);
3、编辑mainPro.c
#include "contrlDevices.h"
#include "InputCommand.h"
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>struct Devices *pdeviceHead = NULL; //设备工厂
struct InputCommander *pCommandHead = NULL; //指令工厂
struct InputCommander *socketHandler = NULL;
int c_fd;
struct Devices *cameraThrad = NULL;
typedef unsigned int bool;struct Devices* findDeviceByName(char *name,struct Devices *phead)
{struct Devices *tmp = phead;if(phead == NULL){return NULL;}else{while(tmp != NULL){if(strcmp(tmp->deviceName,name) == 0){return tmp;}tmp = tmp->next;}return NULL;}
}struct InputCommander* findCommandByName(char *name,struct InputCommander *phead)
{struct InputCommander *tmp = phead;if(phead == NULL){return NULL;}else{while(tmp != NULL){if(strcmp(tmp->commandName,name) == 0){return tmp;}tmp = tmp->next;}return NULL;}
}void *voice_thread(void* datas)
{ int nread;printf("voice_thread\n");struct InputCommander *voiceHandler;voiceHandler = findCommandByName("voice",pCommandHead);if(voiceHandler == NULL){printf("find voiceHandler error\n");pthread_exit(NULL);}else{if(voiceHandler->Init(voiceHandler,NULL,NULL) < 0){printf("voice init error\n");pthread_exit(NULL);}else{printf("%s init success\n",voiceHandler->commandName);}while(1){nread = voiceHandler->getCommand(voiceHandler);if(nread == 0){printf("nodata form vocie\n");}else{printf("do divece contrl:%s\n",voiceHandler->command);}}}
}void *read_thread(void* datas)
{int n_read;printf("have user connect\n");memset(socketHandler->command,'\0',sizeof(socketHandler->command));while(1){n_read = read(c_fd,socketHandler->command,sizeof(socketHandler->command));if(n_read == -1){perror("read");}else if(n_read > 0){printf("\nget: %d,%s\n",n_read,socketHandler->command);memset(socketHandler->command,'\0',sizeof(socketHandler->command));}else{printf("client quit\n"); }}
}void *socket_thread(void* datas)
{int n_read = 0;printf("socket_thread\n");pthread_t readThrad;struct sockaddr_in c_addr;memset(&c_addr,0,sizeof(struct sockaddr_in));int clen = sizeof(struct sockaddr_in);socketHandler = findCommandByName("socketServer",pCommandHead);if(socketHandler == NULL){printf("find socketServerHandler error\n");pthread_exit(NULL);}else{printf("%s init success\n",socketHandler->commandName);}socketHandler->Init(socketHandler,NULL,NULL);while(1){c_fd = accept(socketHandler->sfd,(struct sockaddr *)&c_addr,&clen);pthread_create(&readThrad,NULL,read_thread,NULL);}
}void *cameraThread_func(void* data)//起线程的函数有格式要求
{struct Devices *cameraTemp;cameraTemp = findDeviceByName("camera", pdeviceHead); //摄像头的设备编号为c1if(cameraTemp == NULL){ //防止段错误的必需判断,当给指针赋值是,一定要考虑NULL的情况,否则后续操作都是空谈printf("find camera error\n");pthread_exit(NULL); //在线程中不用return}cameraTemp->justDoOnce(); //设备都要从工厂里面取出来.可不能camera.justDoOnce,谁认识你这个camera!
}int main()
{char name[128];struct Devices *tmp = NULL;pthread_t voiceThread;pthread_t socketThread;pthread_t cameraThread;if(-1 == wiringPiSetup()){return -1;} //1、设备工厂初始化pdeviceHead = addBathroomLightToDeviceLink(pdeviceHead);pdeviceHead = addUpstairLightToDeviceLink(pdeviceHead);pdeviceHead = addLivingRoomLightToDeviceLink(pdeviceHead);pdeviceHead = addRestaurantLightToDeviceLink(pdeviceHead);pdeviceHead = addFireToDeviceLink(pdeviceHead);pdeviceHead = addCameraContrlToDeviceLink(pdeviceHead); //摄像头pCommandHead = addvoiceContrlToInputCommandLink(pCommandHead);//声音pCommandHead = addSocketContrlToInputCommandLink(pCommandHead);//2、语音线程池建立/*int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);*/pthread_create(&voiceThread,NULL,voice_thread,NULL);//3、socket线程池建立pthread_create(&socketThread,NULL,socket_thread,NULL);//4、 摄像头线程pthread_create(&cameraThread,NULL,cameraThread_func,NULL);//5、 火灾线程//线程等待pthread_join(voiceThread,NULL);pthread_join(socketThread,NULL);pthread_join(cameraThread,NULL);return 0;
}
4、进行编译:
gcc mainPro.c upstairLight.c bathroomLight.c fire.c livingroomLight.c socketContrl.c restaurantLight.c camera.c voiceContrl.c -lwiringPi -lpthread -I ./curl-7.71.1/_install/include/ -L ./curl-7.71.1/_install/lib/ -lcurl -o test1
5、运行结果: ./test1
结果显示diff Person,说明人脸识别失败了,我也尝试了很多次,都没有成功,有可能是我放在树莓派里的本人照片和用摄像头拍的本人照片,差别较大的缘故吧,但是程序是可以正常运行的。
6、项目图片演示
相关文章:

智能家居项目(八)之树莓派+摄像头进行人脸识别
目录 1、编辑Camera.c 2、编辑contrlDevices.h 3、编辑mainPro.c 4、进行编译: 5、运行结果: ./test1 6、项目图片演示 智能家居项目(七)之Libcurl库与HTTPS协议实现人脸识别_Love小羽的博客-CSDN博客 经过上一篇文章&…...

渗透测试之地基服务篇:无线攻防之钓鱼无线攻击(上)
简介 渗透测试-地基篇 该篇章目的是重新牢固地基,加强每日训练操作的笔记,在记录地基笔记中会有很多跳跃性思维的操作和方式方法,望大家能共同加油学到东西。 请注意 : 本文仅用于技术讨论与研究,对于所有笔记中复现…...

「ABAP」一文带你入门OPEN SQL中的SELECT查询(附超详细案例解析)
💂作者简介: THUNDER王,一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学会计学专业大二本科在读,同时任汉硕云(广东)科技有限公司ABAP开发顾问。在学习工作中,我通常使用偏后…...

【搞透C语言指针】那年我双手插兜, 不知道指针是我的对手
☃️内容专栏:【C语言】进阶部分 ☃️本文概括: 征服C语言指针!一篇文章搞清楚指针的全部要点。 ☃️本文作者:花香碟自来_ ☃️发布时间:2023.3.3 目录 一、字符指针 二、指针数组 三、数组指针 1.数组指针的定义…...

如何从 Android 手机上的 SD 卡恢复已删除的照片
为了扩展手机的存储空间,很多人都会在安卓手机上插入一张SD卡来存储一些大文件,比如电影、照片、视频等。虽然SD卡给我们带来了很大的方便,但我们还是避免不了数据丢失一些事故造成的。您是否正在为 SD 卡上的照片意外丢失而苦恼?…...

01-前端-htmlcss
文章目录HTML&CSS1,HTML1.1 介绍1.2 快速入门1.3 基础标签1.3.1 标题标签1.3.2 hr标签1.3.3 字体标签1.3.4 换行标签1.3.5 段落标签1.3.6 加粗、斜体、下划线标签1.3.7 居中标签1.3.8 案例1.4 图片、音频、视频标签1.5 超链接标签1.6 列表标签1.7 表格标签1.8 布…...

【YOLO系列】YOLOv5超详细解读(网络详解)
前言 吼吼!终于来到了YOLOv5啦! 首先,一个热知识:YOLOv5没有发表正式论文哦~ 为什么呢?可能YOLOv5项目的作者Glenn Jocher还在吃帽子吧,hh 目录 前言 一、YOLOv5的网络结构 二、输入端 (1…...

从 ChatGPT 爆火回溯 NLP 技术
ChatGPT 火遍了全网,多个话题频频登上热搜。见证了自然语言处理(NLP)技术的重大突破,体验到通用技术的无限魅力。GPT 模型是一种 NLP 模型,使用多层变换器(Transformer)来预测下一个单词的概率分…...

面了 6 家大厂,并拿下 5 家 offer,进大厂好像也没有那么困难吧....
前言 二月份的时候因为换工作的缘故,陆续参加了华为、蚂蚁、字节跳动、PDD、百度、Paypal 的社招面试,除了字节跳动流程较长,我主动结束面试以外,其他的都顺利拿到了 Offer。 最近时间稍微宽裕点了,写个面经…...
四、Spring对IoC的实现
1.IoC 控制反转 控制反转是一种思想。控制反转是为了降低程序耦合度,提高程序扩展力,达到OCP原则,达到DIP原则。控制反转,反转的是什么? 将对象的创建权利交出去,交给第三方容器负责。将对象和对象之间关系…...

Java语言如何求平方根
问题 在编程时,会遇到求平方根的问题,本次问题讲到如何使用Java来求解平方根。 方法 使用java.lang.Math类的sqrt(double)方法求平方根。Math是java.lang包中的类,所以就可以直接使用这个类。Double为对象中的基本类型。例如求正整数16的平方…...
C++20中的span容器
一.span容器 span 是 C20 中引入的一个新的标准容器,它用于表示连续的一段内存区间,类似于一个轻量级的只读数组容器。 span 是一个轻量级的非拥有式容器,它提供了对连续内存的引用。 span 的主要用途是作为函数参数,可以避免不…...

codeforces周赛div3#855记录
目录 总结 一,A. Is It a Cat? 二,B. Count the Number of Pairs 三,C1. Powering the Hero (easy version) 四,C2. Powering the Hero (hard version) 总结 真羡慕ACM校队的同学,能AC七八题,甚至ak …...

2022年考研结果已出,你上岸了吗?
官方公布:2022年考研人数为457万。 2月20号左右,全国考研分数已经陆续公布,现在已经过去一周左右的时间了,你上岸了吗,还是在等调剂,或者已经知道落榜不知道何去何从? 考研的热潮在近几年席卷…...

2023 工业互联网平台:智慧制硅厂 Web SCADA 生产线
我国目前是全球最大的工业硅生产国、消费国和贸易国,且未来该产业的主要增量也将来源于我国。绿色低碳发展已成为全球大趋势和国际社会的共识,随着我国“双碳”目标的推进,光伏产业链快速发展,在光伏装机需求的带动下,…...

6-2 SpringCloud快速开发入门:声明式服务消费 Feign实现消费者
声明式服务消费 Feign实现消费者 使用 Feign实现消费者,我们通过下面步骤进行: 第一步:创建普通 Spring Boot工程 第二步:添加依赖 <dependencies><!--SpringCloud 集成 eureka 客户端的起步依赖--><dependency>…...

Git-学习笔记01【Git简介及安装使用】
Java后端 学习路线 笔记汇总表【黑马-传智播客】Git-学习笔记01【Git简介及安装使用】Git-学习笔记02【Git连接远程仓库】Git-学习笔记03【Git分支】目录 01-git的历史 02-git和svn的对比 03-git的安装 04-向本地仓库中添加文件 05-修改文件内容并提交 06-删除本地仓库中…...

【Python】控制自己的手机拍照,并自动发送到邮箱
前言 嗨喽,大家好呀~这里是爱看美女的茜茜呐 今天这个案例,就是控制自己的摄像头拍照, 并且把拍下来的照片,通过邮件发到自己的邮箱里。 想完成今天的这个案例,只要记住一个重点:你需要一个摄像头 思路…...

八股文(二)
一、 实现深拷贝和浅拷贝 1.深拷贝 function checkType(any) {return Object.prototype.toString.call(any).slice(8, -1) }//判断拷贝的要进行深拷贝的是数组还是对象,是数组的话进行数组拷贝,对象的话进行对象拷贝 //如果获得的数据是可遍历的&#…...

在CANoe/CANalyzer中观察CAN Message报文的周期Cycle
案例背景: 该篇博文将告诉您,如何直观的,图示化的,查看CAN网络中各CAN Message报文的周期变化。 优质博文推荐阅读(单击下方链接,即可跳转): Vector工具链 CAN Matrix DBC CAN M…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...

1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...

初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
适应性Java用于现代 API:REST、GraphQL 和事件驱动
在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...

AI语音助手的Python实现
引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...