智能家居项目(八)之树莓派+摄像头进行人脸识别

news2024/11/25 0:28:19

目录

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";//翔云平台购买人脸识别后的key
    char* secret = "自行购买翔云平台购买人脸识别后的secret";//翔云平台购买人脸识别后的secret
    int   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); //摄像头的设备编号为c1

	if(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、项目图片演示

 

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

redhawk:Low Power Analysis

1.rush current与switch cell 在standby状态下为了控制leakage power我们选择power gating的设计方式&#xff0c;使用power switch cell关闭block/power domain的电源。 power switch的基本介绍可见: 低功耗设计-Power Switch power switch的table中有四种状态&#xff0c;…

Simulink 自动代码生成电机控制:优化Simulink生成的代码提升代码运行效率

目录 优化需求 优化方法 从模型配置优化 优化结果对比 从算法层优化 优化结果对比 总结 优化需求 本次优化的目的是提升FOC代码执行速度&#xff0c;以普通滑模观测器为例&#xff0c;优化前把速度环控制放到2ms的周期单独运行&#xff0c;把VOFA上位机通信代码放到主循…

mongodb入门到使用(上)

mongodb的安装与使用前言一、linux下载二、mongodb配置三、 mongodb服务管理启动服务查看停止四、远程连接五、SpringBoot整合总结前言 本文主要针对一些项目的部署服务器在使用方面用到了mongodb&#xff0c;参考解决一些部署方面遇到的问题。 一、linux下载 使用wget下载 w…

代数小课堂:向量代数(通过向量夹角理解不同的维度)

文章目录 引言I 计算向量的夹角1.1 毕达哥拉斯定理1.2 余弦定理1.3 计算向量的夹角II 向量夹角的应用2.1 用计算机自动筛选简历(对人进行分类)2.2 计算机进行文本自动分类的原理引言 根据余弦定理计算两个向量的夹角向量夹角的应用: 对文本进行自动分类、自动筛选简历。如果…

【上位机入门常见问题】Visual Studio 2022安装指导

Visual Studio 2022安装指导 这里给大家指导安装Visual Studio 2022 Community版本&#xff0c;也就是我们常说的社区版&#xff0c;这个版本是微软给开发者学习技术专门定制的免费版本&#xff0c;其他的专业版和企业版都是商业收费版本。对于我们学习&#xff0c;大家使用社…

使用Docker、navicat部署和连接GaussDB

一、在CentOS7上安装Docker工具 1.卸载之前老版本的Docker yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-selinux \docker-engine-selinux \docker-engine \docker-ce 2.安装D…

TLS协议

TLS全称传输层安全协议&#xff0c;上一代是安全套接层&#xff08;SSL,不安全&#xff09;&#xff0c;用途广泛&#xff0c;最知名的是用于http&#xff0c;使http升级为https协议&#xff0c;最新版本为TLSv1.3&#xff08;推荐使用&#xff09;。TLS通过建立客户端和服务器…

Vue-router的引入和安装

什么是Vue-Router&#xff1f;Vue路由器是Vue.js的官方路由器&#xff0c;它与Vue.js核心深度集成&#xff0c;使用Vue轻松构建单页应用程序变得轻而易举。功能包括&#xff1a;嵌套路线映射动态路由模块化&#xff0c;基于组件的路由器配置路由参数&#xff0c;查询&#xff0…

常用的hive sql

细节&#xff1a;sql 中有涉及到正则匹配函数的&#xff0c;要注意转义符号 因为在不同语言下正则匹配规则是否需要加转义符号是不同的&#xff0c;举例&#xff0c;regexp_replace 函数&#xff0c;在hive sql的正则匹配规则的 \d 需要前面给它加上转义符号\&#xff0c;而在j…

RocketMQ5.0.0事务消息

目录 一、事务消息概览 二、事务消息实现机制 1. 事务消息发送流程 1)&#xff1a;发送事务消息类图 2)&#xff1a;生产端发送事务消息 3)&#xff1a;Broker存储事务消息 2. 生产者提交或回滚事务消息 1)&#xff1a;生产者发送提交或回滚事务请求 2)&#xff1a;Broker处…

