关键词:
开源地址:
https://github.com/liukangcc/ART-PI_BAIDUAI
不用自己训练模型,也能进行 AI 图像识别;借助百度云平台,我们可以在 APT-Pi 上实现图像识别功能。
创建图像识别应用
1、打开链接 百度智能云, 申请账号;
2、打开控制台
3、打开图像识别
4、创建应用
5、获取 AK 和 SK
通用图像识别
该请求用于通用物体及场景识别,即对于输入的一张图片(可正常解码,且长宽比适宜),输出图片中的多个物体及场景标签。
1、打开 image_classify.c 文件, 修改 access_token
, 填入应用的 AK 和 SK;
2、在 SD 卡中放入要识别的图片;
3、编译下载;
4、在终端输入命令: baidu_ai cat.jpg
5、加入百度百科,使能宏定义:#define BD_AI_BAIKE
,编译下载:
返回说明
返回参数
菜品识别
该请求用于菜品识别。即对于输入的一张图片(可正常解码,且长宽比适宜),输出图片的菜品名称、卡路里信息、置信度。
1、修改 URL 为菜品识别:
1 index = strlen(BAIDU_AI_API[1]);
2 post_uri_size = index;
3 post_uri = rt_malloc(256);
4
5 rt_memcpy(post_uri, BAIDU_AI_API[1], post_uri_size);
2、编译下载;
3、识别结果:
返回说明
返回参数
监控报表
在百度服务端,可以查看 API 调用成功和失败的次数:
图像格式
图像格式转换流程:
1、百度 AI 支持的图像格式有:PNG、JPG、JPEG、BMP
2、原始的图片数据需要转换为 base64 编码
3、base64 编码的图片数据进行百分比编码
Base64 编码
请求图片需经过base64编码
:图片的base64编码指将一副图片数据编码成一串字符串,使用该字符串代替图像地址。您可以首先得到图片的二进制,然后用Base64格式编码即可。
Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。可查看RFC2045~RFC2049,上面有MIME的详细规范。
Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。采用Base64编码具有不可读性,需要解码后才能阅读。
Base64由于以上优点被广泛应用于计算机的各个领域,然而由于输出内容中包括两个以上“符号类”字符(+, /, =),不同的应用场景又分别研制了Base64的各种“变种”。为统一和规范化Base64的输出,Base62x被视为无符号化的改进版本。
百分比编码
百分比编码 是一种拥有8位字符编码的编码机制,这些编码在URL的上下文中具有特定的含义。它有时被称为URL编码。编码由英文字母替换组成:“%” 后跟替换字符的ASCII的十六进制表示。
需要编码的特殊字符有:':','/','?','#','[',']','@','!','$','&',"'",'(',')','*','+',',',';','=',以及,'%'
` 本身.其他的字符虽然可以进行编码但是不需要。
':' '/' '?' '#' '[' ']' '@' '!' '$' '&' "'" '(' ')' '*' '+' ',' ';' '=' '%' ' '
%3A %2F %3F %23 %5B %5D %40 %21 %24 %26 %27 %28 %29 %2A %2B %2C %3B %3D %25 %20 或 +
根据上下文, 空白符 ’ ’ 将会转换为 ‘+’ (必须在HTTP的POST方法中使定义 application/x-www-form-urlencoded 传输方式), 或者将会转换为 ‘%20’ 的 URL。
图像识别流程
获取 token
1 /* get token */
2int get_ai_token(const char *uri, unsigned char *token)
3
4 char *request = RT_NULL;
5 int token_len = 0, index = 0;
6
7 cJSON* cjson_parse = RT_NULL;
8 cJSON* cjson_token = RT_NULL;
9
10 if (webclient_request(uri, RT_NULL, RT_NULL, (unsigned char **)&request) < 0)
11
12 rt_kprintf("webclient send get request failed.");
13 return -RT_ERROR;
14
15
16 rt_kprintf("webclient send get request by simplify request interface.\\n");
17 rt_kprintf("webclient get response data: \\n");
18
19 for (index = 0; index < rt_strlen(request); index++)
20
21 rt_kprintf("%c", request[index]);
22
23 rt_kprintf("\\n");
24
25 cjson_parse = cJSON_Parse(request);
26 if(cjson_parse == RT_NULL)
27
28 LOG_E("parse fail.\\n");
29 goto __exit;
30
31
32 cjson_token = cJSON_GetObjectItem(cjson_parse, "access_token");
33 if (cjson_token == RT_NULL)
34
35 LOG_E("get onject 'access_token' item fail.\\n");
36 goto __exit;
37
38
39 LOG_D("get_token: %s\\n", cjson_token->valuestring);
40 token_len = rt_strlen(cjson_token->valuestring);
41 rt_memcpy(token, cjson_token->valuestring, token_len);
42
43__exit:
44
45 if (cjson_parse)
46
47 cJSON_Delete(cjson_parse);
48 cjson_parse = RT_NULL;
49 cjson_token = RT_NULL;
50
51
52 if (request)
53
54 web_free(request);
55
56
57 return token_len;
58
图片数据编码
Base 64
1static const char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2
3/* encode image */
4int base64_encode(unsigned char * bytes_to_encode, unsigned char *encode, int bytes_len)
5
6 int i = 0, j = 0, encode_size = 0;
7 unsigned char char_array_3[3];
8 unsigned char char_array_4[4];
9
10 while (bytes_len--)
11
12 char_array_3[i++] = *(bytes_to_encode++);
13
14 if (i == 3)
15
16 char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
17 char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
18 char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
19 char_array_4[3] = char_array_3[2] & 0x3f;
20
21 for(i = 0; i < 4; i++)
22
23 encode[encode_size++] = base64_chars[char_array_4[i]];
24
25 i = 0;
26
27
28
29 if (i)
30
31 for (j = i; j < 3; j++)
32
33 char_array_3[j] = '\\0';
34
35
36 char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
37 char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
38 char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
39 char_array_4[3] = char_array_3[2] & 0x3f;
40
41 for(j = 0; (j < i + 1); j++)
42
43 encode[encode_size++] = base64_chars[char_array_4[j]];
44
45
46 while ((i++ < 3))
47
48 encode[encode_size++] = '=';
49
50
51
52 return encode_size;
53
百分比编码
1int http_percentage_coding(unsigned char *org_data, unsigned char *new_data, int len)
2
3 int i = 0;
4 unsigned char org_char = 0;
5
6 while (len--)
7
8 org_char = *(org_data++);
9 switch (org_char)
10
11 case ':' :
12 new_data[i++] = '%';
13 new_data[i++] = '3';
14 new_data[i++] = 'A';
15 break;
16
17 case '/' :
18 new_data[i++] = '%';
19 new_data[i++] = '2';
20 new_data[i++] = 'F';
21 break;
22
23 case '?' :
24 new_data[i++] = '%';
25 new_data[i++] = '3';
26 new_data[i++] = 'F';
27 break;
28
29 case '#' :
30 new_data[i++] = '%';
31 new_data[i++] = '2';
32 new_data[i++] = '3';
33 break;
34
35 case '[' :
36 new_data[i++] = '%';
37 new_data[i++] = '5';
38 new_data[i++] = 'B';
39 break;
40
41 case ']' :
42 new_data[i++] = '%';
43 new_data[i++] = '5';
44 new_data[i++] = 'D';
45 break;
46
47 case '@' :
48 new_data[i++] = '%';
49 new_data[i++] = '4';
50 new_data[i++] = '0';
51 break;
52
53 case '!' :
54 new_data[i++] = '%';
55 new_data[i++] = '2';
56 new_data[i++] = '1';
57 break;
58
59 case '$' :
60 new_data[i++] = '%';
61 new_data[i++] = '2';
62 new_data[i++] = '4';
63 break;
64
65 case '&' :
66 new_data[i++] = '%';
67 new_data[i++] = '2';
68 new_data[i++] = '6';
69 break;
70
71 case '\\'' :
72 new_data[i++] = '%';
73 new_data[i++] = '2';
74 new_data[i++] = '7';
75 break;
76
77 case '(' :
78 new_data[i++] = '%';
79 new_data[i++] = '2';
80 new_data[i++] = '8';
81 break;
82
83 case ')' :
84 new_data[i++] = '%';
85 new_data[i++] = '2';
86 new_data[i++] = '9';
87 break;
88
89 case '*' :
90 new_data[i++] = '%';
91 new_data[i++] = '2';
92 new_data[i++] = 'A';
93 break;
94
95 case '+' :
96 new_data[i++] = '%';
97 new_data[i++] = '2';
98 new_data[i++] = 'B';
99 break;
100
101 case ',' :
102 new_data[i++] = '%';
103 new_data[i++] = '2';
104 new_data[i++] = 'C';
105 break;
106
107 case ';' :
108 new_data[i++] = '%';
109 new_data[i++] = '3';
110 new_data[i++] = 'B';
111 break;
112
113 case '=' :
114 new_data[i++] = '%';
115 new_data[i++] = '3';
116 new_data[i++] = 'D';
117 break;
118
119 case '%' :
120 new_data[i++] = '%';
121 new_data[i++] = '2';
122 new_data[i++] = '5';
123 break;
124
125 case ' ' :
126 new_data[i++] = '%';
127 new_data[i++] = '2';
128 new_data[i++] = '0';
129 break;
130
131 default:
132 new_data[i++] = org_char;
133 break;
134
135
136 return i;
137
获取识别结果
1int get_ai_result(const char *uri, const char *post_data, int post_data_size)
2
3 struct webclient_session* session = RT_NULL;
4 unsigned char *buffer = RT_NULL;
5 int index, result = 0, resp_status, bytes_read;
6
7 buffer = (unsigned char *)web_malloc(POST_RESP_BUFSZ);
8 if (buffer == RT_NULL)
9
10 rt_kprintf("no memory for receive response buffer.\\n");
11 result = -RT_ENOMEM;
12 goto __exit;
13
14
15 /* create webclient session and set header response size */
16 session = webclient_session_create(POST_HEADER_BUFSZ);
17 if (session == RT_NULL)
18
19 result = -RT_ENOMEM;
20 goto __exit;
21
22
23 /* add http header */
24 webclient_header_fields_add(session, "Content-Length: %d\\r\\n", post_data_size);
25 webclient_header_fields_add(session, "Content-Type: application/x-www-form-urlencoded\\r\\n");
26
27 /* send POST request by default header */
28 if ((resp_status = webclient_post(session, uri, (const char *)post_data)) != 200)
29
30 LOG_E("webclient POST request failed, response(%d) error.\\n", resp_status);
31 result = -RT_ERROR;
32 goto __exit;
33
34
35 rt_kprintf("webclient post response data: \\n");
36 do
37
38 bytes_read = webclient_read(session, buffer, POST_RESP_BUFSZ);
39 if (bytes_read <= 0)
40
41 break;
42
43 for (index = 0; index < bytes_read; index++)
44
45 rt_kprintf("%c", buffer[index]);
46
47
48 while (1);
49
50 rt_kprintf("\\n");
51
52__exit:
53 if (session)
54
55 webclient_close(session);
56
57
58 if (buffer)
59
60 web_free(buffer);
61
62
63 return result;
64
你可以添加微信17775982065为好友,注明:公司+姓名,拉进RT-Thread官方微信交流群!
👇 点击阅读原文进入官网
python实现ai图像识别-身份证识别(代码片段)
...的这个身份识别主要是使用python+flask+华为云OCR进行实现的。步骤申请华为云OCR接口获取token调用身份证识别接口提取身份证信息申请华为云OCR接口图像识别主要使 查看详情
知物由学|只要5行代码,就可以实现ai图像识别(代码片段)
“知物由学”是网易云易盾打造的一个品牌栏目,词语出自汉·王充《论衡·实知》。人,能力有高下之分,学习才知道事物的道理,而后才有智慧,不去求问就不会知道。“知物由学”希望通过一篇篇技术干货、趋势解读、人... 查看详情
图像识别基于卷积神经网络cnn实现车牌识别matlab源码(代码片段)
过去几年,深度学习(Deeplearning)在解决诸如视觉识别(visualrecognition)、语音识别(speechrecognition)和自然语言处理(naturallanguageprocessing)等很多问题方面都表现出非常好的性能。在不同类型的深度神经网络当中,卷积... 查看详情
ai实战篇|基于ai开放平台实现货币识别功能,彻底解决货币盲区(代码片段)
🎬博客主页:https://xiaoy.blog.csdn.net🎥本文由呆呆敲代码的小Y原创,首发于CSDN🙉🎄学习专栏推荐:Unity系统学习专栏🌲游戏制作专栏推荐:游戏制作🌲Unity实战100例专栏推荐:Unity实战... 查看详情
基于opencv实现人脸识别案例(代码片段)
一、基础我们使用机器学习的方法完成人脸检测,首先需要大量的正样本图像(面部图像)和负样本图像(不含面部的图像)来训练分类器。我们需要从其中提取特征。下图中的Haar特征会被使用,就像我... 查看详情
计算机视觉(cv)基于高层api实现宝石分类(代码片段)
【计算机视觉(CV)】基于高层API实现宝石分类(文章目录)前言(一)、任务描述图像分类是根据图像的语义信息将不同类别图像区分开来,是计算机视觉中重要的基本问题宝石识别属于图像分类中的一个细分类问题实践平台:百度... 查看详情
ai常用框架和工具丨13.pytorch实现基于cnn的手写数字识别
代码实例,PyTorch实现基于CNN的手写数字识别,希望对您有所帮助。文章目录环境说明一、模型训练1.1导入相关依赖1.2选择使用的硬件1.3超参数配置1.4准备训练集和测试集1.5模型创建1.6模型评估指标1.7模型训练1.8模型测试1.9模型... 查看详情
ai常用框架和工具丨13.pytorch实现基于cnn的手写数字识别
代码实例,PyTorch实现基于CNN的手写数字识别,希望对您有所帮助。文章目录环境说明一、模型训练1.1导入相关依赖1.2选择使用的硬件1.3超参数配置1.4准备训练集和测试集1.5模型创建1.6模型评估指标1.7模型训练1.8模型测试1.9模型... 查看详情
ai常用框架和工具丨13.pytorch实现基于cnn的手写数字识别
代码实例,PyTorch实现基于CNN的手写数字识别,希望对您有所帮助。文章目录环境说明一、模型训练1.1导入相关依赖1.2选择使用的硬件1.3超参数配置1.4准备训练集和测试集1.5模型创建1.6模型评估指标1.7模型训练1.8模型测试1.9模型... 查看详情
ai实战篇|基于ai开放平台实现人脸识别对比功能,超详细教程附带源码(代码片段)
🎬博客主页:https://xiaoy.blog.csdn.net🎥本文由呆呆敲代码的小Y原创,首发于CSDN🙉🎄学习专栏推荐:Unity系统学习专栏🌲游戏制作专栏推荐:游戏制作🌲Unity实战100例专栏推荐:Unity实战... 查看详情
基于matlab的指纹识别算法仿真实现(代码片段)
...了一种图像预处理方案。在指纹特征提取部分,采用基于Matlab实现的指纹细节特征提取方法,并给出了去伪算法。指纹特征提取是从细化后的指纹图中得到细节 查看详情
项目实战解析:基于深度学习搭建卷积神经网络模型算法,实现图像识别分类(代码片段)
...通过项目开发实例,带领大家从零开始设计实现一款基于深度学习的图像识别算法。学习本章内容 查看详情
基于openpose实现人体动作识别(代码片段)
...随着计算机视觉的发展和在生活实践中的广泛应用,基于各种算法的行为检测和动作识别项目在实践中得到了越来越多的应用,并在相关领域得到了广泛的研究。在行为监测方面,不仅仅有通过图形、温湿度、声音等... 查看详情
《嵌入操作系统–玩转art-pi开发板》第9章基于select/poll实现并发服务器(代码片段)
基于Select/Poll实现并发服务器(一)9.3Select/Poll概述在LWIP中,如果要实现并发服务器,可以基于SequentaialAPI来实现,这种方式需要使用多线程,也就是为每个连接创建一个线程来处理数据。而在资源受限的... 查看详情
《嵌入操作系统–玩转art-pi开发板》第9章基于select/poll实现并发服务器(代码片段)
基于Select/Poll实现并发服务器(一)9.3Select/Poll概述在LWIP中,如果要实现并发服务器,可以基于SequentaialAPI来实现,这种方式需要使用多线程,也就是为每个连接创建一个线程来处理数据。而在资源受限的... 查看详情
computervision基于卷积神经网络实现美食分类(代码片段)
【ComputerVision】基于卷积神经网络实现美食分类@TOC前言任务描述如何根据据图像的视觉内容为图像赋予一个语义类别是图像分类的目标,也是图像检索、图像内容分析和目标识别等问题的基础。本实践旨在通过一个美食分类的案... 查看详情
基于百度ai开放平台的人脸识别及语音合成(代码片段)
基于百度AI的人脸识别及语音合成课题课题需求(1)人脸识别在Web界面上传人的照片,后台使用Java技术接收图片,然后对图片进行解码,调用云平台接口识别人脸特征,接收平台返回的人员年龄、性别、颜值等信息,将信息返... 查看详情
图像识别基于卷积神经网络(cnn)实现垃圾分类matlab源码(代码片段)
一、一、垃圾分类如何通过垃圾分类管理,最大限度地实现垃圾资源利用,减少垃圾处置量,改善生存环境质量,是当前世界各国共同关注的迫切问题之一。根据国家制定的统一标准,现在生活垃圾被广泛分... 查看详情