目录
一、翔云人工智能开放平台
下面通过人工智能OCR识别平台翔云的使用,掌握调库调API开发的一般步骤,其他的平台也基本类似。
开发示例下载
C++示例代码
strPostData.Format(_T("img=%s&key=%s&secret=%s&typeId=%d&format=xml"),strImageBase64,strKey,strSecret,nTypeID);
java示例代码
java大多直接调库,非常简洁,这也是它开发效率高的原因之一。
二、编译openSSL支持libcurl的https访问
那是因为在编译libcurl库的时候,由于翔云接口是https:开头的,需要选择支持SSL。
./configure --with -ssl
我们访问的接口是https开头的,要进行身份验证和数据加密的,体现在我们的key和secret。
那我们就要回到/curl-7.71.1
路径下,删除rm _install -rf
上次编译出来的文件夹,重新编译支持SSL的库。由/docs/INSTALL.md
我们可以得知要想支持SSL,就得./configure --with-ssl
./configure --prefix=$PWD/_install --with-ssl
编译错误
cheking for SSL_connect in -lssl... (cached)no no
configure:error:openSSL libs and/or directories were not found where specified!
安装SSL依赖库openSSL(使用工具wget)
想要支持SSL必须要有依赖库,需要系统中已经安装好了SSL。
我们需要安装openSSL.tar
利用linux的开源工具下载:wget是Linux中的一个下载文件的工具,wget是在Linux下开发的开放源代码的软件。
百度搜索技巧:wget openSSL.tar
wget https://www.openssl.org/source/openssl-1.1.1a.tar.gz
tar xvf openssl-1.1.1a.tar.gz
进入文件夹,直接去看他的INSTALL。
为了避免到时候编译这个curl又要去配置SSL这个库,我们直接把SSL安装到默认的系统位置去(一般默认是在/usr/local底下),所以不指定安装路径了,直接
在/openssl-1.1.1a
路径下,配置
./config
make
sudo make install
要加 sudo因为肯定安装在了 usr/local 中,非工作目录无权限
curl库重新配置,编译,安装
回到/curl-7.71.1/
目录下重新进行配置:
./configure --prefix=$PWD/_install --with-ssl
make
make install
三、编程实现人脸识别
翔云人脸识别API文档
OCR.c
#include <stdio.h>
#include <curl/curl.h>
#include <string.h>
#include <stdlib.h>
typedef unsigned int bool;//数据类型别名用typedef
#define true 1 //宏定义用define 就是宏替换
#define false 0
//回调函数,读取从OCR后台返回的数据 前面打通百度的例子是将内容读取到本地文件fd里面
size_t readData(void *ptr, size_t size, size_t nmemb, void *stream)
{
char buf[1024] = {'\0'};
strncpy(buf,ptr,1024);
printf("============================= get data ===========================\n");
printf("%s\n",buf);
}
bool postUrl() //根据文档,接口调用方法为post请求
{
CURL *curl;
CURLcode res;
char* postString;//野指针,要开辟空间
//根据翔云平台的接口要求 分开定义,然后字符串拼接
char* img1 = NULL; //图片base64流
char* img2 = NULL;
char* key = "Tnf7EDJaQ1qFZkow29xxxx";
char* secret = "66d49fdbfd4944ec93035f14ea14xxxx";
int typeId = 21;
char* format = "xml";
postString = (char* )malloc(strlen(key)+strlen(secret)+2048);
sprintf(postString,"img1=%s&img2=%s&key=%s&secret=%s&typeId=%d&format=%s","","",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");// 指定url
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,readData); //回调函数读取返回值
res = curl_easy_perform(curl);
printf("OK:%d\n",res);
curl_easy_cleanup(curl);
}
return true;
}
int main(void)
{
postUrl();
}
gcc OCR.c -I ./curl-7.71.1/_install/include/ -L ./curl-7.71.1/_install/lib/ -lcurl
运行
可以看到已经收到了翔云后台的反馈:
加入图片base64编码
Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,可用于在HTTP环境下传递较长的标识信息。
在Linux下生成图片的base64编码
base64 photo.jpg
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开辟的空间地址还在,我拿到了这块地址,就能读
}
人脸识别完整代码
OCR.c
#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>
typedef unsigned int bool;//数据类型别名用typedef
#define true 1 //宏定义用define 就是宏替换
#define false 0
char ocrRetBuf[1024] = {'\0'};//全局变量,用来接收从OCR后台返回的数据
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开辟的空间地址还在,我拿到了这块地址,就能读
}
bool postUrl() //根据文档,接口调用方法为post请求
{
CURL *curl;
CURLcode res;
//根据翔云平台的接口要求 分开定义,然后字符串拼接
char* base64BufPic1 = getBase64FromFile("./aobama1.jpg");//图片base64流
char* base64BufPic2 = getBase64FromFile("./aobama2.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");// 指定url
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,readData); //回调函数读取返回值
res = curl_easy_perform(curl);
printf("OK:%d\n",res);
if(strstr(ocrRetBuf,"否") != NULL){ //字符串检索 判断翔云后台返回的一大堆字符串中有没有“否”
printf("不是同一个人\n");
}
else{
printf("是同一个人\n");
}
curl_easy_cleanup(curl);
}
return true;
}
int main(void)
{
postUrl();
return 0;
}
gcc OCR.c -I ./curl-7.71.1/_install/include/ -L ./curl-7.71.1/_install/lib/ -lcurl
智能家居项目目录
智能家居(5) —— 智能家居项目整合(语音控制线程,网络控制线程、烟雾报警线程)
网络编程知识预备(2) —— 三次握手与四次挥手、半连接状态、2MSL
网络编程知识预备(3) —— TCP流量控制(滑动窗口)、拥塞控制
网络编程知识预备(4) —— SOCKET、TCP、HTTP之间的区别与联系
网络编程知识预备(5) —— 了解应用层的HTTP协议与HTTPS协议
网络编程知识预备(6) —— libcurl库简介及其编程访问百度首页
智能家居(7) —— 人脸识别 & 翔云平台编程使用(编译openSSL支持libcurl的https访问、安装SSL依赖库openSSL)