This tutorial covers how to implement an ESP32-CAM Image classification system using Machine Learning. The ESP32-CAM has the capability to acquire video and images, we will use this capability to classify images using machine learning. Mixing the ESP32-CAM vision capability with cloud machine learning, in this tutorial, we will bring the power of the computer vision to a tiny device.
Machine Learning image classification is the task of extracting information from an image using a trained model.
In order to classify an image, the ESP32-CAM will connect to a cloud machine learning platform named Clarifai.com (you can create an account for free).
How the ESP32-CAM Image classification works
These are the setps to:
- Acquire images using ESP32-CAM
- Encode the image in base64
- Invoke an API exposed by the machine learning cloud platform, sending the image acquired by the ESP32
- Parse the response and extract the information
The advantage of this method is that it is not necessary to train a model to classify the images by ourselves, but the ESP32-CAM uses a pre-trained model built by Clarifai. This machine learning model is capable to identify and classify more than 10,000 concepts. From the images captured by the ESP32-CAM, applying image recognition, it is possible to extract information such as:
- if there is a person or not
- indoor or outdoor
- objects
- moods
and much more. Image recognition is an important branch of computer vision.
If this is the first time you use ESP32-CAM, you should read how to stream video using ESP32-CAM. In this article the ESP32-CAM uses an external machine learning system to classify images. If you want to run directly the machine learning engine on your device, you have to read how to use Tensorflow lite with ESP32.
Let’s start!
Initializing the ESP32-CAM
The first step is initializing the ESP32-CAM. This tutorial uses PlatformIO as IDE, but you can use other IDEs if you like.
Create a new file name ESP32-Vision.ino and add the following lines:
#include "Arduino.h"
#include "esp_camera.h"
#include <WiFi.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
#include "camera_pins.h"
const char* ssid = "your_ssid";
const char* password = "wifi_password";
void setup() {
Serial.begin(9600);
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();
}
Code language: PHP (php)
Even this code seems complex, it is quite simple. First, it is necessary to select your CAM type. Change it according to your ESP32-CAM. Then, we have to set the wifi ssid and the wifi passord so that it connects to the WiFi.
It is important to notice that we have reduced the camera resolution because the base64 encoding requires a lot of memory. Anyway, we do not need a higher resolution to recognize the image.
More useful resources:
How to use ESP32-CAM and Tensorflow.js to detect objects
Acquiring a picture using ESP32-CAM
Next, we can capture the image we want to classify. Add the following lines:
void classifyImage() {
// Capture picture
camera_fb_t * fb = NULL;
fb = esp_camera_fb_get();
if(!fb) {
Serial.println("Camera capture failed");
return;
}
size_t size = fb->len;
String buffer = base64::encode((uint8_t *) fb->buf, fb->len);
....
}
Code language: PHP (php)
camera_fb_t
holds the picture information and the data representing the image captured. Using the method esp_camera_fb_get()
, the ESP32-CAM captures the image.
Finally, we encode in base64 the image. fb->buf
holds the data and fb->len
is the buffer size. Moreover, add the following line at the beginning of the file:
#include <base64.h>
Code language: CSS (css)
Applying image recognition using ESP32-CAM
Once the image is captured, the next step is recognize the image and extract information from it. Even if it is possible to use machine learning model running on ESP32, we want to use a cloud machine learning platform that uses pre-trained models. To achieve it, it is necessary to invoke an API and send the encoded image. In the classifyImage
method add the following lines:
String payload = "{\"inputs\": [{ \"data\": {\"image\": {\"base64\": \"" + buffer + "\"}}}]}";
buffer = "";
// Uncomment this if you want to show the payload
// Serial.println(payload);
esp_camera_fb_return(fb);
// Generic model
String model_id = "aaa03c23b3724a16a56b629203edc62c";
HTTPClient http;
http.begin("https://api.clarifai.com/v2/models/" + model_id + "/outputs");
http.addHeader("Content-Type", "application/json");
http.addHeader("Authorization", "Key your_key");
int response_code = http.POST(payload);
Code language: JavaScript (javascript)
The code in line 10 is the model id, we want to use to recognize the image. By now do not consider in line 14 the key. It is an authorization key. We will see later how to get it.
Add this line at the beginning:
#include <HTTPClient.h>
Code language: CSS (css)
Adding computer vision capability to the ESP32-CAM
After we have sent the base64 image to the machine learning cloud platform, we get the response with all the concepts extracted from the image.
Concepts are labels that are used to classify the image and recognize it. Using the labels, we get an image description. Each label has a probability.
Add to the previous method the following lines:
// 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);
DynamicJsonDocument doc(jsonSize);
deserializeJson(doc, 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"];
Serial.println("=====================");
Serial.print("Name:");
Serial.println(name[i]);
Serial.print("Prob:");
Serial.println(p);
Serial.println();
}
Code language: PHP (php)
In this code, we use the ArduinoJson library to parse the output. Moreover, add the following line at the file top:
#include <ArduinoJson.h>
Code language: CSS (css)
Finally, make the ESP32-CAM sleep waiting for the pression of the reset button:
Serial.println("\nSleep....");
esp_deep_sleep_start();
Code language: JavaScript (javascript)
Test the image recognition
We are ready to test how the image classification works with our ESP32-CAM. After uploading the sketch into the ESP32-CAM, you have to press the reset button to start the image recognition process.
To visualize the image captured, you can use a base64 to image decoder passing the encoded byte stream representing the image.
These are some examples:
![]() ![]() |
The ESP32-CAM has correctly identified all the concepts: flower, no person, nature and leafs.
This is another example:
![]() ![]() |
Notice all the information extracted from the image: no person, ball, recreation, soccer. As you can see applying computer vision to the ESP32-CAM we can extract interesting concepts from an image. The ESP32 cam is capable to identify the image correctly.
Testing machine learning model using food
In this last example, we will test the ESP32-CAM image recognition using foods. Therefore, it is necessary to change the model. If you are wondering where the models are, you can use this link.
Change the model id in the previous code commenting the old model and the this line:
// Generic model
//String model_id = "aaa03c23b3724a16a56b629203edc62c";
// Food model
String model_id = "bd367be194cf45149e75f01d59f77ba7";
Code language: JavaScript (javascript)
Then upload the sketch again into the ESP32-CAM and verify how the ESP32-CAM recognizes objects using the new machine learning models:
![]() ![]() |
As stated in the previous image, the probability that it is an apple is 96%. Therefore, the ESP32-CAM has identified the image correctly again.
Finally, the last example:
![]() ![]() |
Wrapping up
At the end of this tutorial, we have discovered how to implement ESP32-CAM image classification using a cloud machine learning API provided by Clarifai. We have demonstrated how easy it is to implement a computer vision system based on ESP32-CAM. The integration between the ESP32-CAM capability and the machine learning model can make this tiny device to detect objects and recognize them. Moreover, using computer vision, we have extracted image information using the machine learning pre-trained models.
Boa noite
Muito bom sua aplicação..
Estive vendo a API da clarifai e seu projeto mais com a url settada no seu projeto ao roda no esp32cam o mesmo não se conectado com a plataforma. alem do mais tem erros no seu json para deserializarjson. ok
Let me know how i can improve it!
Hello, how are you. Seeing your application I performed tests. More expensive when trying to connect to the clarifai server using your code do not connect. And about the logic to deserialize the return of the request to the clarifai server of the error in the use of the logic json asks to use lib 6.0 onwards.
Hello, how are you. Seeing your application I performed tests. More expensive when trying to connect to the clarifai server using your code do not connect. And about the logic to deserialize the return of the request to the clarifai server of the error in the use of the logic json asks to use lib 6.0 onwards.
Did you use your API Key?….You have to import the Arduino JSON library to handle the json response. Let me know
Hi, I was wondering if you could provide the complete source code for this project? It would be a great help as I could not find “camera_pins.h”. If there is a .zip file or a Github source code, then this project would be terrific!
Hi,
I’m looking for the code to commit on github. Meanwhile you can use here (https://github.com/survivingwithandroid/ESP32-CAM-Style-Transfer) you can find the file you are looking for even if the project is different. Let me know if it fixes your problem.
Thank you very much! I will keep an eye out for it ^-^
Thanks a lot! I will be keeping an eye out for when this clarifai one is released!
How to get the API. And where to post in the code?
Please check here..
..
deserializeJson(doc, response); // what’s response ?
for (int i=0; i what’s a type of name? char* or char ?
const float p = doc[“outputs”][0][“data”][“concepts”][i][“value”];
…
Serial.println(name[); //==> name ?
Serial.print(“Prob:”);
Serial.println(prob); // ==> p?
Serial.println();
}
I’ve updated the source code Thank you for your suggestions
Hi Francesco, great tutorial.
I got the code to work but I am getting the following response from the clarifai:
400 Returned String: {“status”:{“code”:11102,”description”:”Invalid request”,”details”:”Empty or malformed authorization header. Please provide an API key or session token.”,”req_id”:”39d7b4f1b7ad489fb3a9a878000f6e88″},”outputs”:[]}
deserializeJson() failed: EmptyInput
Hi, do you use your API Key to invoke clarify?
Hi, thanks for responding to my question.
Yes, I subscribed to clarifai and got the API Key.
I made some changes to the code to see what is going on as below:
#include “Arduino.h”
#include “esp_camera.h”
#include
#include
#include
#include
// 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.print(“WiFi connected to: “);
Serial.println(ssid);
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 payloadData = “{\”inputs\”: [{ \”data\”: {\”image\”: {\”base64\”: \”” + buffer + “\”}}}]}”;
buffer = “”;
// Uncomment this if you want to show the payload
Serial.println(payloadData);
esp_camera_fb_return(fb);
// Generic model
String model_id = “aaa03c23b3724a16a56b629203edc62c”;
HTTPClient http;
http.begin(“https://api.clarifai.com/v2/models/” + model_id + “/outputs”);
http.addHeader(“Content-Type: “, “application/json”);
http.addHeader(“Authorization: “, “Here goes the APIkey I got from clarifai”);
int httpResponseCode = http.POST(payloadData);
if(httpResponseCode>0){
Serial.print(httpResponseCode);
Serial.print(” Returned String: “);
response = http.getString();
Serial.println(response);
} else {
Serial.print(“POST Error: “);
Serial.print(httpResponseCode);
return;
}
// 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);
//DynamicJsonDocument doc(jsonSize);
//deserializeJson(doc, response);
StaticJsonDocument 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;
}
for (int i=0; i < 10; i++) {
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();
}
}
It feels like the JSON that is being submited is not wat clarifai.com expects but I could not confirm that as I found no example on their site.
What am I doing wrong?
Thanks again
Paulo
Hi, thanks for responding to my question.
Yes, I subscribed to clarifai.com and got the API Key.
I made some changes to the code to see what is going on as below:
#include “Arduino.h”
#include “esp_camera.h”
#include
#include
#include
#include
// 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.print(“WiFi connected to: “);
Serial.println(ssid);
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 payloadData = “{\”inputs\”: [{ \”data\”: {\”image\”: {\”base64\”: \”” + buffer + “\”}}}]}”;
buffer = “”;
// Uncomment this if you want to show the payload
Serial.println(payloadData);
esp_camera_fb_return(fb);
// Generic model
String model_id = “aaa03c23b3724a16a56b629203edc62c”;
HTTPClient http;
http.begin(“https://api.clarifai.com/v2/models/” + model_id + “/outputs”);
http.addHeader(“Content-Type: “, “application/json”);
http.addHeader(“Authorization: “, “Here goes the APIkey I got from clarifai”);
int httpResponseCode = http.POST(payloadData);
if(httpResponseCode>0){
Serial.print(httpResponseCode);
Serial.print(” Returned String: “);
response = http.getString();
Serial.println(response);
} else {
Serial.print(“POST Error: “);
Serial.print(httpResponseCode);
return;
}
// 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);
//DynamicJsonDocument doc(jsonSize);
//deserializeJson(doc, response);
StaticJsonDocument 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;
}
for (int i=0; i < 10; i++) {
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();
}
}
It feels like the JSON that is being submitted is not what clarifai.com expects but I could not confirm that as I found no example on their site.
What am I doing wrong?
Thanks again
Paulo
Hi, I am trying to respond but always get message of duplicated post…
Can you please supply an email so I can send you how the code is looking now with some changes I made to better debug the code?
Thanks
Hi, I am trying to respond but always get message of duplicated post…
Can you please supply an email?
Thanks
Sent a email.
Message of duplicated post on this forum…
Problem solved:
http.addHeader(“Authorization”, “Key c7cde234537462388e256785c071231”); //That is a randon key
Question:
Where to find model_id?
All I can find is the name of the model but not the ID.
Thanks
Paulo
For example, if you go here https://www.clarifai.com/models/face-detection you can find the model ID
deserializeJson(doc, response);
In this line what is ‘response’ ? It is not also declared in previous as a variable.
I don’t have the code right now but you can try:
response = http.getString();
Let me know it works!
I’m not getting the “name” field correctly using this code only getting the i th char of the name field.
Name:N
Prob:0.99
=====================
Name:o
Prob:0.99
=====================
Name:l
Prob:0.99
=====================
Name:u
Prob:0.95
Sounds strange!…You can try to print the JSON response and check!
Hi, thanks for this great tutorial, please correct the size of the DynamicJsonDocument, using the https://arduinojson.org/v5/assistant/ showed a number much higher… for me I used the following and it worked: const int jsonSize = 2*JSON_ARRAY_SIZE(0) + JSON_ARRAY_SIZE(1) + JSON_ARRAY_SIZE(20) + 4*JSON_OBJECT_SIZE(0) + 7*JSON_OBJECT_SIZE(1) + 5*JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + 21*JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(5) + JSON_OBJECT_SIZE(6) + JSON_OBJECT_SIZE(7) + JSON_OBJECT_SIZE(18)+ 3251;
Also parsing the results has to be modified: String name = doc[“outputs”][0][“data”][“concepts”][i][“name”];
String p = doc[“outputs”][0][“data”][“concepts”][i][“value”];
Serial.println(“=====================”);
Serial.print(“Name:”);
Serial.println(name);
Serial.print(“Prob:”);
Serial.println(p);
Serial.println();
Hi, how do you capture the picture? My coding works with no error however the camera goes to sleep. Do I use if else for the sleep mode?
what algorithm method should be used to recognition faces on esp32 cam?
……………………………………….
WiFi connected to: SDS
“Camera capture OK”
{“inputs”: [{ “data”: {“image”: {“base64”: “/9j/4AAQSkZJRgABAQEAAAAAAAD/2wBDAAoHCAkIBgoJCAkLCwoMDxkQDw4ODx8WFxIZJCAmJiQgIyIoLToxKCs2KyIjMkQzNjs9QEFAJzBHTEY/Szo/QD7/2wBDAQsLCw8NDx0QEB0+KSMpPj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj7/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMDAgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiI���=U�i�a�)����=������-����=�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”}}}]}
POST Error:-1
Sleep….
im getting this error and new to this please help