我有以下 ESP32CAM 草图,应该拍照并将其发布到 Clarify:
#include "Arduino.h"
#include "esp_camera.h"
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <base64.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
// Select camera model
//#define CAMERA_MODEL_WROVER_KIT // Has PSRAM
//#define CAMERA_MODEL_ESP_EYE // Has PSRAM
//#define CAMERA_MODEL_M5STACK_PSRAM // Has PSRAM
//#define CAMERA_MODEL_M5STACK_WIDE // Has PSRAM
#define CAMERA_MODEL_AI_THINKER // Has PSRAM
//#define CAMERA_MODEL_TTGO_T_JOURNAL // No PSRAM
//CAMERA_MODEL_AI_THINKER
#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 0
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27
#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 21
#define Y4_GPIO_NUM 19
#define Y3_GPIO_NUM 18
#define Y2_GPIO_NUM 5
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
const char* ssid = "mySSID";
const char* password = "myPass";
void setup() {
Serial.begin(115200);
Serial.setDebugOutput(true);
Serial.println();
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sscb_sda = SIOD_GPIO_NUM;
config.pin_sscb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
// if PSRAM IC present, init with UXGA resolution and higher JPEG quality
// for larger pre-allocated frame buffer.
if(psramFound()){
config.frame_size = FRAMESIZE_QVGA;
config.jpeg_quality = 10;
config.fb_count = 2;
} else {
config.frame_size = FRAMESIZE_QVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}
#if defined(CAMERA_MODEL_ESP_EYE)
pinMode(13, INPUT_PULLUP);
pinMode(14, INPUT_PULLUP);
#endif
// camera init
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Camera init failed with error 0x%x", err);
return;
}
#if defined(CAMERA_MODEL_M5STACK_WIDE)
s->set_vflip(s, 1);
s->set_hmirror(s, 1);
#endif
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
classifyImage();
Serial.println("\nSleep....");
esp_deep_sleep_start();
}
void loop(){
}
void classifyImage() {
String response;
// Capture picture
camera_fb_t * fb = NULL;
fb = esp_camera_fb_get();
if(!fb) {
Serial.println("Camera capture failed");
return;
} else {
Serial.println("Camera capture OK");
}
size_t size = fb->len;
String buffer = base64::encode((uint8_t *) fb->buf, fb->len);
String imgPayload = "{\"inputs\": [{ \"data\": {\"image\": {\"base64\": \"" + buffer + "\"}}}]}";
buffer = "";
// Uncomment this if you want to show the payload
Serial.println(imgPayload);
esp_camera_fb_return(fb);
// Generic model
String model_id = "General";
HTTPClient http;
http.begin("https://api.clarifai.com/v2/models/" + model_id + "/outputs");
http.addHeader("Content-Type", "application/json");
http.addHeader("Authorization", "c7f894790533332388e23d4d21278321");
int httpResponseCode = http.POST(imgPayload);
if(httpResponseCode>0){
Serial.print(httpResponseCode);
Serial.print(" Returned String: ");
Serial.println(http.getString());
} else {
Serial.print("POST Error: ");
Serial.print(httpResponseCode);
}
// Parse the json response: Arduino assistant
const int jsonSize = JSON_ARRAY_SIZE(1) + JSON_ARRAY_SIZE(20) + 3*JSON_OBJECT_SIZE(1) + 6*JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + 20*JSON_OBJECT_SIZE(4) + 2*JSON_OBJECT_SIZE(6);
StaticJsonDocument<jsonSize> doc;
// Deserialize the JSON document
DeserializationError error = deserializeJson(doc, response);
// Test if parsing succeeds.
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return;
}
Serial.println(jsonSize);
Serial.println(response);
for (int i=0; i < 10; i++) {
// const name = doc["outputs"][0]["data"]["concepts"][i]["name"];
// const float p = doc["outputs"][0]["data"]["concepts"][i]["value"];
const char* name = doc["outputs"][0]["data"]["concepts"][i]["name"];
const char* p = doc["outputs"][0]["data"]["concepts"][i]["value"];
Serial.println("=====================");
Serial.print("Name:");
Serial.println(name[i]);
Serial.print("Prob:");
Serial.println(p);
Serial.println();
}
}
它将图像发布给 Clarifai,我得到的回报是:
-400 返回字符串:{"status":{"code":11102,"description":"Invalid request","details":"空的或格式错误的授权标头。请提供 API 密钥或会话令牌。","req_id ":"39d7b4f1b7ad489fb3a9a878000f6e88"},"outputs":[]} -deserializeJson() 失败:EmptyInput
我需要确认 HTTP POST 请求的格式是否正确。