目录
智能家居项目(七)之Libcurl库与HTTPS协议实现人脸识别_Love小羽的博客-CSDN博客
经过上一篇文章,写的代码是在Ubuntu系统中写的,这回把代码搬到树莓派上进行测试
直接上代码
#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;
}
//设备工厂
#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);
#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;
}
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

结果显示diff Person,说明人脸识别失败了,我也尝试了很多次,都没有成功,有可能是我放在树莓派里的本人照片和用摄像头拍的本人照片,差别较大的缘故吧,但是程序是可以正常运行的。

如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘
我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="
假设我有这个范围:("aaaaa".."zzzzz")如何在不事先/每次生成整个项目的情况下从范围中获取第N个项目? 最佳答案 一种快速简便的方法:("aaaaa".."zzzzz").first(42).last#==>"aaabp"如果出于某种原因你不得不一遍又一遍地这样做,或者如果你需要避免为前N个元素构建中间数组,你可以这样写:moduleEnumerabledefskip(n)returnto_enum:skip,nunlessblock_given?each_with_indexdo|item,index|yieldit
我正在尝试创建一个带有项目符号字符的Ruby1.9.3字符串。str="•"+"helloworld"但是,当我输入它时,我收到有关非ASCII字符的语法错误。我该怎么做? 最佳答案 你可以把Unicode字符放在那里。str="\u2022"+"helloworld" 关于ruby-如何在Ruby字符串中插入项目符号字符?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/1195
我的Rails站点使用了一个确实不是很好的gem。每次我需要做一些新的事情时,我最终不得不花费与向实际Rails项目添加代码一样多的时间来为gem添加功能。但我不介意,我将我的Gemfile设置为指向我的gem的GitHub分支(我尝试提交PR,但维护者似乎已经下台)。问题是我真的没有找到一种合理的方法来测试我添加到gem的新东西。在railsc中测试它会特别好,但我能想到的唯一方法是a)更改~/.rvm/gems/.../foo。rb,这看起来不对或者b)升级版本,推送到Github,然后运行bundleup,这除了耗时之外显然是一场灾难,因为我不确定我所做的promise是否正
我一直在尝试使用nanoc用于生成静态网站。我需要组织一个复杂的排列页面,我想让我的内容保持干燥。包含或合并的概念在nanoc系统中如何运作?我已阅读文档,但似乎找不到我想要的内容。例如:我如何获取两个部分内容项并将它们合并到一个新的内容项中。在staticmatic您可以在您的页面中执行以下操作。=partial('partials/shared/navigation')类似的约定在nanoc中如何运作? 最佳答案 这里是nanoc的作者。在nanoc中,部分是布局。因此,您可以拥有layouts/partials/shared/
我安装了ruby、yeoman,当我运行我的项目时,出现了这个错误:Warning:Running"compass:dist"(compass)taskWarning:YouneedtohaveRubyandCompassinstalledthistasktowork.Moreinfo:https://github.com/gruUse--forcetocontinue.Use--forcetocontinue.我有进入可变session目标的路径,但它不起作用。谁能帮帮我? 最佳答案 我必须运行这个:geminstallcom
我有一个包含多个组件的存储库,其中大部分是用JavaScript(Node.js)编写的,一个是用Ruby(RubyonRails)编写的。我想要一个.travis.yml文件来触发一个运行每个组件的所有测试的构建。根据thisTravisCIGoogleGroupthread,目前还没有官方支持。我的目录结构是这样的:.├──构建服务器├──核心├──扩展├──网络应用├──流浪文件├──package.json├──.travis.yml└──生成文件我希望能够运行特定版本的Ruby(2.2.2)和Node.js(0.12.2)。我已经有了一个make目标,所以maketest在每
前面一篇关于智能合约翻译文讲到了,是一种计算机程序,既然是程序,那就可以使用程序语言去编写智能合约了。而若想玩区块链上的项目,大部分区块链项目都是开源的,能看得懂智能合约代码,或找出其中的漏洞,那么,学习Solidity这门高级的智能合约语言是有必要的,当然,这都得在公链``````以太坊上,毕竟国内的联盟链有些是不兼容Solidity。Solidity是一种面向对象的高级语言,用于实现智能合约。智能合约是管理以太坊状态下的账户行为的程序。Solidity是运行在以太坊(Ethereum)虚拟机(EVM)上,其语法受到了c++、python、javascript影响。Solidity是静态类型