opensll、libcurl库安装的使用,树莓派CSI摄像头的配置,树莓派调用智能API平台实现人脸识别、树莓派配置中文环境

接着上一节人工智能翔云平台介绍:

人工智能OCR识别: OCR 是英文Optical Character Recognition的缩写,意思是光学字符识别,也可简单地称为文字识别,是文字自动输入的一种方法。它通过 扫描 和摄像等光学输入方式获取纸张上的文字图像信息,利用各种 模式 识别算法分析文字形态特征 可以将票据、报刊、书籍、文稿及其它印刷品转化为图像信息,再利用文字识别技术将图像信息转化为可以使用的计算机输入技术。可应用于银行票据、大量文字资料、档案卷宗、文案的录入和处理领域。适合于银行、税务等行业大量票据表格的自动扫描识别及长期存储。相对一般文本,通常以最终识别率、识别速度、版面理解正确率及版面还原满意度4个方面作为OCR技术的评测依据;而相对于表格及票据, 通常以识别率或整张通过率及识别速度为测定OCR技术的实用标准,随着人工智能的兴起,人们在追求让工作更简单化,ocr识别技术可以让从事文字工作的人更加轻松。

人脸识别接口的购买:

首先注册翔云平台的账号,然后进入价格与购买,购买后即可进行程序代码的编写进行接口的调用。通过查看开发文档,要求http请求是post请求。
在这里插入图片描述在这里插入图片描述

编写代码实现人脸识别:
在这里插入图片描述
编译openssl支持libcurl的https访问:

  • 如果不带编译时不带openssl库那么无法访问https的网页,从网页端什么也获取不到。
    在这里插入图片描述以下是图片内容的翻译:
    在这里插入图片描述
  • 如上图所示:之前安装的libcurl库不支持https的访问,所以将原先安装的libcurl库删掉,就把_install这个文件夹删掉即可,然后重新编译安装,编译的时候记得先安装openssl库,就安装在默认位置/usr/local/lib/usr/lib下面即可,这样编译libcurl库的时候不用指定ssl库的路径了。安装openssl库的时候可以从官网下载,也可以使用指令:wget https://www.openssl.org/source/openssl-1.1.1a.tar.gz进行下载,wget 是linux的开源工具,可以从网页上下载内容。
    在这里插入图片描述
  • 下载完成后,tar vxf openssl-1.1.1l.tar.gz解压文件后,文件夹里面的风格和其他库的内容差不多,首先阅读README查看这个库的一些信息,然后得知库的安装和编译要查看INSTALL文件,如下图所示,可知使用指令:./configmakesudo make install可以进行默认位置的编译和安装。如果想指定位置则使用指令:./config --prefix=/home/fhn/httphandler/openssl/opssl1(主要包含库文件和头文件之类的) --openssldir=/home/fhn/httphandler/openssl/opssl2(主要包含一些配置文件,如果不写这个将会在opssl1下面创建ssl文件夹去放这些配置文件)其中–prefix选项是配置安装目录,如果不配置该选项,安装后可执行文件默认放在/usr /local/bin,库文件默认放在/usr/local/lib,配置文件默认放在/usr/local/etc,其它的资源文件放在/usr /local/share,比较凌乱。如果配置了–prefix,如: ./config --prefix=/usr/local/test1安装后的所有资源文件都会被放在/usr/local/test目录中,不会分散到其他目录。使用–prefix选项的另一个好处是方便卸载软件或移植软件, 当某个安装的软件不再需要时,只须简单的删除该安装目录,就可以把软件卸载干净;移植软件只需拷贝整个目录到另外一个机器即可(相同的操作系统下)。
    在这里插入图片描述
    在这里插入图片描述在这里插入图片描述
  • openssl安装好后,就可以进行支持https的libcurl库的安装了,使用指令:./configure --prefix=$pwd/_install --with-sslmakesudo make install进行安装编译,然后现在的环境就支持了https网页的访问。再次使用指令进行编译即可:gcc demo2.c -o demo2 -I ~/httphandler/curl-7.71.1/_install/include -L ~/httphandler/curl-7.71.1/_install/lib/ -lcurl