【谷粒学院】微信扫码支付(224~238)

224.项目第十五天内容介绍 225.课程评论实现过程分析 226.课程支付功能需求分析 1、课程支付说明 &#xff08;1&#xff09;课程分为免费课程和付费课程&#xff0c;如果是免费课程可以直接观看&#xff0c;如果是付费观看的课程&#xff0c;用户需下单支付后才可以观看 &am…

CAD轴测图怎么画?

很多新手设计师小伙伴&#xff0c;不知道CAD轴测图怎么画&#xff1f;其实很简单&#xff0c;浩辰CAD中的超级轴测功能&#xff0c;可以方便地将CAD平面图转化为轴侧图&#xff0c;是绘制管线系统图的好帮手。今天就和小编一起来看看在浩辰CAD软件中通过调用超级轴测命令来绘制…

[数据结构]:08-顺序查找(顺序表指针实现形式)(C语言实现)

目录 前言 已完成内容 顺序查找实现 01-开发环境 02-文件布局 03-代码 01-主函数 02-头文件 03-PSeqListFunction.cpp 结语 前言 此专栏包含408考研数据结构全部内容&#xff0c;除其中使用到C引用外&#xff0c;全为C语言代码。使用C引用主要是为了简化指针的使用&a…

webpack生产环境配置

3 webpack生产环境配置 由于笔记文档没有按照之前的md格式书写&#xff0c;所以排版上代码上存在问题&#x1f622;&#x1f622;&#x1f622;&#x1f622; 09 提取css成单独文件 使用下载插件 npm i mini-css-extract-plugin0.9.0 -D webpack配置此时a,b提取成单独文件,并且…

1378:最短路径(shopth)

1378&#xff1a;最短路径(shopth) 时间限制: 1000 ms 内存限制: 65536 KB 【题目描述】 给出一个有向图G(V, E)&#xff0c;和一个源点v0∈V&#xff0c;请写一个程序输出v0和图G中其它顶点的最短路径。只要所有的有向环权值和都是正的&#xff0c;我们就允许图的边有…

有趣的小知识(二)浏览器内的秘密:了解Cookie基础知识

一、简介 Cookie是一种小型的文本文件&#xff0c;由Web服务器发送给Web浏览器&#xff0c;并存储在用户的计算机硬盘上。它通常用于记录用户的偏好、登录状态、购物车信息等&#xff0c;以便在用户下次访问该网站时能够提供更好的用户体验。Cookie通常包含网站的名称、Cookie的…

2023年工业自动化,机器人与控制工程国际会议(IARCE 2023)

2023年工业自动化&#xff0c;机器人与控制工程国际会议&#xff08;IARCE 2023&#xff09; 重要信息 会议网址&#xff1a;www.iarce.org 会议时间&#xff1a;2023年10月27-29日 召开地点&#xff1a;中国成都 截稿时间&#xff1a;2023年9月21日 录用通知&#xff1a;…

[创业之路-57] :商业计划书BP如何书写?总体框架!

引言&#xff1a;BP (Buiness Plan) &#xff0c;即商业计划书&#xff0c;本质上还是一份计划&#xff0c;是一份商业计划&#xff0c;即一种关于如何赚钱的计划&#xff0c;是一份通过组建公司&#xff0c;运营项目&#xff0c;进而赚钱的项目计划。什么是商业&#xff1f;商…

【计算机网络】ISO/OSI参考模型与TCP/IP模型

ISO/OSI参考模型与TCP/IP模型 一、ISO/OSI参考模型&#xff08;七层&#xff09; 一个理论模型&#xff0c;并未商用。 OSI参考模型有七层&#xff0c;自上而下分别为 应用层 &#xff1a; 所有能产生网络流量的应用程序都属于是应用层 典型协议&#xff1a;FTP&#xff08…

分布式锁详解

文章目录分布式锁是什么基于 Redis 实现分布式锁如何基于Redis实现一个简单的分布式锁为什么要给锁设置一个过期时间&#xff1f;如何实现锁的优雅续期&#xff1f;如何实现可重入锁&#xff1f;Redis 如何解决集群情况下分布式锁的可靠性&#xff1f;分布式锁是什么 java单机…