[ESP32]:基于HTTP实现百度AI识图

[ESP32]:基于HTTP实现百度AI识图

测试环境:

  • esp32-s3
  • esp idf 5.1

首先,先配置sdk,可以写入到sdkconfig.defaults

CONFIG_IDF_TARGET="esp32s3"
CONFIG_IDF_TARGET_ESP32S3=y

CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"

CONFIG_ESP_TLS_INSECURE=y
CONFIG_ESP_TLS_SKIP_SERVER_CERT_VERIFY=y

这里关闭了认证,并且建了分区表来存放我们待识别的图片。

1.百度控制台调试

1.获取token

在这里插入图片描述

2.在线调试,看下传输过程

在这里插入图片描述

主要关注如下内容:

header:

{
    "Accept": "application/json",
    "Content-Type": "application/x-www-form-urlencoded"
}

body:

image=%2F9j%2F4AAQSkZJRgABAQEBLAEsAAD%2F2wBDAAUEBAUEAwUFBAUGBgUGCA4JCAcHCBEMDQoO...

其中imge图像要先base64编码,在url编码

2.esp32调试

我们这里主要参考esp http client的代码

1.base64编码

esp-idf中已经有base64编码的代码,我们include一下即可

#include "mbedtls/base64.h"

int mbedtls_base64_encode(unsigned char *dst, size_t dlen, size_t *olen,
                          const unsigned char *src, size_t slen)
2.url编码

这个要自己实现一下

int url_encode(const unsigned char *src, size_t slen, size_t *olen, unsigned char *dst, size_t dlen)
{
    size_t i, j = 0;

    // clac encoed size
    for (i = 0; i < slen; i++)
    {
        if ((src[i] >= 'A' && src[i] <= 'Z') ||
            (src[i] >= 'a' && src[i] <= 'z') ||
            (src[i] >= '0' && src[i] <= '9') ||
            src[i] == '-' || src[i] == '_' || src[i] == '.' || src[i] == '~')
        {
            j++;
        }
        else if (src[i] == ' ')
        {
            j++;
        }
        else
        {
            j += 3; // length of %xx is three
        }
    }

    // check buffer size
    if (dlen < j + 1)
    {
        *olen = j + 1; // reytun need size
        return -1;
    }

    // url encode
    for (i = 0, j = 0; i < slen; i++)
    {
        if ((src[i] >= 'A' && src[i] <= 'Z') ||
            (src[i] >= 'a' && src[i] <= 'z') ||
            (src[i] >= '0' && src[i] <= '9') ||
            src[i] == '-' || src[i] == '_' || src[i] == '.' || src[i] == '~')
        {
            dst[j++] = src[i];
        }
        else if (src[i] == ' ')
        {
            dst[j++] = '+';
        }
        else
        {
            dst[j++] = '%';
            dst[j++] = "0123456789ABCDEF"[src[i] >> 4];
            dst[j++] = "0123456789ABCDEF"[src[i] & 0x0F];
        }
    }

    // add end
    dst[j] = '\0';

    // return size
    *olen = j;

    return 0;
}
3.添加http client的调用
 char post_url[1024] = {0};
    esp_http_client_config_t config = {
        .method = HTTP_METHOD_POST,
        .event_handler = app_http_baidu_event_handler,
        .buffer_size = 4 * 1024,
    };
    sprintf(post_url, "%s?access_token=%s", base_url, access_token);
    config.url = post_url;
    esp_http_client_handle_t client = esp_http_client_init(&config);
    esp_http_client_set_method(client, HTTP_METHOD_POST);
    esp_http_client_set_post_field(client, img_params, strlen(img_params)); //填入url编码后的图像数据
    esp_http_client_set_header(client, "Content-Type", "application/x-www-form-urlencoded");
    esp_err_t err = esp_http_client_perform(client);
    if (err == ESP_OK)
    {
        ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %d", esp_http_client_get_status_code(client), (int)esp_http_client_get_content_length(client));
    }
    else
    {
        ESP_LOGI(TAG, "HTTP GET request failed: %s", esp_err_to_name(err));
    }
    esp_http_client_cleanup(client);
4.整体代码
#include "app_baidu.h"
#include "mbedtls/base64.h"
#include "esp_http_client.h"
#include "esp_log.h"
#include "esp_heap_caps.h"
#include "string.h"

static const char *TAG = "HTTP_BAIDU";

char access_token[256] = "xxxx"; //更换自己的token
char base_url[256] = "https://aip.baidubce.com/rest/2.0/image-classify/v2/advanced_general";

esp_err_t app_http_baidu_event_handler(esp_http_client_event_t *evt)
{
    if (evt->event_id == HTTP_EVENT_ON_DATA)
    {
        ESP_LOGI(TAG, "%s",(char *)evt->data);
    }

    return ESP_OK;
}

