前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >在RT-Thread的ART-PI平台,进行图片识别

在RT-Thread的ART-PI平台,进行图片识别

作者头像
Rice加饭
发布2022-05-10 17:47:13
3430
发布2022-05-10 17:47:13
举报
文章被收录于专栏:Rice嵌入式

摘要

  • 最近在完成2020年没有完成的一个DIY项目,去年年底整个人有点泄气,导致一直搁置的。现在重新把他做好
  • 因为项目DIY项目中想引入图片识别,但是我的DIY作品不方便使用烧录等,所以我想用ART-PI来进行调试测试。
  • 这个功能取决于强大的RT-THREAD软件包,只需要勾勾选选,就可以实现了。

图片识别实现

开发环境:
代码语言:javascript
复制
- 平台:rt-thread的ART-PI。
- 软件包:webclient-v2.1.2,cjson-v1.0.2,mbedtls-v2.7.10。
- 图片识别平台:百度云平台。
百度云平台
  • 我的这个图片识别,是依赖百度云平台提供的图片识别API。
  • 步骤:
  1. 需要注册一个百度云账号。
  1. 然后选择人工智能->图片识别。
  1. 百度云提供不同类别的API,而我这里选择了通用物体和场景识别
  1. 点击技术文档
  1. 技术文档中,百度云提供了通用物体和场景识别API的详细说明:①HTTP方法:post。②请求URL。③URL参数:token和header。④百度云提供了不同语言的开发实例。而我们使用的是基于RTT来开发,所以需要对其进行造轮子(可以根据bash的实例来了解)。
  1. bash的例子:
代码语言:javascript
复制
curl -i -k 'https://aip.baidubce.com/rest/2.0/image-classify/v2/advanced_general?access_token=【调用鉴权接口获取的token】' --data 'image=【图片Base64编码,需UrlEncode】' -H 'Content-Type:application/x-www-form-urlencoded'
  • 注意:需要注意的是图片需要进行Base64编码和UrlEncode
rt-thread代码实现:
  • 增加软件:webclient-v2.1.2,cjson-v1.0.2,mbedtls-v2.7.10
  • 通过HTTP方法:get获取token。
  1. token的获取方法可以看百度云的教程,如下:
  1. 需要AK(API Key)和SK(Secret Key)
代码语言:javascript
复制
curl -i -k 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=【百度云应用的AK】&client_secret=【百度云应用的SK】'
  1. AK和SK获取方式,需要通过创建一个应用,以个人的方式创建。
  1. rt-thread代码实现获取token
代码语言:javascript
复制

#define GET_TOKEN_URI "http://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=[填入自己的AK]&client_secret=[填入自己SK]"

void rp_get_token(void)
{
    char *response = RT_NULL;
    char *uri = RT_NULL;

    uri = web_strdup(GET_TOKEN_URI);

    if (webclient_request(uri, RT_NULL, RT_NULL, (unsigned char **)&response) < 0)
    {
        rt_kprintf("get image fail!\n");
        return -RT_ERROR;
    }

    image_info->root = cJSON_Parse(response);

    if(image_info->root != RT_NULL)
    {
        image_info->token = cJSON_GetObjectItem(image_info->root, "access_token");
        rt_kprintf("token : %s\n", image_info->token->valuestring);
    }
}
  1. Base64编码函数:
代码语言:javascript
复制
const char * base64char = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char *base64_encode(char *bindata, char *base64, int binlength)
{
    int i, j;
    unsigned char current;

    for ( i = 0, j = 0 ; i < binlength ; i += 3 )
    {
        current = (bindata[i] >> 2) ;
        current &= (unsigned char)0x3F;
        base64[j++] = base64char[(int)current];

        current = ( (unsigned char)(bindata[i] << 4 ) ) & ( (unsigned char)0x30 ) ;
        if ( i + 1 >= binlength )
        {
            base64[j++] = base64char[(int)current];
            base64[j++] = '=';
            base64[j++] = '=';
            break;
        }
        current |= ( (unsigned char)(bindata[i+1] >> 4) ) & ( (unsigned char) 0x0F );
        base64[j++] = base64char[(int)current];

        current = ( (unsigned char)(bindata[i+1] << 2) ) & ( (unsigned char)0x3C ) ;
        if ( i + 2 >= binlength )
        {
            base64[j++] = base64char[(int)current];
            base64[j++] = '=';
            break;
        }
        current |= ( (unsigned char)(bindata[i+2] >> 6) ) & ( (unsigned char) 0x03 );
        base64[j++] = base64char[(int)current];

        current = ( (unsigned char)bindata[i+2] ) & ( (unsigned char)0x3F ) ;
        base64[j++] = base64char[(int)current];
    }
    base64[j] = '\0';
    return 0;
}
  1. 图片UrlEncode:
代码语言:javascript
复制
static rt_bool_t is_non_symbol(char c)
{
    if(c == '\0') return 1;
    int c_int = (int)c;
    return (c_int >= 48 && c_int <= 57) || (c_int >= 65 && c_int <= 90) || (c_int >= 97 && c_int <= 122);
}

char *url_encode(const char *input)
{
    int end = strlen(input);
    size_t final_size = (end * 3) + 1;
    char *working = rt_malloc(final_size);
    char *output = working;
    if(working == NULL)
    {
        rt_kprintf("working malloc failed\n");
    }

    while(*input)
    {
        const char c = *input;
        if(c < 0)
        {
            input++;
        }
        else if(is_non_symbol(c))
        {
            *working++ = *input++;
        }
        else
        {
            char encoded[4] = {0};
            snprintf(encoded, 4, "%%%02X", c);

            *working++ = encoded[0];
            *working++ = encoded[1];
            *working++ = encoded[2];
            input++;
        }
    }

    *working = 0;
    //psram_free(working);
    return output;
}
  1. rt-thread实现图片识别结果请求
代码语言:javascript
复制
void rp_get_image_result(void)
{
    rt_uint8_t *image_tag = "image=";
    // 获取图片编码后的数据
    rt_uint8_t *image_base64 = pic_base64("./flash/fish.jpg");
    rt_uint32_t image_tag_len = 0;
    rt_uint32_t image_base64_len = 0;
    rt_uint8_t *params = RT_NULL;

    image_tag_len = strlen(image_tag);
    image_base64_len = strlen(image_base64);

    params = rt_malloc(image_tag_len + image_base64_len);

    // 拼接HTTP请求格式中的(--data) 的数据 
    rt_memcpy(params, image_tag, image_tag_len);
    rt_memcpy(params + image_tag_len, image_base64, image_base64_len);

    char *image_uri = RT_NULL;
    char *header = RT_NULL;
    char *image_result = RT_NULL;
    int index = 0;

    image_uri = web_strdup(GET_IMAGE_RESULT_URI);

    // HTTP header数据
    webclient_request_header_add(&header, "Content-Length: %d\r\n", image_tag_len + image_base64_len);
    webclient_request_header_add(&header, "Content-Type: application/x-www-form-urlencoded\r\n");

    // HTTP POST
    if (webclient_request(image_uri, (const char *)header, params, (unsigned char **)&image_result) < 0)
    {
        rt_kprintf("webclient send post request failed.");
        web_free(header);
        return -RT_ERROR;
    }

    // 答应返回结果
    for (index = 0; index < rt_strlen(image_result); index++)
    {
        rt_kprintf("%c", image_result[index]);
    }
    rt_kprintf("\n");
}
  1. 测试图片:
  1. 测试结果:
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-03-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Rice 嵌入式开发技术分享 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 摘要
  • 图片识别实现
    • 开发环境:
      • 百度云平台
        • rt-thread代码实现:
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档