接着上一节人工智能翔云平台介绍:
人工智能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
文件,如下图所示,可知使用指令:./config
、make
、sudo 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-ssl
、make
、sudo 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-dev
、sudo 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 belocal',
hdmi’,both' or
alsa’
树莓派安装中文输入法:
- 安装中文字库:
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。