int url_encode(const unsigned char *src, size_t slen, size_t *olen, unsigned char *dst, size_t dlen)
{
    size_t i, j = 0;

    // clac encoed size
    for (i = 0; i < slen; i++)
    {
        if ((src[i] >= 'A' && src[i] <= 'Z') ||
            (src[i] >= 'a' && src[i] <= 'z') ||
            (src[i] >= '0' && src[i] <= '9') ||
            src[i] == '-' || src[i] == '_' || src[i] == '.' || src[i] == '~')
        {
            j++;
        }
        else if (src[i] == ' ')
        {
            j++;
        }
        else
        {
            j += 3; // length of %xx is three
        }
    }

    // check buffer size
    if (dlen < j + 1)
    {
        *olen = j + 1; // reytun need size
        return -1;
    }

    // url encode
    for (i = 0, j = 0; i < slen; i++)
    {
        if ((src[i] >= 'A' && src[i] <= 'Z') ||
            (src[i] >= 'a' && src[i] <= 'z') ||
            (src[i] >= '0' && src[i] <= '9') ||
            src[i] == '-' || src[i] == '_' || src[i] == '.' || src[i] == '~')
        {
            dst[j++] = src[i];
        }
        else if (src[i] == ' ')
        {
            dst[j++] = '+';
        }
        else
        {
            dst[j++] = '%';
            dst[j++] = "0123456789ABCDEF"[src[i] >> 4];
            dst[j++] = "0123456789ABCDEF"[src[i] & 0x0F];
        }
    }

    // add end
    dst[j] = '\0';

    // return size
    *olen = j;

    return 0;
}

// base64 encode: http://www.yzcopen.com/img/imgbase64
// url encode: https://www.jyshare.com/front-end/695/?
void app_baidu_classification(char *img_buf, int file_size)
{
    char *img_base64 = NULL;
    char *img_params = NULL;
    char *img_base64_url = NULL;
    char *img_params_format = "image=%s";
    size_t img_base64_size = 0;
    size_t img_base64_url_size = 0;

    // base64 encode
    mbedtls_base64_encode(NULL, 0, &img_base64_size, (const unsigned char *)img_buf, file_size);
    ESP_LOGI(TAG, "Image size after bash64:%zu", img_base64_size);

    img_base64 = heap_caps_calloc(1, img_base64_size + 1, MALLOC_CAP_DMA);
    if (img_base64 == NULL)
    {
        ESP_LOGI(TAG, "Memory image bash64 allocation failed");
        return;
    }
    mbedtls_base64_encode((unsigned char *)img_base64, img_base64_size + 1, &img_base64_size, (const unsigned char *)img_buf, file_size);

    // url encode
    url_encode((const unsigned char *)img_base64, img_base64_size, &img_base64_url_size, NULL, 0);
    ESP_LOGI(TAG, "Image size after url:%zu", img_base64_url_size);

    img_base64_url = heap_caps_calloc(1, img_base64_url_size + 1, MALLOC_CAP_DMA);
    if (img_base64_url == NULL)
    {
        ESP_LOGI(TAG, "Memory image bash64 url allocation failed");
        free(img_base64);
        return;
    }
    url_encode((const unsigned char *)img_base64, img_base64_size, &img_base64_url_size, (unsigned char *)img_base64_url, img_base64_url_size + 1);

    // set data params
    img_params = heap_caps_calloc(1, img_base64_url_size + 1 + strlen(img_params_format), MALLOC_CAP_DMA);
    if (img_params == NULL)
    {
        ESP_LOGI(TAG, "Memory image params allocation failed");
        free(img_base64);
        free(img_base64_url);
        return;
    }

    sprintf(img_params, img_params_format, img_base64_url);

    // http client setting

    char post_url[1024] = {0};
    esp_http_client_config_t config = {
        .method = HTTP_METHOD_POST,
        .event_handler = app_http_baidu_event_handler,
        .buffer_size = 4 * 1024,
    };
    sprintf(post_url, "%s?access_token=%s", base_url, access_token);
    config.url = post_url;
    esp_http_client_handle_t client = esp_http_client_init(&config);
    esp_http_client_set_method(client, HTTP_METHOD_POST);
    esp_http_client_set_post_field(client, img_params, strlen(img_params));
    esp_http_client_set_header(client, "Content-Type", "application/x-www-form-urlencoded");
    esp_err_t err = esp_http_client_perform(client);
    if (err == ESP_OK)
    {
        ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %d", esp_http_client_get_status_code(client), (int)esp_http_client_get_content_length(client));
    }
    else
    {
        ESP_LOGI(TAG, "HTTP GET request failed: %s", esp_err_to_name(err));
    }
    esp_http_client_cleanup(client);

    free(img_base64);
    free(img_base64_url);
    free(img_params);
}

3.实验效果

拿了一张泰勒的图来识别

在这里插入图片描述

在这里插入图片描述

  • 11
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值