base64编码:

  • Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。可查看RFC2045~RFC2049,上面有MIME的详细规范。Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。采用Base64编码具有不可读性,需要解码后才能阅读。Base64由于以上优点被广泛应用于计算机的各个领域,然而由于输出内容中包括两个以上“符号类”字符(+, /, =),不同的应用场景又分别研制了Base64的各种“变种”。为统一和规范化Base64的输出,Base62x被视为无符号化的改进版本。总结:就是一种传输格式。
  • 相让图片传到网页端首先要将它转化为base64编码的格式,然后进行上传,liinux有一个自带的编码装换工具,使用指令:base64 图片路径就可以将图片转化为base64编码在http环境下进行传输
  • cookie文件: cookie是一种程序,当它放到硬盘后,就成为一个扩展名为TXT的纯文本文件。curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "/tmp/cookie.txt"); // 指定cookie文件
    关于Cookie的一些选项:
    CURLOPT_COOKIE:用来指定一个Cookie,用来在之后的http请求中发送这个Cookie。
    CURLOPT_COOKIEFILE:告诉libcurl激活cookie引擎,然后读取指定文件来初始化Cookie,只读。
    CURLOPT_COOKIEJAR:告诉libcurl激活cookie引擎,当easy handle被关闭,保存所有已知的Cookie到cookie jar文件,只写。
    CURLOPT_COOKIELIST:提供单个的Cookie加入内部的Cookie存储引擎。可以传递http头格式也可以传递netscape 格式。这个也可以用来刷新Cookies。
    CURLINFO_COOKIELIST:将Cookie信息从内部Cookie存储里导出,导出格式为链表。
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS,postString); // 指定post内容;传递给 CURLOPT_POSTFIELDS 的应该是形如name1=var1&name2=var2,在使用 CURLOPT_POSTFIELDS 时,您不需要使用 CURLOPT_POST 。在这种情况下,请求方法将始终设置为POST,c调用libcurl库POST请求。

然后进行虚拟机上面的代码编写:

#include <unistd.h>
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
#include <curl/curl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define true 1
#define false 0
int i=0;
long long int  size;
typedef unsigned int bool;
size_t readData( void *ptr, size_t size, size_t nmemb, void *stream) //回调函数
{char* buf2;char buf3[100]={'\0'};char buf[1024]={'\0'};strncpy(buf,ptr,1024);buf2=strstr(buf,"CDATA");buf2=buf2+6;strncpy(buf3,buf2,9);if(strstr(buf,"是")!=NULL){printf("是同一个人\n");}else{printf("不是同一个人\n");}printf("置信度为:%s\n",buf3);
}
char* makeBase64(char* str1,char* str2)//第一个参数是模板文件的地址,第二个参数是传入文件的地址
{char* sourceimg;char* type1;char* type2;int sourcefd;type1=(char*)malloc(strlen(str1)+50);type2=(char*)malloc(strlen(str2)+50);memset(type1,'\0',strlen(str1)+50);memset(type2,'\0',strlen(str2)+50);sprintf(type1,"base64 %s > %s",str1,str2);sprintf(type2,"rm %s",str2);sourcefd=open(str2,O_RDWR|O_CREAT,0600);system(type1);size=lseek(sourcefd,0,SEEK_END);sourceimg=(char*)malloc(size+2);memset(sourceimg,'\0',size+2);lseek(sourcefd,0,SEEK_SET);//重新让光标回到文件头部read(sourcefd,sourceimg,size);close(sourcefd);if(i>=1)system(type2);i=i+1;if(i==10)i=i-9;return sourceimg;
}
bool postUrl()
{CURL *curl;CURLcode res;int typeId=21;char* img1;char* img2;char* format="xml";        //返回格式(xml或者json),如果format为空,则默认返回xml char* postString;char* key="翔云平台获取";char* secret="翔云平台获取";img1=makeBase64("/home/fhn/httphandler/img/2019270100013390_0_1.jpg","/home/fhn/httphandler/img/source");img2=makeBase64("/home/fhn/httphandler/img/2019289045205325_0_1.jpg","/home/fhn/httphandler/img/compare");int len=strlen(key)+strlen(secret)+sizeof(typeId)+strlen(format)+strlen(img1)+strlen(img2);postString=(char*)malloc(len);memset(postString,'\0',len);sprintf(postString,"&img1=%s&img2=%s&key=%s&secret=%s&typeId=%d&format=%s",img1,img2,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); //当有数据回来的时候调用回调函数res = curl_easy_perform(curl);curl_easy_cleanup(curl);}free(img1);free(img2);return true;
}
int main()
{postUrl();
}

