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

news2024/11/14 8:41:20

[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.实验效果

拿了一张泰勒的图来识别

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1539275.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue.config.js配置项

vue.config.js配置项 vue-cli3 脚手架搭建完成后&#xff0c;项目目录中没有 vue.config.js 文件&#xff0c;需要手动创建 创建vue.config.js vue.config.js(相当于之前的webpack.config.js) 是一个可选的配置文件&#xff0c;如果项目的 (和 package.json 同级的) 根目录中存…

数组不初始化带来的问题及解决、动态分配

C中数组不初始化会输出什么结果 在C中&#xff0c;如果你声明了一个数组但没有对其进行初始化&#xff0c;数组的元素将具有未定义的值。这意味着数组元素的值是不确定的&#xff0c;可能是垃圾值。 当你访问未初始化的数组元素时&#xff0c;可能会得到以下结果&#xff1a;…

力扣---全排列---回溯

思路&#xff1a; 递归做法&#xff0c;一般会有visit数组来判断第 i 位是否被考虑了。我们先考虑第0位&#xff0c;再考虑第1位&#xff0c;再考虑第2位...dfs函数中还是老套路&#xff0c;先判定特殊条件&#xff0c;再从当下的角度&#xff08;决定第 j 位是哪个元素&#x…

Docker 【通过Dockerfile构建镜像】【docker容器与镜像的关系】

文章目录 前言一、前期的准备工作二、上手构建一个简单的镜像三、DcokerFile1 指令总览2 指令详情 四、Dockerfile文件规范五、docker运行build时发生了什么?六、调试手段1. 修改镜像打包后&#xff0c;如何验证新内容已更新至镜像 七、Dockerfile优化方案 前言 docker构建镜…

优化选址问题 | 基于鹈鹕算法求解基站选址问题含Matlab源码

目录 问题代码问题 鹈鹕算法(Pelican Optimization Algorithm, POA)是一种相对较新的启发式优化算法,模拟了鹈鹕鸟觅食的行为。这种算法通常用于解决复杂的优化问题,如函数优化、路径规划、调度问题等。基站选址问题通常是一个复杂的优化问题,需要考虑覆盖范围、干扰、成…

AI修复老照片的一些参数设置

很久没更新CSDN文章了&#xff0c;这次给粉丝带来老照片修复流程 1>用ps修图 图章工具 笔刷 画笔修复 2>高清放大 3>lineattile 重绘 4>上色 具体可参考我的B站视频。 下面是一些笔记。 best quality,masterpiece,photorealistic,8k,ultra high res,solo,ext…

Fabric Measurement

Fabric Measurement 布料测量

通信网络设计[PTA]

文章目录 题目描述思路AC代码 题目描述 输入样例1 6 10 1 2 6 1 5 10 1 6 12 2 4 5 2 6 8 2 3 3 3 4 7 4 5 9 4 6 11 5 6 16 输出样例1 YES! Total cost:31输入样例2 5 4 1 2 3 1 3 11 2 3 8 4 5 9 输出样例2 NO! 1 part:1 2 3 2 part:4 5思路 最小生成树–kruskal算法 具体做法…

RbbitMQ使用教程

RabbitMQ 是一个可靠且成熟的消息传递和流代理&#xff0c;易于部署在云环境、本地和本地计算机上。它目前被全球数百万人使用。通过确认消息传递和跨集群复制消息的功能&#xff0c;您可以使用 RabbitMQ 确保您的消息是安全的。 RabbitMQ安装 推荐使用docker安装部署&#xf…

VMware Workstation Pro 17虚拟机超级详细搭建(含redis,nacos,docker)(一)

今天从零搭建一下虚拟机的环境&#xff0c;把nacos&#xff0c;redis等微服务组件还有数据库搭建到里面&#xff0c;首先看到的是我们最开始下载VMware Workstation Pro 17 之后的样子&#xff0c;总共一起应该有三部分因为篇幅太长了 下载地址 : VMware - Delivering a Digit…

pytest全局配置+前后只固件配置

pytest全局配置前后只固件配置 通过读取pytest.ini配置文件运行通过读取pytest.ini配置文件运行无条件跳过pytest.initest_mashang.pyrun.py 有条件跳过test_mashang.py pytest框架实现的一些前后置&#xff08;固件、夹具&#xff09;处理方法一&#xff08;封装&#xff09;方…

VUE3.0(一):vue3.0简介

Vue 3 入门指南 什么是vue Vue (发音为 /vjuː/&#xff0c;类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和JavaScript 构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;帮助你高效地开发用户界面。无论是简单还是复杂的界…

[ C++ ] STL---仿函数与priority_queue

目录 仿函数 示例一&#xff1a; 示例二 : 常见的仿函数 priority_queue简介 priority_queue的常用接口 priority_queue的模拟实现 基础接口 push() 堆的向上调整算法 堆的插入 pop() 堆的向下调整算法 堆的删除 priority_queue最终实现 仿函数 仿函数&#xff…

数据结构 - 二叉树非递归遍历

文章目录 前言一、前序二、中序三、后序 前言 本文实现二叉树的前中后的非递归遍历&#xff0c;使用栈来模拟递归。 文字有点简略&#xff0c;需要看图和代码理解 树节点&#xff1a; typedef char DATA; //树节点 typedef struct Node {DATA data; //数据struct Node* left…

MySQL进阶-----Linux系统安装MySQL

目录 前言 一、准备工作 1. 准备一台Linux服务器 2. 下载Linux版MySQL安装包 3. 上传MySQL安装包 二、安装操作指令 1. 创建目录,并解压 2.安装mysql的安装包 三、开启mysql与密码修改 1.启动MySQL服务 2. 查询自动生成的root用户密码 3.修改root用户密码 四、创…

【LeetCode】升级打怪之路 Day 26:回溯算法 — 集合划分问题

今日题目&#xff1a; 698. 划分为k个相等的子集 | LeetCode473. 火柴拼正方形 | LeetCode 参考文章&#xff1a; 经典回溯算法&#xff1a;集合划分问题 目录 LC 698. 划分为k个相等的子集 【classic&#xff0c;有难度】数据预处理&#xff1a;计算 target基本回溯优化 1&…

限时免费!Unity 资源商店威尔房间精品资源等你来领!

Unity 资源商店威尔房间精品资源分享 资源介绍资源特色免费领取 Unity 商店资源&#xff1a;Will’s Room Environment, Dormitory Room Environment 免费获取。 资源介绍 好消息来啦&#xff01;Unity 资源商店的威尔房间精品资源正在限时免费中&#xff01;这是一个非常受欢迎…

一维前缀和一维差分(下篇讲解二维前缀和二维差分)(超详细,python版,其他语言也很轻松能看懂)

本篇博客讲解一维前缀和&#xff0c;一维差分&#xff0c;还会给出一维差分的模板题&#xff0c;下篇博客讲解 二维前缀和&二维差分。 一维前缀和&#xff1a; 接触过算法的小伙伴应该都了解前缀和&#xff0c;前缀和在算法中应用很广&#xff0c;不了解也没有关系&#…

【算法】小强爱数学(迭代公式+数论取模)

文章目录 1. 问题2. 输入3. 输出4. 示例5. 分析6. 思路7. 数论&#xff0c;取模相关公式8. 数论&#xff0c;同余定理9. 代码 1. 问题 小强发现当已知 x y B xyB xyB以及 x y A xyA xyA时,能很轻易的算出 x n x_ {n} xn​ y n y_ {n} yn​ 的值.但小强想请你在已知A和B的…

【No.16】蓝桥杯动态规划下|线性DP装箱问题|计数DP0/1背包的方案数|过河卒|完全背包小明的背包2|最长公共子序列|蓝桥骑士|推荐练习题(C++)

线性DP&#xff0c;0/1背包简化版&#xff0c;装箱问题 【题目描述】有一个箱子容量为V(正整数&#xff0c; 0 ≤ V ≤ 20000 0 \le V \le 20000 0≤V≤20000)&#xff0c;同时有n个物品( 0 < n ≤ 30 0 < n \le 30 0<n≤30)&#xff0c;每个物品有一个体积(正整数)。…