智能家居项目(八)之树莓派+摄像头进行人脸识别
目录
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、项目图片演示
智能家居项目(八)之树莓派+摄像头进行人脸识别相关推荐
- 从零开始的DIY智能家居--自己在家手搓一套人脸识别智慧猫眼系统
前言 最近整理资料的时候,才发现之前写的一个智慧猫眼的爱智场景没有给大家写文章介绍,可能有的小伙伴之前也看到爱智官方引用我的这个代码给大家进行了一个直播演示,我个人还是觉得自己也有必要简单介绍一下 ...
- 智能家居黑科技!首款3D人脸识别智能锁发布 搭载百度智能云函谷物联安全系统...
随着AI在家庭场景中应用的普及与发展,智能锁逐渐成为智能家居的不可或缺的"门面担当",在满足消费者快捷和多样化需求的同时,如何保障家庭安全也成为被重点关注的问题.4月24日,德施曼 ...
- 树莓派智能家居项目整合(包含语音、socket、火灾、摄像头线程)
树莓派智能家居项目一 1.百度网盘下载代码链接 2.main.c 3.段错误 4.C语言的函数声明 4.1没声明的报错内容 5.关于报错,调试程序 坎坎坷坷,墨墨迹迹了这么久也算是完成了四个线程的同时 ...
- 智能家居 (8) ——智能家居项目整合(网络控制线程、语音控制线程,火灾报警线程)
目录 mainPro.c(主函数) 指令工厂 inputCommand.h voiceControl.c(语音控制) socketControl.c(网络线程) 控制工厂 contrlEquipmen ...
- 智能家居项目开发: 设计模式(工厂模式)+ 线程池 + Socket (持续更新中)
智能家居项目开发 一.智能家居功能细节拆分 控制区: 外设区: 面向对象类和对象的概念 结构体新玩法 二.工厂模式 1. 工厂模式的概念 2. 工厂模式的实现 3. 工厂模式使用及功能验证 三.智能家 ...
- 智能家居项目(三)之框架设计及框架代码文件工程建立
目录 一.智能家居项目框架设计草图 二.框架代码文件工程建立 三.添加声音识别模块的串口读取功能 一.智能家居项目框架设计草图 代码思路讲解: 1.一个指令工厂,一个控制工厂,实际上就是通过链表链起来 ...
- 智能家居项目开发(一):简单工厂设计模式引入
智能家居项目开发 一.智能家居功能细节拆分 二.设计模式概念的引入 三.类与对象 四.结构体新玩法 五.工厂模式 一.智能家居功能细节拆分 1.控制区 我们会用到之前学过的: 语音识别模块 socke ...
- 智能家居 (5) ——智能家居项目整合(语音控制线程,网络控制线程、烟雾报警线程)
目录 一.主函数 mianPro.c 二.指令工厂 voiceControl.c socketControl.c inputCommand.h 三.设备工厂 smokeAlarm.c buzzer.c ...
- 物联网智能家居项目---智能卧室
智能卧室 介绍 设计需求 功能介绍 准备 软件准备 硬件准备 项目制作 库文件调用和变量定义 超声波测距函数 初始化 变量赋值和LCD显示屏显示温湿度 功能实现 后续 介绍 设计需求 为了提高用户生活 ...
最新文章
- 嵌入式MVN指令解析
- 01_Nginx安装,nginx下部署项目,nginx.conf配置文件修改,相关文件配置
- html卷轴展开,HTML文本框滚动代码4:卷轴变化应用
- dart系列之:和null说再见,null使用真实实践
- [蓝桥杯][2016年第七届真题]密码脱落(记忆化搜索)
- Python基础案例(一)
- 使用Struts2,Hibernate和MySQL BLOB开发个人迷你相册应用程序–第1部分
- 第七期:详解JavaScript运行机制(Event Loop)
- Intel Core Enhanced Core架构/微架构/流水线 (14) - 存储器/内存读写 Memory Load/Store
- Sendmail邮件服务器搭建与配置笔记
- log4j:WARN No appenders could be found for logger ().解决方案
- Oracle传统基本体系结构初步介绍(2)
- 一劳永逸解决latex的字体问题
- 织梦网站建设广告网络公司网站模板 电脑+手机 整站源码
- 最新AWVS14.9.220913107 支持Windows使用教程(附下载地址)
- 实时的含时密度泛函理论(rt-TDDFT)的算法进展及在超快动力学中的应用
- 自己制作一个小程序需要多少钱
- count(1)、count(*)、count(列名) 详解
- 前端之CSS篇(一)——CSS入门及基础选择器和字体文本属性
- SAP客户主数据相关表
热门文章
- 【CUDA】安装CUDA
- 性能监控与服务器监控
- 开源OA:手把手教你搭建OA办公系统(3)开发企业报销审批流程
- 超低功耗LCD液晶显示驱动芯片(IC)-VKL128-稳定性好,超低工作电流,低休眠电流-技术开发资料
- oracle设置字符集为gbk,rac 环境下修改oracle数据库字符集为GBK
- 【Java】接口与继承
- .so是什么文件_Linux的so文件到底是干嘛的?浅析Linux的动态链接库
- java为什么有基本类型_你了解Java数据类型吗?
- Java项目:springboot大学生实习管理系统
- DSP中定点与浮点运算