树莓派简单配置CSI摄像头:

  • 测试环境: 硬件:树莓派3B/3B+、系统:Raspberry Debian 9 / Debian 10、已安装好CSI摄像头的树莓派。

  • 首先使用"ls"指令来查看是否存在vchiq设备节点(如果没有,则可能是内核或者设备硬件存在问题,可尝试重刷系统或更换硬件):
    在这里插入图片描述

  • 运行"vcgencmd get_camera"查看当前摄像头是否可用,如果detected=0,说明摄像头模块没接好,重新排查下硬件。detected=1则说明CSI摄像头接入正常。supported=1说明摄像头已经使能,摄像头已经可以使用。supported=1则说明CSI摄像头没有使能。需要使能下摄像头模块。
    在这里插入图片描述

  • 运行"sudo raspi-config"命令使能树莓派CSI摄像头:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 有些程序采用V4L2编程,会访问到/dev/videoX设备,因此需要添加UVC驱动,针对树莓派3B/3B+可以采用如下的方法添加bcm2835-v4l2驱动:

pi@raspberrypi:~$ vim.tiny /etc/modules
# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.i2c-dev
bcm2835-v4l2

在这里插入图片描述

  • 运行raspistill -o ~/seeFace/image.jpg即可成功拍照并保存,可选择保存路径,更多参数使用raspistill --help

  • 移除从原代码安装的程序、删除库就在源代码哪里执行sudo make uninstall

然后在树莓派上面操作和虚拟机相同的操作(先编译、安装支持库,然后编写代码):

  • 在树莓派上面输入指令:sudo apt install libssl-devsudo apt install libcurl4-openssl-dev 即可快速安装libcurl和openssl库,可以不使用在虚拟机那样方法,但是我没有尝试这个方法。
  • 我在树莓派上使用的是在虚拟机那样的方法,遇到了很多问题,大概就是找不到库吧,解决过程中:sudo apt-get update(该命令会访问源列表里的每个网址,并读取软件列表,然后保存在本地电脑。)、sudo apt-get upgrade(该命令,会把本地已安装的软件,与刚下载的软件列表里对应软件进行对比,如果发现已安装的软件版本太低,就会提示你更新。)然而并没有什么卵用,问题如下:
    在这里插入图片描述
  • 最终将在树莓派上装的openssl库libcurl库使用指令:sudo make uninstall卸载,然后重新安装openssl库并且这次安装的是下图的版本,就可以编译并且使用了(但不知道具体原因)。
    在这里插入图片描述
  • 过程中还遇到树莓派摄像头出现下面错误:
mmal mmal_vc_component_create failed to create component 'vc ril camera' (1:ENOMEM)
mmal mmal_component_create_core could not create component 'vc ril camera' (1) mmal Failed to create camera component
mmal main Failed to create camera component
mmal Camera is not detected. Please check carefully the camera module is installed correctly
  • 解决: 使用指令:vcgencmd get_camera查看是否能识别设备,出现结果:supported=1 detected=0, 说明只有输出,并没有检测到设备,然后使用指令:sudo raspi-config进入到树莓派基本设置界面,将Camera Enable、SSH Enable、VNC Enable、SPI Enable、I2C Enable、Serial Enable、1-Wire Enable再次检测出现下列情况问题就解决:supported=1 detected=1
    在这里插入图片描述
    在这里插入图片描述

