不用自己训练模型,也能进行 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);
45 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;
910 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 }
1516 rt_kprintf(“webclient send get request by simplify request interface.
”);
17 rt_kprintf(“webclient get response data:
”);
1819 for (index = 0; index 《 rt_strlen(request); index++)
20 {
21 rt_kprintf(“%c”, request[index]);
22 }
23 rt_kprintf(“
”);
2425 cjson_parse = cjson_parse(request);
26 if(cjson_parse == rt_null)
27 {
28 log_e(“parse fail.
”);
29 goto __exit;
30 }
3132 cjson_token = cjson_getobjectitem(cjson_parse, “access_token”);
33 if (cjson_token == rt_null)
34 {
35 log_e(“get onject ‘access_token’ item fail.
”);
36 goto __exit;
37 }
3839 log_d(“get_token: %s
”, cjson_token-》valuestring);
40 token_len = rt_strlen(cjson_token-》valuestring);
41 rt_memcpy(token, cjson_token-》valuestring, token_len);
4243__exit:
4445 if (cjson_parse)
46 {
47 cjson_delete(cjson_parse);
48 cjson_parse = rt_null;
49 cjson_token = rt_null;
50 }
5152 if (request)
53 {
54 web_free(request);
55 }
5657 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];
910 while (bytes_len--)
11 {
12 char_array_3[i++] = *(bytes_to_encode++);
1314 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;
2021 for(i = 0; i 《 4; i++)
22 {
23 encode[encode_size++] = base64_chars[char_array_4[i]];
24 }
25 i = 0;
26 }
27 }
2829 if (i)
30 {
31 for (j = i; j 《 3; j++)
32 {
33 char_array_3[j] = ‘’;
34 }
3536 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;
4041 for(j = 0; (j 《 i + 1); j++)
42 {
43 encode[encode_size++] = base64_chars[char_array_4[j]];
44 }
4546 while ((i++ 《 3))
47 {
48 encode[encode_size++] = ‘=’;
49 }
50 }
5152 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;
100101 case ’,‘ :
102 new_data[i++] = ’%‘;
103 new_data[i++] = ’2‘;
104 new_data[i++] = ’c‘;
105 break;
106107 case ’;‘ :
108 new_data[i++] = ’%‘;
109 new_data[i++] = ’3‘;
110 new_data[i++] = ’b‘;
111 break;
112113 case ’=‘ :
114 new_data[i++] = ’%‘;
115 new_data[i++] = ’3‘;
116 new_data[i++] = ’d‘;
117 break;
118119 case ’%‘ :
120 new_data[i++] = ’%‘;
121 new_data[i++] = ’2‘;
122 new_data[i++] = ’5‘;
123 break;
124125 case ’ ‘ :
126 new_data[i++] = ’%‘;
127 new_data[i++] = ’2‘;
128 new_data[i++] = ’0‘;
129 break;
130131 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.
”);
11 result = -rt_enomem;
12 goto __exit;
13 }
1415 /* 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 }
2223 /* add http header */24 webclient_header_fields_add(session, “content-length: %d
”, post_data_size);
25 webclient_header_fields_add(session, “content-type: application/x-www-form-urlencoded
”);
2627 /* 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.
”, resp_status);
31 result = -rt_error;
32 goto __exit;
33 }
3435 rt_kprintf(“webclient post response data:
”);
36 do37 {
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 }
4748 } while (1);
4950 rt_kprintf(“
”);
5152__exit:
53 if (session)
54 {
55 webclient_close(session);
56 }
5758 if (buffer)
59 {
60 web_free(buffer);
61 }
6263 return result;
64}
华为FreeBuds无线耳机:亲近每一对爱听的耳朵!
谷歌正式推出Chrome OS Flex系统 华为支付发布最新进展
关于GD32F403系列高性能基本型Cortex®-M4 MCU的性能分析
三星Galaxy S11e疑似入网 后置三摄竖排放置及25W充电功率
未来的自主机器人表明情感表达可以塑造合作
如何在APT-Pi上实现图像识别功能
开放式创新生态实力尽显 海尔智家模式备受认可
现代生物技术发展
PLC在电气自动控制系统中的应用
一文让你透彻理解模电
三星将开始递送Note 7死亡升级,升级后将无法再充电
全新体验,首发适配!一加手机极速尝鲜ColorOS 13.1
芯昇科技有限公司亮相ICDIA 助力RISC-V生态发展
Core I2C的原理及采用FPGA技术实现I2C IP核的设计
一分钟让你知道什么是OTP语音芯片
晶体管工作的条件和晶体管工作状态的判断
固定式可燃气体报警器检定中的标定方法
诺基亚任命新掌门人能否进一步巩固市场地位
Fluke TiS75+/55+红外热像仪重磅上市:精度升级,重构清晰
10.6.4 非平衡格林函数∈《集成电路产业全书》