2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > ESP32利用百度智能云实现图像识别 文字识别

ESP32利用百度智能云实现图像识别 文字识别

时间:2020-03-06 06:45:41

相关推荐

ESP32利用百度智能云实现图像识别 文字识别

在我的Kevincoooool/ESP_MASTER ()项目中用到了百度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, "/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 : -01-07 14:40:25* @LastEditors : Kevincoooool* @LastEditTime : -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 : -01-07 15:05:22* @LastEditors : Kevincoooool* @LastEditTime : -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开放平台 ()

成功创建后的页面,默默把“API Key”和“Secret Key”复制下来,后面的调用需要用到。

5、获取access_token

把“API Key”和“Secret Key”复制到以下链接的两处进入即可获得

/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;}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。