使用树莓派播放音频文件:

  • 登录树莓派,打开终端,执行sudo raspi-config命令

  • 选择第7项Advanced Options高级选项 在这里插入图片描述

  • 选择第4项Audio音频
    在这里插入图片描述

  • 可以看到有三种声音配置,(1)【Auto】-自动选择;(2)【Force 3.5mm (‘headphone’) jack】-从3.5毫米(“耳机”)插孔输出;(3)【Force HDMI 】-从HDMI输出
    在这里插入图片描述

安装音乐播放软件:

  • 要保证树莓派可以正常连接网络,我们使用的omxplayer音乐播放软件需要从网络下载安装
  • 输入指令sudo apt-get install omxplayer,下载安装omxplayer
  • 进入MP3文件夹,使用omxplayer -o local mp3文件地址播放音乐, -o: Output device must be local',hdmi’, both' oralsa’

树莓派安装中文输入法:

  • 安装中文字库:
sudo apt update
sudo apt install -y ttf-wqy-zenhei
  • 安装中文输入法:
sudo apt install -y scim-pinyin
  • 切换语言环境:sudo raspi-config按方向键选择【localisation options】
    在这里插入图片描述
  • 选择【Change Locale】
    在这里插入图片描述
  • 按方向键往下翻,直到找到"zh_CN UTF-8" , 按下空格键将其打上*号,回车
    在这里插入图片描述
  • 选择语言环境"zh_CN UTF-8"
    在这里插入图片描述
  • 配置完成,重启树莓派:sudo shutdown -r now
  • 另外,如果用vim编辑保存出现“no write since last change",无法保存,可以先退出,然后重新进入编辑,保存时指定编码方式,如下:w ++enc=utf-8
  • 因为我使用的SecureCRT,所以还要将终端界面配置为中文编码:
    在这里插入图片描述

然后进行代码的编写(人脸识别成功后,播报语音,控制继电器):

#include <unistd.h>
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
#include <curl/curl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <wiringPi.h>
#define true 1
#define JD 25
#define false 0
int i=0;
long long int size;
typedef unsigned int bool;
void gpioInit()
{pinMode(JD,OUTPUT);digitalWrite(JD,HIGH);
}
size_t readData( void *ptr, size_t size, size_t nmemb, void *stream)
{char* buf2;float believe;char buf3[100]={'\0'};char buf[1024]={'\0'};strncpy(buf,ptr,1024);printf("%s\n",buf);buf2=strstr(buf,"CDATA");buf2=buf2+6;strncpy(buf3,buf2,3);believe=(float)atof(buf3);if(believe>0.6){system("omxplayer -o local ~/seeFace/img/success.mp3");digitalWrite(JD,LOW);}else{system("omxplayer -o local ~/seeFace/img/fail.mp3");}
}
char* makeBase64(char* str1,char* str2)
{char* sourceimg;char* type1;char* type2;int sourcefd;type1=(char*)malloc(strlen(str1)+50);type2=(char*)malloc(strlen(str2)+50);memset(type1,'\0',strlen(str1)+50);memset(type2,'\0',strlen(str2)+50);sprintf(type1,"base64 %s > %s",str1,str2);sprintf(type2,"rm %s",str2);sourcefd=open(str2,O_RDWR|O_CREAT,0600);system(type1);size=lseek(sourcefd,0,SEEK_END);sourceimg=(char*)malloc(size+20);memset(sourceimg,'\0',size+20);lseek(sourcefd,0,SEEK_SET);read(sourcefd,sourceimg,size+20);close(sourcefd);if(i>=1){system(type2);}i=i+1;if(i==10){i=i-9;}return sourceimg;
}
bool postUrl()
{CURL *curl;CURLcode res;int typeId=21;char* img1=NULL;char* img2=NULL;char* format="xml";char* postString;char* key="平台获取";char* secret="平台获取";img1=makeBase64("/home/pi/seeFace/img/imagesource.jpg","/home/pi/seeFace/img/source");img2=makeBase64("/home/pi/seeFace/img/image.jpg","/home/pi/seeFace/img/compare");int len=strlen(key)+strlen(secret)+sizeof(typeId)+strlen(format)+strlen(img1)+strlen(img2);postString=(char*)malloc(len);memset(postString,'\0',len);sprintf(postString,"&img1=%s&img2=%s&key=%s&secret=%s&typeId=%d&format=%s",img1,img2,key,secret,typeId,format);curl = curl_easy_init();if (curl){curl_easy_setopt(curl, CURLOPT_POSTFIELDS,postString);curl_easy_setopt(curl, CURLOPT_URL, "https://netocr.com/api/faceliu.do");curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, readData);res = curl_easy_perform(curl);curl_easy_cleanup(curl);}free(img1);free(img2);return  true;
}
int main()
{int i=wiringPiSetup();if(i==-1){printf("GPIO Init fail\n");}gpioInit();system("raspistill -t 1000 -o ~/seeFace/img/image.jpg");system("convert -resize 1024x768 ~/seeFace/img/image.jpg ~/seeFace/img/image.jpg");postUrl();
}   
  • 使用指令:gcc face.c -o face -I /home/pi/libcurl/curl-7.71.1/_install/include -L /home/pi/libcurl/curl-7.71.1/_install/lib/ -lcurl -lwiringPi编译后出现问题:
    在这里插入图片描述
  • 官网查阅错误代码含义:
    在这里插入图片描述
  • 然后尝试缩小图片分辨率,再次进行尝试,然后即可正常访问。
  • 使用工具convert进行图片分辨率的改变
  • 使用指令:sudo apt install imagemagick进行安装convert的工具包imagemagick
  • 然后使用指令:convert -resize 1024×768 被改图片地址 改后的图片地址1024×768中间的是小写的x。

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

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

