目录
一、祥云人工智能开放平台
二、编译openSSL支持libcurl的https访问
安装SSL依赖库openSSL(使用工具wget)
curl库重新配置,编译,安装
三、编程实现人脸识别
翔云人脸识别API文档
加入图片base64编码
人脸识别完整代码
下面通过人工智能OCR识别平台翔云的使用,掌握调库调API开发的一般步骤,其他的平台也基本类似。
开发示例下载
C++示例代码
strPostData.Format(_T("img=%s&key=%s&secret=%s&typeId=%d&format=xml"),strImageBase64,strKey,strSecret,nTypeID);
java示例代码
java大多直接调库,非常简洁,这也是它开发效率高的原因之一。
那是因为在编译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必须要有依赖库,需要系统中已经安装好了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-7.71.1/
目录下重新进行配置:
./configure --prefix=$PWD/_install --with-ssl
make
make install
OCR.c
#include
#include
#include
#include
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是网络上最常见的用于传输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
#include
#include
#include
#include
#include
#include
#include
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
智能家居(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) —— 香橙派摄像头加入设备工厂