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

更多干货推荐可以去牛客网看看,他们现在的IT题库内容很丰富,属于国内做的很好的了,而且是课程+刷题+面经+求职+讨论区分享,一站式求职学习网站,最最最重要的里面的资源全部免费!!!点击进入--------------》跳转接口
在这里插入图片描述

更多干货推荐可以去牛客网看看,他们现在的IT题库内容很丰富,属于国内做的很好的了,而且是课程+刷题+面经+求职+讨论区分享,一站式求职学习网站,最最最重要的里面的资源全部免费!!!点击进入--------------》跳转接口
在这里插入图片描述

目录

  • 实现思路
  • 主要功能代码
  • 功能验证
  • 往期文章

实现思路

学完前面在Ubuntu系统下的人脸识别内容,本节我们将实现在树莓派上通过一个指令启动摄像头进行拍照并且完成人脸识别,为后面我们的智能家居系统加入人脸识别开锁功能做准备。

首先,去扩容一下SD卡

【树莓派】让你的SD卡快速扩容

其次,使用指令拍一张照片

【树莓派】CSI摄像头简单配置

上文介绍的拍照指令,运行即可拍照

raspistill -o image3.jpg

如果直接使用上面这个指令,那拍出来的图片大概有1.3M左右,不符合祥云后台所要求的图片大小在200k以下
在这里插入图片描述

那么我们可以对图片进行压缩,可以改变摄像头的参数,降低摄像头输出的图片质量。通过查阅树莓派摄像头参数设置,做如下配置:

raspistill -q 5 -t 1 -o image.jpg

-q 是图片质量,在0~100之间,我们调成5,压缩图片质量
-t 是拍照延时,设定1s后拍照

经过测试,拍出来的图片由原来的1.3M变成了90多K,而且图片还很清晰。

做好上述准备工作,我们就可以发送指令open-c1启动摄像头线程了,在这个线程中,需要完成下列操作:

①摄像头拍照返回base64流,
②然后用翔云平台进行对比识别,
③返回识别的结果

线程结束完成一次拍照识别

主要功能代码

(1)通过拍照指令提取当前人脸数据的base64流

上面介绍了树莓派的拍照指令,问题是拍照的时机怎么确定?

  • 原始手动的话,采用按钮方式人脸靠近手动拍照;
  • 自动的话一种方式是通过每隔一秒拍照一次,不断对比,很快就会将OCR识别次数用完;
  • 另一种方式我们可以识别人物动作,发现有人来再进行拍照识别,具体可参照这篇博文:树莓派摄像头使用Motion监测人物动作
char* getFace()
{printf("人脸数据采集中...\n");system("raspistill -q 5 -t 1 -o image.jpg");while(access("./image.jpg",F_OK) != 0); //判断是否拍照完毕printf("数据采集完毕\n");char* base64BufFaceRec = getBase64FromFile("./image.jpg");system("rm image.jpg");  //采集完成删除,防止占内存return base64BufFaceRec;   //返回刚才拍照的base64
}

(2)通过命令起摄像头线程

if(0 == strcmp(devName,"c1")){  //open-c1起摄像头线程pthread_t cameraThread;pthread_create(&cameraThread,NULL,cameraThread_func,NULL);return;  //执行拍照就不往下走了,返回
}

(3)线程函数

void *cameraThread_func(void* data)//起线程的函数有格式要求
{struct Devices *cameraTemp;cameraTemp = findDeviceByNum(pDeviceHead, "c1"); //摄像头的设备编号为c1if(cameraTemp == NULL){  //防止段错误的必需判断,当给指针赋值是,一定要考虑NULL的情况,否则后续操作都是空谈printf("find camera error\n");pthread_exit(NULL); //在线程中不用return}cameraTemp->justDoOnce(); //设备都要从工厂里面取出来.可不能camera.justDoOnce,谁认识你这个camera!
}

(4)摄像头的结构体

struct Devices camera = {.name = "camera",.serialNum = "c1",.justDoOnce = postUrl,.deviceInit = cameraInit,};

(5)调库人脸识别函数