相关文章

Shell脚本中函数返回值的用法笔记

函数的返回值又可以称为函数的退出状态&#xff0c;实际上可以理解为一种通信方式。Shell脚本中函数可以使用返回值的方式把调用的结果信息反馈给调用者。便于调用者可以根据反馈的结果做相应处理。说明&#xff1a;函数的返回值主要使用 return 关键字来处理。这和很多编程语言…

python 怎么取对数_概率矩阵分解(PMF)及MovieLens上的Python代码

首先对Probabilistic Matrix Factorization这篇论文的核心公式进行讲解和推导&#xff1b;然后用Python代码在Movielens数据集上进行测试实验。一、 背景知识文中作者提到&#xff0c;传统的协同过滤算法有两个不足&#xff1a;1).不能很好地处理规模非常大的数据&#xff1b;2…

JAVA SE、EE、ME,JRE、JDK,基本数据类型,访问修饰符、函数、封装的概念、UML类图、构造方法、this关键字、static关键字、方法重载、方法重写、包(packahe)

运行第一个JAVA程序&#xff1a; 这里使用的开发环境是eclipse&#xff0c;新建一个java工程&#xff0c;然后可以看到src这个是存放java代码的地方&#xff0c;然后在src文件右击新建一个class&#xff08;类&#xff09;&#xff0c;然后可以看到下图&#xff0c;同样和C语言…

unity中如何解决镜头穿透模型?

设置相机的Near clip plane,调小一点,但是不要给负数就行。 转载于:https://www.cnblogs.com/ZeroMurder/p/5331174.html

Shell脚本中函数位置参数的用法笔记

位置参数主要是用于调用函数的时候有时候需要传递参数&#xff0c;有很大的比例都是需要调用函数的时候动态传递参数&#xff0c;从而实现相应的功能。比如我想要计算两个数的和&#xff0c;可以通过函数是实现&#xff0c;需要定义两个参数作为计算的值。这样的计算两个数的函…

生鲜配送小程序源码_生鲜社区团购配送系统小程序源码搭建平台模式

