Classificação de imagens em ESP32-CAM usando aprendizado de máquina
Este tutorial aborda como implementar um sistema de classificação de imagens ESP32-CAM usando o aprendizado de máquina. O ESP32-CAM tem a capacidade de adquirir vídeo e imagens, usaremos essa capacidade para classificar imagens usando aprendizado de máquina. Combinando a capacidade de visão ESP32-CAM com aprendizado de máquina em nuvem, neste tutorial, levaremos o poder da visão computacional para um pequeno dispositivo.
A classificação de imagens de aprendizado de máquina é a tarefa de extrair informações de uma imagem usando um modelo treinado.
Para classificar uma imagem, o ESP32-CAM se conectará a uma plataforma de aprendizado de máquina em nuvem chamada Clarifai.com (você pode criar uma conta gratuitamente)..
Conteudo
Como funciona a classificação de imagens ESP32-CAM
Estes são os ajustes para:
- Adquira imagens usando ESP32-CAM
- Codifique a imagem em base64
- Invocar uma API exposta pela plataforma de aprendizado de máquina em nuvem, enviando a imagem adquirida pelo ESP32
- Analise a resposta e extraia as informações
A vantagem desse método é que não é necessário treinar um modelo para classificar as imagens por nós mesmos, mas o ESP32-CAM usa um modelo pré-treinado construído pelo Clarifai. Este modelo de aprendizado de máquina é capaz de identificar e classificar mais de 10.000 conceitos. A partir das imagens capturadas pelo ESP32-CAM, aplicando o reconhecimento de imagem, é possível extrair informações como:
- se há uma pessoa ou não
- interno ou externo
- objetos
- humores
e muito mais. O reconhecimento de imagem é um ramo importante da visão computacional.
Se esta é a primeira vez que você usa ESP32-CAM, você deve ler como fazer streaming de vídeo usando ESP32-CAM. Neste artigo, o ESP32-CAM usa um sistema de aprendizado de máquina externo para classificar as imagens. Se você deseja executar diretamente o mecanismo de aprendizado de máquina no seu dispositivo, é necessário ler como usar o Tensorflow Lite com ESP32.
Vamos começar!
Inicializando o ESP32-CAM
A primeira etapa é inicializar o ESP32-CAM. Este tutorial usa PlatformIO como IDE, mas você pode usar outros IDEs se desejar.
Crie um novo nome de arquivo ESP32-Vision.ino e adicione as seguintes linhas:
#include "Arduino.h" #include "esp_camera.h" #include <WiFi.h> // Select camera model //#define CAMERA_MODEL_WROVER_KIT // Tem PSRAM //#define CAMERA_MODEL_ESP_EYE // Tem PSRAM //#define CAMERA_MODEL_M5STACK_PSRAM // Tem PSRAM //#define CAMERA_MODEL_M5STACK_WIDE // Tem PSRAM #define CAMERA_MODEL_AI_THINKER // Tem PSRAM //#define CAMERA_MODEL_TTGO_T_JOURNAL // Sem 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; // se PSRAM IC estiver presente, init com resolução UXGA e qualidade JPEG superior // para buffer de quadro pré-alocado maior. 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("A inicialização da câmera falhou com erro 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 conectado"); classifyImage(); }
Mesmo este código parece complexo, é bastante simples. Primeiro, é necessário selecionar seu tipo de CAM. Altere de acordo com seu ESP32-CAM. Em seguida, temos que definir o ssid wi-fi e o passord wi-fi para que se conecte ao wi-fi.
É importante notar que reduzimos a resolução da câmera porque a codificação base64 requer muita memória. De qualquer forma, não precisamos de uma resolução maior para reconhecer a imagem.
Aquisição de uma imagem usando ESP32-CAM
Em seguida, podemos capturar a imagem que queremos classificar. Adicione as seguintes linhas:
void classifyImage() { // Capturar imagem camera_fb_t * fb = NULL; fb = esp_camera_fb_get(); if(!fb) { Serial.println("A captura da câmera falhou"); return; } size_t size = fb->len; String buffer = base64::encode((uint8_t *) fb->buf, fb->len); .... }
camera_fb_
t contém as informações da imagem e os dados que representam a imagem capturada. Usando o método esp_camera_fb_get()
, o ESP32-CAM captura a imagem.
Finalmente, codificamos a imagem em base64. fb->buf
contém os dados e fb->len
é o tamanho do buffer. Além disso, adicione a seguinte linha no início do arquivo:
#include <base64.h>
Aplicação de reconhecimento de imagem usando ESP32-CAM
Uma vez que a imagem é capturada, o próximo passo é reconhecer a imagem e extrair informações dela. Mesmo que seja possível usar o modelo de aprendizado de máquina em execução no ESP32, queremos usar uma plataforma de aprendizado de máquina em nuvem que usa modelos pré-treinados. Para isso, é necessário invocar uma API e enviar a imagem codificada. No método classifyImage
, adicione as seguintes linhas:
String payload = "{\"inputs\": [{ \"data\": {\"image\": {\"base64\": \"" + buffer + "\"}}}]}"; buffer = ""; // Remova o comentário se quiser mostrar a carga útil // 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);
O código na linha 10 é o id do modelo que queremos usar para reconhecer a imagem. Por enquanto, não considere a linha 14 a chave. É uma chave de autorização. Veremos mais tarde como fazer isso.
Adicione esta linha no início:
#include <HTTPClient.h>
Adicionando capacidade de visão computacional ao ESP32-CAM
Depois de enviarmos a imagem base64 para a plataforma de nuvem de aprendizado de máquina, obtemos a resposta com todos os conceitos extraídos da imagem.
Conceitos são rótulos usados para classificar a imagem e reconhecê-la. Usando os rótulos, obtemos uma descrição da imagem. Cada rótulo tem uma probabilidade.
Adicione ao método anterior as seguintes linhas:
// Analise a resposta json: assistente do Arduino 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("Nome:"); Serial.println(name[); Serial.print("Prob:"); Serial.println(prob); Serial.println(); }
Neste código, usamos a biblioteca ArduinoJson para analisar a saída. Além disso, adicione a seguinte linha no topo do arquivo:
#include <ArduinoJson.h>
Finalmente, faça o ESP32-CAM dormir esperando a pressão do botão de reset:
Serial.println("\nDormir...."); esp_deep_sleep_start();
Teste o reconhecimento de imagem
Estamos prontos para testar como funciona a classificação de imagens com nosso ESP32-CAM. Depois de enviar o esboço para o ESP32-CAM, você deve pressionar o botão reset para iniciar o processo de reconhecimento de imagem.
Para visualizar a imagem capturada, você pode usar um decodificador de imagem base64 passando o fluxo de bytes codificado que representa a imagem.
Estes são alguns exemplos:
O ESP32-CAM identificou corretamente todos os conceitos: flor, nenhuma pessoa, natureza e folhas.
Este é outro exemplo:
Observe todas as informações extraídas da imagem: nenhuma pessoa, bola, recreação, futebol. Como você pode ver, aplicando a visão computacional ao ESP32-CAM, podemos extrair conceitos interessantes de uma imagem. A câmera ESP32 é capaz de identificar a imagem corretamente.
Testando modelo de aprendizado de máquina usando alimentos
Neste último exemplo, testaremos o reconhecimento de imagem ESP32-CAM usando alimentos. Portanto, é necessário mudar o modelo. Se você está se perguntando onde estão os modelos, você pode usar este link.
Altere o id do modelo no código anterior comentando o modelo antigo e esta linha:
// Generic model //String model_id = "aaa03c23b3724a16a56b629203edc62c"; // Food model String model_id = "bd367be194cf45149e75f01d59f77ba7";
Em seguida, carregue o sketch novamente no ESP32-CAM e verifique como o ESP32-CAM reconhece objetos usando os novos modelos de aprendizado de máquina:
Conforme afirmado na imagem anterior, a probabilidade de que seja uma maçã é de 96%. Portanto, o ESP32-CAM identificou a imagem corretamente novamente.
Finalmente, o último exemplo:
Empacotando
No final deste tutorial, descobrimos como implementar a classificação de imagem ESP32-CAM usando uma API de aprendizado de máquina em nuvem fornecida pela Clarifai. Demonstramos como é fácil implementar um sistema de visão computacional baseado em ESP32-CAM. A integração entre a capacidade ESP32-CAM e o modelo de aprendizado de máquina pode fazer com que este pequeno dispositivo detecte objetos e os reconheça. Além disso, por meio de visão computacional, extraímos informações de imagem usando os modelos pré-treinados de aprendizado de máquina.