ESP32利用百度智能云实现图像识别 文字识别
在我的Kevincoooool/ESP_MASTER (gitee.com)项目中用到了百度AI识别,来讲讲实现过程。
1、通过esp32获取jpg图像
int baidu_img_ai(void)
{char *base64_buf = NULL;char *urlcode_buf = NULL;camera_fb_t *fb = NULL;esp_err_t res = ESP_OK;size_t _jpg_buf_len = 0;uint8_t *_jpg_buf = NULL;char *url_buf = malloc(sizeof(char) * 512);ESP_LOGE(TAG, "baidu Start");ESP_LOGE(TAG, "Taking picture...");camera_fb_t *pic = esp_camera_fb_get();if (!pic){ESP_LOGE(TAG, "esp_camera_fb_get failed...");esp_camera_deinit();free(url_buf);url_buf = NULL;return;}if (!fmt2jpg(pic->buf, pic->width * pic->height * 3, pic->width, pic->height, PIXFORMAT_RGB565, 80, &_jpg_buf, &_jpg_buf_len)){ESP_LOGE(TAG, "fmt2jpg failed");return ESP_FAIL;}ESP_LOGE(TAG, "Picture taken! Its size was: %zu bytes", _jpg_buf_len);/* base64编码 */base64_buf = base64_encode(_jpg_buf, _jpg_buf_len);ESP_LOGE(TAG, "base64_encode OK,size: %d", strlen(base64_buf));urlcode_buf = malloc(sizeof(char) * strlen(base64_buf) * 2);URLEncode(base64_buf, strlen(base64_buf), urlcode_buf, strlen(base64_buf) * 2);ESP_LOGE(TAG, "urlencode OK,size: %d", strlen(urlcode_buf));/* 开始上传百度AI */esp_http_client_config_t config = {//.url = BAIDU_WEB_URL,.event_handler = img_http_event_handler,.buffer_size = 4 * 1024,.timeout_ms = 4000,};sprintf(url_buf, "https://aip.baidubce.com/rest/2.0/image-classify/%s?access_token=%s", detect_class[0], img_access_token);config.url = url_buf;printf("URL: %s\n", config.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_header(client, "Accept", "*/*");esp_http_client_set_header(client, "Accept-Encoding", "identity");esp_http_client_set_header(client, "User-Agent", "PostmanRuntime/7.24.1");esp_http_client_set_header(client, "Connection", "keep-alive");esp_http_client_set_header(client, "Content-Type", "application/x-www-form-urlencoded");esp_http_client_set_post_field(client, urlcode_buf, strlen(urlcode_buf));esp_err_t err = esp_http_client_perform(client);if (err == ESP_OK){ESP_LOGE(TAG, "HTTP POST Status = %d, content_length = %d",esp_http_client_get_status_code(client),esp_http_client_get_content_length(client));esp_http_client_cleanup(client);free(base64_buf);free(urlcode_buf);base64_buf = NULL;urlcode_buf = NULL;free(url_buf);url_buf = NULL;// esp_camera_deinit();ESP_LOGE(TAG, "baidu End");}else{lv_label_set_text(label_speech, "识别出错!");ESP_LOGE(TAG, "HTTP POST request failed: %d", err);esp_http_client_cleanup(client);free(base64_buf);free(urlcode_buf);base64_buf = NULL;urlcode_buf = NULL;free(url_buf);url_buf = NULL;// esp_camera_deinit();ESP_LOGE(TAG, "baidu End");}return;
}
2、把jpg图像进行base64编码
/** @Descripttion : * @version : * @Author : Kevincoooool* @Date : 2021-01-07 14:40:25* @LastEditors : Kevincoooool* @LastEditTime : 2021-07-07 18:24:01* @FilePath : \esp-idf\pro\KSDIY_ESPCAM\main\baidu\base64.c*/
/*base64.c*/
#include "base64.h"//定义base64编码表
#define base64_table "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"char *base64_encode(uint8_t *str, uint32_t img_len)
{long len;long str_len;char *res = NULL;int i, j;//计算经过base64编码后的字符串长度str_len = img_len;if (str_len % 3 == 0)len = str_len / 3 * 4;elselen = (str_len / 3 + 1) * 4;res = malloc(sizeof(char) * len + 1);res[len] = '\0';//以3个8位字符为一组进行编码for (i = 0, j = 0; i < len - 2; j += 3, i += 4){res[i] = base64_table[str[j] >> 2]; //取出第一个字符的前6位并找出对应的结果字符res[i + 1] = base64_table[(str[j] & 0x3) << 4 | (str[j + 1] >> 4)]; //将第一个字符的后位与第二个字符的前4位进行组合并找到对应的结果字符res[i + 2] = base64_table[(str[j + 1] & 0xf) << 2 | (str[j + 2] >> 6)]; //将第二个字符的后4位与第三个字符的前2位组合并找出对应的结果字符res[i + 3] = base64_table[str[j + 2] & 0x3f]; //取出第三个字符的后6位并找出结果字符}switch (str_len % 3){case 1:res[i - 2] = '=';res[i - 1] = '=';break;case 2:res[i - 1] = '=';break;}return res;
}uint8_t *base64_decode(uint8_t *code)
{//根据base64表,以字符找到对应的十进制数据int table[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0,63, 52, 53, 54, 55, 56, 57, 58,59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0,1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,13, 14, 15, 16, 17, 18, 19, 20, 21,22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 26,27, 28, 29, 30, 31, 32, 33, 34, 35,36, 37, 38, 39, 40, 41, 42, 43, 44,45, 46, 47, 48, 49, 50, 51};long len;long str_len;uint8_t *res;int i, j;//计算解码后的字符串长度len = strlen((const char *)code);//判断编码后的字符串后是否有=if (strstr((const char *)code, "=="))str_len = len / 4 * 3 - 2;else if (strstr((const char *)code, "="))str_len = len / 4 * 3 - 1;elsestr_len = len / 4 * 3;res = malloc(sizeof(uint8_t) * str_len + 1);res[str_len] = '\0';//以4个字符为一位进行解码for (i = 0, j = 0; i < len - 2; j += 3, i += 4){res[j] = ((uint8_t)table[code[i]]) << 2 | (((uint8_t)table[code[i + 1]]) >> 4); //取出第一个字符对应base64表的十进制数的前6位与第二个字符对应base64表的十进制数的后2位进行组合res[j + 1] = (((uint8_t)table[code[i + 1]]) << 4) | (((uint8_t)table[code[i + 2]]) >> 2); //取出第二个字符对应base64表的十进制数的后4位与第三个字符对应bas464表的十进制数的后4位进行组合res[j + 2] = (((uint8_t)table[code[i + 2]]) << 6) | ((uint8_t)table[code[i + 3]]); //取出第三个字符对应base64表的十进制数的后2位与第4个字符进行组合}return res;
}
3、将base64编码后的结果再进行urlcode编码
/** @Descripttion : * @version : * @Author : Kevincoooool* @Date : 2021-01-07 15:05:22* @LastEditors : Kevincoooool* @LastEditTime : 2021-01-12 09:07:22* @FilePath : \n_esp-adf\1_take_pic_http_to_cloud\main\urlcode.c*/
#include <stdio.h>
#include <string.h>
/*** @brief URLEncode 对字符串URL编码** @param str 原字符串* @param strSize 原字符串长度(不包括最后的\0)* @param result 结果缓冲区的地址* @param resultSize 结果缓冲区的大小(包括最后的\0)** @return: >0:resultstring 里实际有效的长度* 0: 解码失败.*/
int URLEncode(const char *str, const int strSize, char *result, const int resultSize)
{int i;int j = 0; //for result indexchar ch;if ((str == NULL) || (result == NULL) || (strSize <= 0) || (resultSize <= 0)){return 0;}result[0] = 'i';result[1] = 'm';result[2] = 'a';result[3] = 'g';result[4] = 'e';result[5] = '=';j=6;for (i = 0; (i < strSize) && (j < resultSize); ++i){ch = str[i];if (((ch >= 'A') && (ch < 'Z')) ||((ch >= 'a') && (ch < 'z')) ||((ch >= '0') && (ch < '9'))){result[j++] = ch;}else if (ch == ' '){result[j++] = '+';}else if (ch == '.' || ch == '-' || ch == '_' || ch == '*'){result[j++] = ch;}else{if (j + 3 < resultSize){sprintf(result + j, "%%%02X", (unsigned char)ch);j += 3;}else{return 0;}}}result[j] = '\0';return j;
}
4、获取百度AI的密钥
进入图像识别-百度AI开放平台 (baidu.com)
成功创建后的页面,默默把“API Key”和“Secret Key”复制下来,后面的调用需要用到。
5、获取access_token
把“API Key”和“Secret Key”复制到以下链接的两处进入即可获得
https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=API Key&client_secret=Secret Key
6、通过client http上传到百度
7、获取识别结果进行cjson字符串解析
static esp_err_t img_http_event_handler(esp_http_client_event_t *evt)
{//printf("evtid = %d\n", evt->event_id);switch (evt->event_id){case HTTP_EVENT_ERROR:ESP_LOGI(TAG, "HTTP_EVENT_ERROR");break;case HTTP_EVENT_ON_CONNECTED:ESP_LOGI(TAG, "HTTP_EVENT_ON_CONNECTED");break;case HTTP_EVENT_HEADER_SENT:ESP_LOGI(TAG, "HTTP_EVENT_HEADER_SENT");break;case HTTP_EVENT_ON_HEADER:ESP_LOGI(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);break;case HTTP_EVENT_ON_DATA:printf("HTTP_EVENT_ON_DATA, len=%d\n", evt->data_len);printf("%.*s\n", evt->data_len, (char *)evt->data);cJSON *json_root = cJSON_Parse((char *)evt->data);cJSON *result_num = cJSON_GetObjectItem(json_root, "result_num");printf("result_num = %d\n", result_num->valueint);if (result_num->valueint == 0){cJSON_Delete(json_root);return ESP_OK;}cJSON *result = cJSON_GetObjectItem(json_root, "result");cJSON *result1 = cJSON_GetArrayItem(result, 0);cJSON *keyword = cJSON_GetObjectItem(result1, "keyword");printf("keyword = %s\n", keyword->valuestring);strcpy((char *)detect_things, keyword->valuestring);char now_time[256];sprintf((char *)now_time, "识别到:%s", keyword->valuestring);lv_label_set_text(label_speech, now_time);vTaskDelay(2000);if (json_root != NULL){cJSON_Delete(json_root);}break;case HTTP_EVENT_ON_FINISH:ESP_LOGI(TAG, "HTTP_EVENT_ON_FINISH");break;case HTTP_EVENT_DISCONNECTED:ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED");break;}return ESP_OK;
}
ESP32利用百度智能云实现图像识别 文字识别相关推荐
- python图像识别步骤_利用百度智能云结合Python体验图像识别(转载来自qylruirui)
利用百度智能云结合Python体验图像识别 只要注册了百度账号就可以轻松体验百度智能云中图像识别功能的魅力! 1. 所需要的工具 一个百度账号(大家都有哈) 一个可以运行python代码的编译器(Py ...
- python 菜品识别_利用百度智能云结合Python体验图像识别(来自qylruirui)
利用百度智能云结合Python体验图像识别 只要注册了百度账号就可以轻松体验百度智能云中图像识别功能的魅力! 1. 所需要的工具 一个百度账号(大家都有哈) 一个可以运行python代码的编译器(Py ...
- ESP32接入百度智能云语音识别,实现在线语音识别
一.概述 使用ESP32接入百度智能云实现在线语音识别.实现最基本的语音识别功能还是很简单的,但还是遇到了一些小问题,在这记录一下. 使用了max9814麦克风模块用做语音输入,一个按键来控制 ...
- 人脸识别(1)----百度智能云接入人脸离别识别SDK(离线采集SDK) 开通文字识别服务
人脸识别(1)----百度智能云接入人脸离别识别SDK(离线采集SDK)&& 开通文字识别服务 1.打开百度智能云的官网,进行登录,https://console.bce.baidu. ...
- PHP对接百度智能云接口 (植物识别)
在项目中需要对接一个 百度智能云的 接口 植物识别 写在这里记录一下 1账号 账号的参数 这里就不多说了 之前有一篇文章中有过简单的介绍 可以去之前发表的文章 去看一下 账号需要设置的东西 或者流程 ...
- 【云AI】利用百度智能云,实现人像动漫化
- Python 利用百度智能云进行短语音识别
# -*- coding: utf-8 -*- """ Created on Sat Dec 4 16:52:28 2021@author: Tu Xiaopeng &q ...
- 【python】调用百度智能云API实现手写文字识别
注:本文系湛江市第十七中学星火创客团队及岭南师范学院物联网俱乐部原创部分参赛项目,转载请保留声明 文章目录 调用百度智能云API实现python识别手写文字 一.准备工具 电脑端准备: 1.pytho ...
- 百度智能云AI接口的植物识别
文章目录 一个10学时的课程作业 一.在百度智能云(https://cloud.baidu.com/)注册账号并实名认证 二.获取接口 1.在用户中心的产品服务中选择图像识别 2.获取accessTo ...
- 百度智能云携手领悦助力宝马中国数字化转型
百度智能云与华晨宝马旗下全资子公司领悦数字信息技术有限公司(以下简称领悦)正式签约,利用百度智能云在人工智能领域的技术优势,双方将在智能客服领域展开合作,共同推动宝马中国业务的数字化升级. 领悦成立于 ...
最新文章
- 什么是数据结构,为什么我们需要数据结构?
- 用非递归方式实现二叉树先序便利
- Ubuntu16.04中php如何切换版本
- coap python3_node-coap入门(三)——Observe
- 统计问题(HDU-2563)
- 常用数据挖掘算法举例(上)
- 几道Java基础面试题
- 【目录】吴恩达深度学习
- Typescript无法导入json的问题
- spss入门——简单的数据预处理到时间序列分析系列(六)
- woff文件 服务器上找不到,vue Iview 项目部署到服务器上woff2文件 net::ERR_ABORTED 404 (Not Found)怎么处理?...
- 启动界面、封面图片、Splash关不掉,一直转圈,无法进入
- WOS(一)——文献高级检索
- 拓嘉辰丰:拼多多运营方法和技巧
- 五、Linux系统中的权限管理
- 设置全局css/less/sass样式and优化与style-resources-loader的理解
- 关于form与表单提交
- RPG冒险类游戏:矮人The Dwarves for Mac中文版(支持m1)
- Error: Unknown command: cask
- ps基本操作以及盒子综合案例、圆角边框、盒子阴影、文字阴影
热门文章
- 【开发工具集】重复代码检查工具——simian
- 新塘单片机烧写器_ICP Programming Tool
- Matlab图例Legend多行排布、字体格式
- Cadence Allegro PCB设计88问解析(十二) 之 Allegro中两种单位显示设置
- 输出100以内的素数
- matlab中做出球面和圆柱面,用matlab作出抛物柱面y^2=x和平面x+z=1相交的图形具体步骤...
- 增程式混合动力汽车Cruise整车仿真模型 串联混合动力仿真 基于Cruise平台搭建整车部件等动力学模型
- matlab代码注释方法--单行多行
- 使用python bloomfilter实现大文本去重
- python股票查询系统_使用Python查询股票所属行业