void postUrl()
{CURL *curl;CURLcode res;//分开定义,然后字符串拼接char* key    = "xxx";char* secret = "xxx";int   typeId = 21;char* format = "xml";char* base64BufPic1 = getFace();//摄像头拍照获取的照片char* base64BufPic2 = getBase64FromFile("./Your phtot.jpg");//你提前拍好的帅气照片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_POSTFIELDS, postString);  //指定post内容,传入参数  curl_easy_setopt(curl, CURLOPT_URL, "https://netocr.com/api/faceliu.do");// 指定urlcurl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,readData);  //回调函数readDate读取返回值res = curl_easy_perform(curl);          //类似于状态码printf("OK:%d\n",res);if(strstr(ocrRetBuf,"否") != NULL){    //判断翔云后台返回的字符串中有没有“是”printf("不是同一个人\n");}else{printf("是同一个人\n");//这里识别成功,去开锁!}curl_easy_cleanup(curl);}}

(6)回调函数

char ocrRetBuf[1024] = {'\0'};//全局变量,用来接收从OCR后台返回的数据size_t readData(void *ptr, size_t size, size_t nmemb, void *stream)
//回调函数,把从后台的数据拷贝给ocrRetBuf
{strncpy(ocrRetBuf,ptr,1024);
}

功能验证

提前拍好自己的一张帅气照片放到树莓派里面,靠近树莓派摄像头识别成功,相应的继电器打开,锁开启。

在这里插入图片描述

后面我将摄像头识别线程完整的实现代码整合到智能家居里面展示,具体在下一篇博文介绍。

往期文章

智能家居 (1) ——智能家居整体功能框架
智能家居 (2) ——设计模式的引入
智能家居 (3) ——工厂模式继电器控制灯
智能家居 (4) ——工厂模式火焰报警
智能家居 (5) —— LD3320语音模块二次开发
智能家居 (6) ——语音识别线程控制
智能家居 (7) ——网络服务器线程控制
智能家居 (8) ——智能家居项目整合(网络控制线程、语音控制线程,火灾报警线程)
网络编程知识预备(1) ——了解OSI网络模型
网络编程知识预备(2) ——浅显易懂的三次握手与四次挥手
网络编程知识预备(3) ——SOCKET、TCP、HTTP之间的区别与联系
网络编程知识预备(4) ——了解HTTP协议与HTTPS协议
网络编程知识预备(5) ——libcurl库简介及其编程访问百度首页
智能家居 (9) ——人脸识别摄像头安装实现监控功能
智能家居 (10) ——人脸识别祥云平台编程使用
智能家居 (11) ——树莓派摄像头捕捉人脸并识别
智能家居 (12) ——人脸识别整合到智能家居系统
智能家居 (13) ——智能家居加入手机app端控制

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

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

相关文章

centos上使用高版本gcc、g++

0x0 在centos7上gcc版本是4.85,在编译一些代码时需要使用g的一些新特性,而网上大多教程都是重新编译gcc,太麻烦了,在centos 7上默认是yum search不到高版本的gcc的 安装scl scl 是Software collections 的缩写,安装…

【Docker系列教程之一】docker入门

我们在理解 docker 之前,首先我们得先区分清楚两个概念,容器和虚拟机。 我们用的传统虚拟机如 VMware , VisualBox 之类的需要模拟整台机器包括硬件,每台虚拟机都需要有自己的操作系统,虚拟机一旦被开启,预…

Java基础 —— 变量,选择,循环,数组,输入与输出等

目录嵌入式学JAVAJava安卓开发环境搭建并运行HelloWorld概念引入JavaSE,EE,ME的区别JREJDK编程实操:从C面向过程转变变量定义与输出数组的定义与遍历(循环、控制、选择和C完全一样)函数的调用:类比c语言结构体的使用输入数据:Scanner嵌入式学…

ubuntu20 编译dpdk错误 -Werror=address-of-packed-member

0x0 在ubuntu20上编译dpdk 18.11报错,gcc 版本为9.3.0,报错如下: error: converting a packed ‘const struct ether_addr’ pointer (alignment 1) to a ‘unaligned_uint16_t’ {aka ‘const short unsigned int’} pointer (alignment 2…

Java 特性

Java有四大特性: 1.封装:隐藏对象的属性和实现细节,仅仅对外公开接口。 封装具有一下优点: 便于使用者正确、方便的使用系统,防止使用者错误修改系统属性;有助于建立各个系统之间的松耦合关系;…

MyBatis 传递多个参数

2019独角兽企业重金招聘Python工程师标准>>> 在MyBatis中可以用以下的方式来传递多个参数 1. 用java.util.Map来传递, Code 如下: public List<User> getAllUsersByUserName(String username, int start, int limit){Map<String,Object> params new H…

Linux stmac网卡代码分析----probe

probe 主要分析一下驱动的主要框架&#xff0c;必要地方细致分析下 文件位置&#xff1a; drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c 从文件的最后看起&#xff1a; module_pci_driver(stmmac_pci_driver); stmmac_pci_driver结构体如下&#xff0c;里面包含了id_…

Java面向对象(1) —— 封装

目录一、封装的概念二、类的封装以及使用三、访问修饰符四、属性封装的实现五、方法封装的实现六、UML类图七、类的构造方法与可重载八、this关键字九、static关键字十、方法重载&#xff1a;overload十一、包&#xff1a;package一、封装的概念 将字段&#xff08;C结构体中的…

linux下源码软件包的安装

我们在使用linux做服务器的时候&#xff0c;因为linux自带的软件包都有些老&#xff0c;不是最新的&#xff0c;但是有时候我们为了使用最新的软件&#xff0c;会使用最新的软件的源码来进行安装。所以我们需要用心去做了...在我们拿到一个软件的源码时&#xff0c;源码一般都是…

react-native 打包apk 并解决 图片 不出现问题

react-native官网打包apk方法&#xff1a;https://reactnative.cn/docs/signed-apk-android/ 解决办法&#xff1a; 找到项目 android目录下 gradle.properties文件 打开加入如下代码&#xff1a; android.enableAapt2false这段代码非常重要 官网缺少 。不然打包apk图片不出现。…

龙芯派2亚克力外壳

0x0 龙芯派自带的亚克力顶板没有风扇的孔位&#xff0c;在长时间运行时亚克力板很烫&#xff0c;因此我设计了个带风扇孔位的亚克力顶板 效果如下&#xff1a; 风扇规格 4X4风扇 供电由龙芯派的GPIO上的5V管脚供电 使用方法 1.某宝搜索亚克力板定制 2. 将本文件发送给店家…

Java面向对象(2) —— 继承

目录前言继承的概念和实现extends关键字super关键字继承过来的属性和方法的权限研究方法重写OverrideObject根类常见方法toString()常把toString()方法重写后应用equals()重写&#xff1a;判断两个对象p1和p2特征是否相同IDEA的重写模板&#xff1a;敲equals可选择的方案之一St…

dpdk18.11 收发包流程分析

pci probe RTE_PMD_REGISTER_PCI(net_ixgbe, rte_ixgbe_pmd); 宏注册了net_ixgbe driver到pci bus rte_ixgbe_pmd 的定义如下 static struct rte_pci_driver rte_ixgbe_pmd {.id_table pci_id_ixgbe_map,.drv_flags RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,.pr…

人工智能芯片龙头之一gti概念股_AI芯片龙头寒武纪IPO价格定了!概念股全名单收好...

寒武纪披露首次公开发行股票并在科创板上市发行公告&#xff0c;确定发行价格为64.39元/股&#xff0c;本次科创板上市发行剔除无效报价和最高报价后剩余报价拟申购总量为3,405,910万股&#xff0c;整体申购倍数为回拨前网下初始发行规模的1327.12倍。战略配售投资者包含中信证…

Java面向对象(3) —— 抽象类、接口、内部类、匿名内部类

目录抽象类&#xff08;abstract&#xff09;抽象类的使用方法抽象类的应用&#xff1a;模板方法模式接口接口的概念接口的特点接口的使用接口实现与抽象类继承的区别接口的多继承内部类概念成员内部类&#xff08;使用较多&#xff09;及应用创建成员内部类的实例在成员内部类…

Kohana和Zencart

2019独角兽企业重金招聘Python工程师标准>>> 我有一个Kohana php框架但是客户求和zencart系统结合。我有一个想法是Kohana重新zencart 有没有人用过&#xff1f;应该没有吧 Kohana 是一款纯 PHP5 的框架&#xff0c;基于 MVC 模式开发&#xff0c; 它的特点就是高安…

Linux stmac网卡代码分析 -- open

Open stmmac_open是在stmmac_netdev_ops结构体里的&#xff0c;这个ops在probe时就已经注册到了net_device结构体里&#xff0c;在网卡对于stmmac_open函数调用的时间我还不确定是否是在网卡link up时 下面看看stmmac_open函数&#xff0c;文件位置&#xff1a; drivers/net/…

g++ linux 编译开栈_方舟编译器编译hello world踩坑全记录

闲来无事&#xff0c;看到方舟编译器完整开源&#xff0c;于是打算拿来试着编译一个东西来&#xff0c;接下来把踩过的一些坑记录一下。参考文档方舟编译器的官网是OpenArkCompiler​www.openarkcompiler.cn但是这个网站上的文档其实是过时的&#xff0c;没有更新过的&#xff…

绘制自定义键盘

先看下微信当中的自带的数字键盘 这种实现方式比较简单&#xff0c;可以直接用inline-block标签&#xff0c;设置每行平均宽度&#xff0c;比如一行要放4个按钮&#xff0c;可以那么宽度就可以设为25%&#xff0c;同时要注意设置css样式为box-sizing: border-box,这样在设置边框…

配置管理小报100329:脚本中ftp命令无法自动输入密码怎么办?

为什么80%的码农都做不了架构师&#xff1f;>>> 知识点&#xff1a; 作者&#xff1a;王&#xff08;zbwangjian.cn&#xff09; 脚本中ftp命令无法自动输入密码怎么办&#xff1f;参考&#xff1a; http://www.linji.cn/post/1620/ http://www.hamo…