这里的摄像头只是当作一个设备去用,目前实现通过串口指令然后system()进行拍照。然后翔云平台进行人脸对比,未实现自动人脸检测(不会py)。所以摄像头没有另创线程。但是做视频监控可以另创线程。

监控运动物体(人脸靠近)参考:树莓派摄像头使用Motion监测人物动作_行稳方能走远的博客-CSDN博客

这里使用fswebcam进行拍照。参考用户手册

首先在/smarthome拍照,命名为imageComp.jpg

sudo fswebcam -d /dev/video0 --no-banner -r 1280x720 -S 5 ./imageComp.jpg

全局变量

char ocrRetBuf[1024] = {'\0'};//全局变量,用来接收从OCR后台返回的数据

camera.c

#include "controlDevice.h"
#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>size_t readData(void *ptr, size_t size, size_t nmemb, void *stream)//回调函数,把从后台的数据拷贝给ocrRetBuf
{strncpy(ocrRetBuf,ptr,1024);
}char* getBase64FromFile(char* filePath)
{char* base64Buf = NULL;char cmd[256] = {'\0'};sprintf(cmd,"base64 %s > tmpFile",filePath);//图片的base64流导入到文件中system(cmd);int fd = open("./tmpFile",O_RDWR);int fileLen = lseek(fd,0,SEEK_END);        //计算文件大小lseek(fd,0,SEEK_SET);                      base64Buf = (char* )malloc(fileLen+8);memset(base64Buf,'\0',fileLen+8);read(fd,base64Buf,fileLen+8);              //从文件中读取base64流到字符串 close(fd);system("rm -f tmpFile");return base64Buf;//指针变量随着子程序调用结束消失,但malloc开辟的空间地址还在,我拿到了这块地址,就能读
}char* getFace()
{printf("人脸数据采集中...\n");system("sudo fswebcam -d /dev/video0 --no-banner -r 1280x720 -S 5 ./image.jpg");while(access("./image.jpg",F_OK) != 0); //判断是否拍照完毕printf("数据采集完毕\n");char* base64BufFaceRec = getBase64FromFile("./image.jpg");system("rm image.jpg");  //采集完成删除,防止占内存return base64BufFaceRec;   //返回刚才拍照的base64
}void postUrl()       //根据文档,接口调用方法为post请求
{CURL *curl;CURLcode res;//根据翔云平台的接口要求  分开定义,然后字符串拼接char* base64BufPic1 = getFace();//图片base64流char* base64BufPic2 = getBase64FromFile("./imageComp.jpg");char* key    = "Tnf7EDJaQ1qFZkow29xxxx";char* secret = "66d49fdbfd4944ec93035f14ea14xxxx";int   typeId = 21;char* format = "xml"; int len = strlen(key)+strlen(secret)+strlen(base64BufPic1)+strlen(base64BufPic2)+128;//分配空间不够会>导致栈溢出char* postString = (char* )malloc(len);memset(postString,'\0',len);//因为postString是一个指针,不能用sizeof来计算其指向的大小//字符串拼接函数   sprintf(postString,"img1=%s&img2=%s&key=%s&secret=%s&typeId=%d&format=%s",base64BufPic1,base64BufPic2,key,secret,typeId,format);curl = curl_easy_init();if(curl){//curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "/tmp/cookie.txt");// 指定cookie缓存文件 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postString);//指定post传输内容,get请求将URL和postString一次性发送curl_easy_setopt(curl, CURLOPT_URL, "https://netocr.com/api/faceliu.do");// 指定urlcurl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,readData);  //回调函数读取返回值res = curl_easy_perform(curl);printf("OK:%d\n",res);curl_easy_cleanup(curl);}
}struct Devices camera = {.deviceName = "camera",.justDoOnce = postUrl
};struct Devices* addCameraToDeviceLink(struct Devices *phead)
{if(phead == NULL){return &camera;}else{camera.next = phead;  //以前的头变成.nextphead = &camera;      //更新头return phead;}
}

 controlDevice.h

#include <stdio.h>
#include <stdlib.h>
#include <wiringPi.h>                 //wiringPi库extern char ocrRetBuf[1024];struct Devices                          //设备类
{char deviceName[128];               //设备名int status;                         //状态int pinNum;                           //引脚号int (*Init)(int pinNum);           //“初始化设备”函数指针int (*open)(int pinNum);           //“打开设备”函数指针int (*close)(int pinNum);           //“关闭设备”函数指针int (*readStatus)(int pinNum);      //“读取设备状态”函数指针  为火灾报警器准备int (*changeStatus)(int status);    //“改变设备状态”函数指针void (*justDoOnce)();struct Devices *next;
};struct Devices* addBathroomLightToDeviceLink(struct Devices *phead);      //“浴室灯”加入设备链表函数声明
struct Devices* addBedroomLightToDeviceLink(struct Devices *phead);         //“卧室灯”加入设备链表函数声明
struct Devices* addRestaurantLightToDeviceLink(struct Devices *phead);      //“餐厅灯”加入设备链表函数声明
struct Devices* addLivingroomLightToDeviceLink(struct Devices *phead);      //“客厅灯”加入设备链表函数声明
struct Devices* addSmokeAlarmToDeviceLink(struct Devices *phead);           //“烟雾报警器”加入设备链表函数声明
struct Devices* addBuzzerToDeviceLink(struct Devices *phead);               //“蜂鸣器”加入设备链表函数声明
struct Devices* addCameraToDeviceLink(struct Devices *phead);
struct Devices* addLockToDeviceLink(struct Devices *phead);

mainPro.c文件Command(struct InputCommand* CmdHandler)函数添加

    if(strcmp("OCR",CmdHandler->command) == 0){tmp = findDeviceByName("camera",pdeviceHead);if(tmp != NULL){tmp->justDoOnce();if(strstr(ocrRetBuf,"否") != NULL){    //字符串检索 判断翔云后台返回的一大堆字符串中有没有“否”printf("人脸比对失败\n");}else{printf("人脸比对成功\n");tmp = findDeviceByName("lock",pdeviceHead);if(tmp != NULL){tmp->open(tmp->pinNum);printf("已开门\n");delay(3000);tmp->close(tmp->pinNum);}}}}

这样当串口发送OCR时,实现人脸对比并开锁,所以没有用线程去做

当然,要把camera、lock设备加入设备工厂

编译运行

gcc *.c -lwiringPi -lwiringPiDev -lpthread -lm -lcrypt -lrt -I ../https/curl-7.71.1/_install/include/ -L ../https/curl-7.71.1/_install/lib/ -lcurlsudo ./a.out

运行结果

智能家居项目目录

智能家居(1) —— 工厂模式引入&工厂模式实现继电器控制

智能家居(2) —— 工厂模式实现烟雾报警

智能家居(3) —— 串口通信(语音识别)线程控制

智能家居(4) —— 网络服务器线程控制

智能家居(5) —— 智能家居项目整合(语音控制线程,网络控制线程、烟雾报警线程)

网络编程知识预备(1) —— 7层OSI网络模型

网络编程知识预备(2) —— 三次握手与四次挥手、半连接状态、2MSL

网络编程知识预备(3) —— TCP流量控制(滑动窗口)、拥塞控制

网络编程知识预备(4) —— SOCKET、TCP、HTTP之间的区别与联系

网络编程知识预备(5) —— 了解应用层的HTTP协议与HTTPS协议

网络编程知识预备(6) —— libcurl库简介及其编程访问百度首页

智能家居(6) —— 香橙派摄像头安装实现监控功能

智能家居(7) —— 人脸识别 & 翔云平台编程使用(编译openSSL支持libcurl的https访问、安装SSL依赖库openSSL)

智能家居(8) —— 香橙派摄像头加入设备工厂

智能家居(8) —— 香橙派摄像头加入设备工厂相关推荐

  1. 智能家居(6) —— 香橙派摄像头安装实现监控功能

    目录 一.USB摄像头测试 二.face_recognition 人脸识别库的安装和测试方法 三.face_recognition 的测试方法 face_recognition的使用 定位人脸,人脸识 ...

  2. 智能家居-基于香橙派zreo2——手把手搭建、继电器控制灯(一)

    一.什么是设计模式 设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用.设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案.这些解决方案是 ...

  3. 智能家居语音控制及摄像头人脸识别(含代码)

    智能家居语音控制及摄像头人脸识别 1.使用的软件及过程 2.python 人脸代码讲解 3.主函数代码讲解 1.使用的软件及过程 使用到的软件有secureSRT,filezilla,Visual S ...

  4. 智能家居制作之WiFi遥控家中设备

    基于机智云平台和Arduino的智能遥控设备 介绍 流程 创建产品 WiFi模块联网 库文件及头文件准备 功能实现 后续 介绍 现如今,智能家居行业发展迅速,得益于物联网和人工智能技术的迭代发展,各类 ...

  5. 智能家居(12)——树莓派USB摄像头捕捉人脸并识别

    树莓派摄像头捕捉人脸并识别 一.USB摄像头监控.拍照 二.树莓派安装libcurl和openssl库 三.拍照的关键指令: 四.源码及步骤 参考原文: https://blog.csdn.net/N ...

  6. 智能家居(2) —— 工厂模式实现烟雾报警

    目录 工厂模式实现烟雾报警 mainPro.c(主函数) controlDevice.h(设备类) smokeAlarm.c(烟雾报警器) buzzer.c(蜂鸣器) 运行结果 线程实现 mainPr ...

  7. 智能家居 (5) ——智能家居项目整合(语音控制线程,网络控制线程、烟雾报警线程)

    目录 一.主函数 mianPro.c 二.指令工厂 voiceControl.c socketControl.c inputCommand.h 三.设备工厂 smokeAlarm.c buzzer.c ...

  8. 智能家居(1) —— 工厂模式引入工厂模式实现继电器控制

    目录 一.什么是设计模式 二.类和对象 三.工厂模式 工厂模式的实现 四.工厂模式实现继电器控制 mainPro.c(主函数) controlDevice.h(设备类) bathroomLight.c ...

  9. 智能家居(7) —— 人脸识别 翔云平台编程使用(编译openSSL支持libcurl的https访问、安装SSL依赖库openSSL)

    目录 一.祥云人工智能开放平台 二.编译openSSL支持libcurl的https访问 安装SSL依赖库openSSL(使用工具wget) curl库重新配置,编译,安装 三.编程实现人脸识别 翔云 ...

最新文章

  1. python 二叉树遍历
  2. 1-Alternative Boot Flows
  3. ROBOTS.TXT屏蔽笔记、代码、示例大全
  4. 二十多岁不信,三十多岁却深信不疑的道理
  5. 微软职位内部推荐-Sr. SW Engineer for Azure Networking
  6. 找出100以内内被7整除的数,每行显示7个,然后换行显示
  7. singer页左侧滚动的时候右侧跟随高亮显示
  8. 关于数据库的设计的一点思路
  9. ios沙盒查找图片展示
  10. “我升职的原因是:比同事更早学会这个知识”
  11. 蓝牙:深入浅出低功耗蓝牙(BLE)协议栈
  12. java xcap,xcap发包工具的简单使用2(发送报文)
  13. VSCode 即时英文翻译插件 【翻译(英汉词典)】
  14. python入门系列(4) -- python常见应用
  15. WebGL之3D地球
  16. 看脸、听话,飞猪未来酒店就是这么好住
  17. VC知识库视频大讲坛系列之GDI GDI+从入门到精通
  18. 性能测试测试方案总结
  19. 2016都市小说排行版前十推荐
  20. 坦克大战类型 坦克WASD前后左右移动的解决方法

热门文章

  1. c语言克鲁斯卡尔算法
  2. 微服务架构面试题74道(2023)
  3. Monolog-PHP日志类库
  4. yoga1976_Yoga Studios的21个最佳WordPress主题(2020)
  5. CRC Press/Balkema出版社,及其EI会议检索!
  6. 调用API让声卡发出声音
  7. 云边有个小书屋——基于墨刀的读书APP原型化系统
  8. 异步网页采集利器CasperJs
  9. 弘辽科技:拼多多店铺类目有哪些?怎么选择类目?
  10. 当计算摄影成为行业共识,手机影像竞争将卷向何方?