生鲜配送系统开发&#xff0c;找【金生157威6875店2419同号】生鲜配送模式开发&#xff0c;生鲜配送软件开发&#xff0c;生鲜配送APP开发&#xff0c;生鲜配送平台开发平台&#xff0c;生鲜配送系统源码开发平台&#xff0c;生鲜配送系统平台&#xff0c;生鲜配送系统定制开发…

继承的概念和实现 、 super关键字 、 Object常见方法、抽象类、接口、模板方法模式、成员内部类、匿名内部类

这篇博客将会涉及到&#xff1a; 继承的概念和实现super关键字方法重写—OverrideObject常见方法 继承的概念&#xff1a; 生活中&#xff0c;继承的概念随处可见&#xff0c;继承需要符合的关系&#xff1a;is-a&#xff1b;父类更通用、子类更特殊更具体。就比如说&#x…

盘点关于程序员的10个有趣的段子

&#xff08;1&#xff09;程序员的读书历程&#xff1a;x 语言入门 —> x 语言应用实践 —> x 语言高阶编程 —> x 语言的科学与艺术 —> 编程之美 —> 编程之道 —> 编程之禅—> 颈椎病康复指南。&#xff08;2&#xff09;程序员最讨厌的四件事&#x…

Linux 用户管理命令笔记

目录 1、新增用户 2、删除用户 3、修改用户 4、修改用户密码 1、新增用户 useradd user1 用户创建流程 1、系统先将用户信息记录在/etc/passwd中&#xff0c;一般会在/etc/passwd和/etc/shadow末尾,同时分配该用户UID。 2、创建用户目录&#xff0c;一般创建路径/home目录中。…

tomcat依赖导入步骤_Tomcat长生不老之术——嵌入式

前言Tomcat是一个非常流行的Web服务器&#xff0c;用于部署和运行Java Web应用程序。一般情况下&#xff0c;我们都是在单独的Tomcat实例上运行自己的Web应用&#xff0c;其实与这种经典方案相比&#xff0c;我们可以将服务器运行时直接集成到应用程序中&#xff0c;从而更加的…

Linux用户组笔记整理

目录 一、Linux用户组概念 二、常用命令 三、用户组信息存储位置 一、Linux用户组概念 Linux用户组&#xff08;group&#xff09;就是具有相同操作权限范围的Linux用户管理起来&#xff1b; 比如有时我们要让同一类用户具有相同的权限&#xff0c;比如查看、修改某一文件或执…

Linux文件操作实用笔记

Linux系统遵循一切皆是操作文件的规则。所以想用好Linux系统&#xff0c;就必须要掌握文件相关的操作。 1、创建文件命令&#xff1a;touch 语法格式&#xff1a; touch filename #filename 文件名称。 比如 touch hello.txt就会在当前木创建一个hello.txt的文件。 说明&#x…

安装完CentOS 7 后必做的七件事

CentOS是最多人用来运行服务器的 Linux 版本&#xff0c;最新版本是 CentOS 7。当你兴趣勃勃地在一台主机或 VPS 上安装 CentOS 7 后&#xff0c;首要的工作肯定是加强它的安全性&#xff0c;以下列出的七件事&#xff0c;是你进一步配置系统和安装其他软件前必须做的。 1. 更改…

python显示小数点后几位数_python窗口编程-3:数位处理(整数)

我们在上一次课程中(python窗口编程-2&#xff1a;风格与布局 )&#xff0c;制作了完整的计算器窗口界面&#xff0c;只是那个窗口没有真正的功能&#xff0c;是点击任何按钮都会关闭。这一次&#xff0c;我们加入一些事件处理的功能&#xff0c;让它成为一个正常工作的窗口程序…

Linux文件目录基础笔记

1、进入目录名称&#xff1a;cdcd命令主要是方便用户切换到不同目录的指令。比如&#xff1a;cd #只执行cd命令默认进入root的根目录cd /home #进入home目录&#xff0c;如果home目录有testdir目录的话&#xff0c;可以执行 cd testdir 进入testdir目录。2、创建目录命令&#…