Skip to Content

Começar com HUSKYLENS 2 e Arduino/ESP32

Começar com HUSKYLENS 2 e Arduino/ESP32

Este tutorial vai mostrar-lhe como começar a usar o HUSKYLENS 2. O HUSKYLENS 2 da DFRobot é um sensor de visão AI com uma câmara substituível de 2MP, um ecrã tátil IPS de 2,4 polegadas, microfone, altifalante e luzes indicadoras.

Logo ao tirar da caixa, o HUSKYLENS 2 suporta mais de 20 modelos AI incorporados, desde reconhecimento de objetos e rastreamento facial até estimativa de pose e segmentação de instâncias. Além disso, pode implementar modelos treinados personalizados via um fluxo de trabalho estilo YOLO no dispositivo.

Vai aprender como ligar o HUSKYLENS a um Arduino ou ESP32 via I2C e como obter programaticamente os resultados de deteção para diferentes algoritmos AI. Isto permite controlar dispositivos externos a partir do seu Arduino ou ESP32 com base nas deteções.

Por exemplo, neste tutorial vamos construir um Emotion Traffic Light que liga um LED (vermelho, amarelo, verde), dependendo da emoção detetada numa face (Raiva, Neutro, Feliz).

Vamos começar!

Peças Necessárias

Pode adquirir o HUSKYLENS 2 da DFRobot através do link abaixo. Além disso, vai precisar de um microcontrolador. Eu estou a usar um Arduino UNO e um Lolin ESP32 lite, mas a maioria das outras placas Arduino ou ESP32 também funcionam bem. O único requisito é suporte para uma interface I2C (ou UART).

HUSKYLENS 2

Arduino

Arduino Uno

USB Data Sync cable Arduino

Cabo USB para Arduino UNO

ESP32 lite Lolin32

ESP32 lite

USB data cable

Cabo USB de Dados

Dupont wire set

Conjunto de Fios Dupont

Half_breadboard56a

Breadboard

Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.

HUSKYLENS versus novo HUSKYLENS 2

Para evitar confusões, vamos começar com uma rápida comparação entre o original HUSKYLENS (Versão 1) e o novo HUSKYLENS 2 que estamos a usar neste tutorial. Ambos os dispositivos são sensores de visão AI desenhados pela DFRobot para simplificar aplicações de visão computacional em sistemas embebidos. Ambos oferecem processamento de visão a bordo e interfaces seriais, mas o HUSKYLENS 2 tem capacidades de hardware e software melhoradas.

HUSKYLENS

O HUSKYLENS de primeira geração baseia-se no processador AI Kendryte K210 e fornece algoritmos AI incorporados para tarefas como reconhecimento facial, rastreamento de objetos, deteção de cor, rastreamento de linha e reconhecimento de etiquetas. Inclui um ecrã IPS de 2,0 polegadas para feedback em tempo real e suporta interfaces UART, I²C e USB para comunicação.

HUSKYLENS 2

O HUSKYLENS 2, por outro lado, é alimentado por um processador dual-core de 1,6 GHz (K230) com um acelerador AI de 6 TOPS, 1 GB de RAM LPDDR4 e 8 GB de armazenamento onboard. Esta capacidade de processamento melhorada permite-lhe executar tarefas AI mais complexas localmente.

Vem com mais de vinte modelos de visão incorporados, incluindo deteção de objetos, estimativa de pose e segmentação de instâncias, e permite aos utilizadores implementar os seus próprios modelos personalizados usando um fluxo de trabalho baseado em YOLO.

A nova versão também apresenta um ecrã IPS de maior resolução de 2,4 polegadas, um sistema modular de câmara que suporta lentes intercambiáveis, uma porta USB-C para dados e energia, e um módulo opcional de conectividade sem fios.

Tabela Comparativa

CaracterísticaHUSKYLENS (Original)HUSKYLENS 2
ProcessadorChip AI dual-core Kendryte K210Processador dual-core 1,6 GHz com acelerador AI de 6 TOPS
Memória / ArmazenamentoNão especificado1 GB RAM LPDDR4 + 8 GB eMMC
Modelos incorporados7 algoritmos predefinidos (reconhecimento facial, objeto, linha, cor, etiquetas)Mais de 20 modelos incorporados com suporte para modelos YOLO personalizados
Ecrã2,0″ IPS (320×240 px)2,4″ IPS (640×480 px)
CâmaraFixa 2 MP (OV2640)2 MP (GC2093) com lentes intercambiáveis
InterfacesUART, I²C, USBUSB-C, I²C, UART, módulo Wi-Fi opcional
Consumo de Energia230mA @ 5.0V (Reconhecimento Facial)340mA @ 5V (Reconhecimento Facial)

Como mencionado, neste tutorial vamos usar o HUSKYLENS 2 e na próxima secção vamos analisar mais detalhadamente as suas características técnicas.

Hardware do HUSKYLENS 2

O HUSKYLENS 2 é construído em torno de um módulo de visão AI embebido de alto desempenho, projetado para executar inferência de redes neurais inteiramente no dispositivo, reduzindo a necessidade de um processador host separado ou computação na cloud. No seu núcleo está uma CPU dual-core de 1,6 GHz (K230) emparelhada com um acelerador AI capaz de ≈ 6 TOPS (tera-operações por segundo) de desempenho computacional AI.

A imagem abaixo mostra a parte traseira do HUSKYLENS 2 com a câmara, dois LEDs para iluminação, um LED RGB e ao lado um microfone e finalmente um pequeno botão de pressão para programação/aprendizagem:

Back of HUSKYLENS 2
Parte traseira do HUSKYLENS 2

Memória

Complementando o processador está um subsistema de memória composto por 1 GB de RAM LPDDR4 para tarefas de runtime de redes neurais e aplicações, e um armazenamento flash eMMC de 8 GB para firmware do sistema, armazenamento de modelos e dados do utilizador.

Câmara

A cadeia de aquisição de imagem usa um sensor de 2 megapixels (modelo GC2093, formato 1/2.9″) capaz de capturar vídeo a até 60 frames por segundo (fps). O módulo da câmara é projetado para ser modular/intercambiável, permitindo trocar diferentes lentes ou configurações óticas (por exemplo macro, visão noturna, longo alcance) conforme o caso de uso.

Camera Module of HUSKYLENS 2
Módulo de Câmara do HUSKYLENS 2

Ecrã Tátil

Para interação homem-máquina e UI local, o HUSKYLENS 2 integra um ecrã tátil IPS de 2,4″ (resolução 640×480). Um botão de função único, um LED indicador RGB e um pequeno altifalante na parte traseira fornecem feedback áudio/visual adicional.

Front with Touch Screen of HUSKYLENS 2
Frente com Ecrã Tátil do HUSKYLENS 2

Interfaces

O HUSKYLENS 2 oferece uma porta USB-C (para energia e atualizações de firmware), um conector “Gravity” de 4 pinos que expõe UART e I²C (e Power/GND) para comunicação com o host, e possibilidade para um módulo Wi-Fi 6 de 2,4 GHz (opcional) para conectividade sem fios. A expansão é também suportada via slot para cartão TF (micro-SD) na lateral para armazenamento adicional ou captura de datasets.

Interfaces of of HUSKYLENS 2
Interfaces do HUSKYLENS 2

O subsistema de visão fornece dados de coordenadas, caixas delimitadoras, IDs e metadados específicos do modelo via UART/I²C para que microcontroladores externos possam ler e agir sobre eles.

Energia

A entrada de energia é nominalmente de 3,3V a 5,0V (regulada a bordo) e o consumo típico de energia é cerca de 1,5W a 3W dependendo da carga e do uso do modelo ativo. A tabela abaixo mostra as correntes que medi para alguns dos modelos, com uma corrente até 420mA para OCR (Reconhecimento Óptico de Caracteres) e uma corrente em idle (apenas UI a correr) de 250mA:

TarefaCorrente
UI250mA
Reconhecimento Facial340mA
Reconhecimento de Objetos380mA
Rastreamento de Objetos370mA
Reconhecimento de Cor330mA
Classificação de Objetos350mA
Segmentação de Instâncias390mA
Reconhecimento de Mãos370mA
Reconhecimento de Código QR410mA
OCR420mA

Modelos AI Incorporados

O firmware do HUSKYLENS 2 gere tanto o sistema RTOS como o ambiente de implementação dos modelos AI. O dispositivo vem pré-carregado com 20+ built-in AI models (como deteção de objetos, reconhecimento facial, estimativa de pose, segmentação de instâncias) que podem ser selecionados pela UI a bordo ou programaticamente:

AI models of the HUSKYLENS 2
Modelos AI do HUSKYLENS 2 (source)

As atualizações de firmware são feitas via a porta USB-C (ou via a interface host) e o sistema suporta múltiplos modelos a correr em série ou em paralelo (dependendo do uso de recursos) graças ao acelerador de 6 TOPS.

Modelos Treinados Personalizados

Além dos modelos incorporados, o HUSKYLENS 2 suporta a implementação de custom-trained models, especificamente via um fluxo de trabalho estilo YOLO: os utilizadores podem anotar datasets, treinar modelos externamente, convertê-los para o formato alvo, carregá-los no armazenamento eMMC do dispositivo e executá-los localmente.

Protocolo de Contexto de Modelo

Uma característica distintiva é o “Protocolo de Contexto de Modelo” incorporado (MCP) service, que permite ao módulo da câmara emitir dados semânticos estruturados (por exemplo: “pessoa A a levantar objeto B”) para um modelo de linguagem grande (LLM) conectado ou aplicação host, ligando assim o processamento de visão no dispositivo com raciocínio de nível superior.

Especificação Técnica

A tabela seguinte resume a especificação técnica do HUSKYLENS 2:

ParâmetroEspecificação
Núcleo do processadorCPU dual-core @1.6 GHz (Kendryte K230)
Acelerador AI~6 TOPS de computação AI no dispositivo
RAM1 GB LPDDR4
Armazenamento8 GB eMMC
Sensor de imagemGC2093, 2 MP, 1/2.9″, até 60 fps
Ecrã a bordoEcrã tátil IPS 2,4″, resolução 640×480
InterfacesUSB-C (energia/dados), Gravity 4 pinos (UART/I²C/Energia/GND), módulo WiFi opcional
Armazenamento expansívelSlot para cartão TF (micro-SD)
Áudio I/OMicrofone incorporado, altifalante de 1 W
Indicadores / UI1 botão de função, 2 LEDs para iluminação, 1 LED RGB
Suporte para câmara modularMódulos de lentes intercambiáveis (macro, visão noturna, etc)
Tensão de entrada3,3 V a 5,0 V
Consumo típico de energia~1,5 W a 3 W
Dimensões~70 × 58 × 19 mm
Peso~90 g
Modelos pré-carregadosMais de 20 modelos AI incorporados
Suporte a modelos personalizadosvia fluxo de trabalho estilo YOLO
Características especiaisServiço MCP ligando visão a LLMs

Ligação do HUSKYLENS 2 ao Arduino UNO

Pode comunicar com o HUSKYLENS usando o protocolo UART ou I2C. O I2C é mais rápido e permite ligar múltiplos dispositivos ao mesmo barramento. Portanto, vamos usar I2C. O conector Gravity do HUSKYLENS expõe a interface I2C (SDA, SCL) e os pinos de alimentação (VCC, GND). Veja a foto abaixo:

I2C/UART Gravity Interface
Interface Gravity I2C/UART

Poderia ligar o HUSKYLENS 2 diretamente a um Arduino e alimentá-lo a partir do pino de 5V do Arduino, mas NÃO deve fazer isso!

A corrente máxima que o pino 5V do Arduino pode fornecer é 500mA e o HUSKYLENS 2 consome até 420mA (modelo OCR). Isto é inferior à corrente máxima, mas para tempos de funcionamento mais longos o regulador de tensão do Arduino ou ESP32 vai aquecer muito e pode queimar.

A opção segura é usar a pequena placa adaptadora de alimentação que vem com o HUSKYLENS. Ela permite alimentar o HUSKYLENS a partir de uma fonte de alimentação separada.

Alternativamente, pode ligar o HUSKYLENS a uma porta USB e o Arduino a outra porta USB, como mostrado na Wiki da DFRobot:

Connecting HUSKYLENS 2 and Arduino UNO
Ligação do HUSKYLENS 2 e Arduino UNO (source)

No entanto, prefiro usar a placa adaptadora de alimentação e a secção seguinte mostra como fazer essa ligação.

Diagrama de Ligações

O diagrama de ligações abaixo mostra como ligar o HUSKYLENS via a placa adaptadora de alimentação a um Arduino UNO:

Ligação do HUSKYLENS 2 ao Arduino UNO

Comece por ligar a placa adaptadora ao HUSKYLENS. Use o cabo branco Dual-Plug PH2.0-4P Silicone (fios cinzentos no diagrama) que vem com o HUSKYLENS e certifique-se de que está a usar o conector rotulado “Huskylens” e “I2C/UART“:

Connect Adapter to HUSKYLENS
Ligar Adaptador ao HUSKYLENS

De seguida, ligue o cabo colorido Gravity-4P Sensor Connector à placa adaptadora e ao Arduino:

Connect Adapter to Arduino UNO
Ligar Adaptador ao Arduino UNO

O fio vermelho deve ser ligado ao pino 5V do Arduino, e o fio preto ao GND. O fio verde é SDA e deve ser ligado ao A4 e o fio azul (SCL) deve ser ligado ao A5 do Arduino.

Ligue um power bank ou outra fonte de alimentação 5V via um cabo USB à placa adaptadora. Isto fornecerá energia ao HUSKYLENS. O HUSKYLENS deve funcionar assim que a energia USB for fornecida.

Connect power to the Adapter board
Ligar energia à placa adaptadora

Finalmente, precisamos ligar o nosso Arduino via o seu cabo USB a um PC que execute o Arduino IDE para podermos programá-lo:

Connect Arduino to PC
Ligar Arduino ao PC

Instalar a Biblioteca HuskylensV2

Antes de poder executar qualquer um dos exemplos de código seguintes no Arduino ou ESP32, primeiro terá de instalar a biblioteca DFRobot_HuskylensV2. Vá à biblioteca Github repo for the DFRobot_HuskylensV2, clique no botão verde Code e depois em “Download ZIP” para descarregar a biblioteca como um ficheiro ZIP:

Downloading DFRobot_HuskylensV2 library
Descarregar biblioteca DFRobot_HuskylensV2

De seguida, abra o seu Arduino IDE, clique em “Sketch” -> “Include Library” -> “Add .ZIP Library …” para adicionar a biblioteca DFRobot_HuskylensV2 que acabou de descarregar ao Arduino IDE:

Add .ZIP Library
Adicionar Biblioteca .ZIP

Agora estamos prontos para escrever algum código.

Exemplo de Código: Comunicação I2C com Modelos

Neste primeiro exemplo vamos testar a comunicação I2C entre alguns dos modelos AI no dispositivo HUSKYLENS e o Arduino UNO.

Ligue o seu Arduino UNO a um PC com o Arduino IDE. Certifique-se de que o Arduino é reconhecido numa porta COM e que o Arduino UNO está selecionado como placa:

Arduino UNO connected to COM port
Arduino UNO ligado a porta COM

De seguida, crie um novo Sketch e copie&cole o seguinte código nele. Este código estabelece uma comunicação I2C entre o Arduino e o HUSKYLENS, e imprime os resultados de deteção do modelo AI atualmente em execução no HUSKYLENS:

// (c) www.makerguides.com
#include "DFRobot_HuskylensV2.h"

HuskylensV2 huskylens;

void setup() {
    Serial.begin(115200);
    Wire.begin();
    while (!huskylens.begin(Wire)) {
        Serial.println(F("Can't init HUSKYLENS!"));
        delay(100);
    }
    Serial.println("running...");  
}

void loop() {
    while (!huskylens.getResult(ALGORITHM_ANY)) {
        delay(100);
    }
    
    Serial.println("\nRESULTS:"); 
    while (huskylens.available(ALGORITHM_ANY)) {
        Result *r= static_cast<Result *>(huskylens.popCachedResult(ALGORITHM_ANY));        
        Serial.print("Name=");
        Serial.print(r->name);
        Serial.print("  ID=");
        Serial.println(r->ID);
    }
    delay(1000);
}

Bibliotecas e Objetos

O código inclui primeiro a biblioteca DFRobot_HuskylensV2 e cria o objeto HuskylensV2.

#include "DFRobot_HuskylensV2.h"

HuskylensV2 huskylens;

Setup

De seguida, na função setup iniciamos primeiro a comunicação Serial (Serial.begin()) e a interface I2C (Wire.begin()). Depois tentamos estabelecer uma comunicação I2C com o HUSKYLENS via huskylens.begin(Wire):

void setup() {
    Serial.begin(115200);
    Wire.begin();
    while (!huskylens.begin(Wire)) {
        Serial.println(F("Can't init HUSKYLENS!"));
        delay(100);
    }
  Serial.println("running...");  
}

Se isto falhar e vir “Can’t init HUSKYLENS!” impresso no seu Monitor Serial, verifique as ligações e certifique-se de que o protocolo de comunicação do HUSKYLENS 2 está definido para I2C. Para isso, vá a “System Settings” -> “Protocol Type” e verifique que I2C está selecionado como mostrado abaixo:

I2C protocol setting for HUSKYLENS 2
Configuração do protocolo I2C para HUSKYLENS 2

Loop

Na função loop esperamos primeiro se algum dos algoritmos AI no HUSKYLENS tem resultados prontos. Se for o caso, iteramos sobre todos os resultados disponíveis e imprimimos o nome e ID do resultado:

void loop() {
    while (!huskylens.getResult(ALGORITHM_ANY)) {
        delay(100);
    }
    
    Serial.println("\nRESULTS:"); 
    while (huskylens.available(ALGORITHM_ANY)) {
        Result *r= static_cast<Result *>(huskylens.popCachedResult(ALGORITHM_ANY));        
        Serial.print("Name=");
        Serial.print(r->name);
        Serial.print("  ID=");
        Serial.println(r->ID);
    }
    delay(1000);
}

Selecionar Algoritmo AI

Antes de poder ver qualquer resultado impresso no Monitor Serial, deve primeiro selecionar um Algoritmo AI (modelo) no HUSKYLENS (mais tarde faremos isto automaticamente a partir do código). Por exemplo, pode selecionar o algoritmo de Reconhecimento de Objetos:

Select Object Recognition algorithm
Selecionar algoritmo de Reconhecimento de Objetos

O HUSKYLENS começará então a detetar objetos e reportará os resultados ao Arduino, se houver objetos detetados. Deve ver uma saída semelhante à seguinte no seu Monitor Serial:

Detected objects reported on Serial Monitor
Objetos detetados reportados no Monitor Serial

Note que pode haver múltiplas deteções sob um único RESULT, pois podem existir vários objetos na imagem.

Pode experimentar outros Algoritmos AI, mas à exceção do ID, a maioria não fornecerá muita informação útil com este exemplo de código. Os resultados dependem do algoritmo AI específico e requerem código específico para serem impressos. Nas próximas secções vai aprender como obter resultados mais detalhados.

Algoritmos AI

O HUSKYLENS 2 tem muitos Algoritmos AI incorporados. Se abrir o ficheiro Result.h da biblioteca DFRobot_HuskylensV2, encontrará a seguinte lista de constantes para os modelos incorporados:

// https://github.com/DFRobot/DFRobot_HuskylensV2/blob/master/Result.h

typedef enum {
  ALGORITHM_ANY = 0,                      // 0
  ALGORITHM_FACE_RECOGNITION = 1,         // 1
  ALGORITHM_OBJECT_TRACKING,              // 2
  ALGORITHM_OBJECT_RECOGNITION,           // 3
  ALGORITHM_LINE_TRACKING,                // 6
  ALGORITHM_COLOR_RECOGNITION,            // 5
  ALGORITHM_TAG_RECOGNITION,              // 6
  ALGORITHM_SELF_LEARNING_CLASSIFICATION, // 7
  ALGORITHM_OCR_RECOGNITION,              // 8
  ALGORITHM_LICENSE_RECOGNITION,          // 9
  ALGORITHM_QRCODE_RECOGNITION,           // 10
  ALGORITHM_BARCODE_RECOGNITION,          // 11
  ALGORITHM_EMOTION_RECOGNITION,          // 12
  ALGORITHM_POSE_RECOGNITION,             // 13
  ALGORITHM_HAND_RECOGNITION,             // 14
  ALGORITHM_OBJECT_CLASSIFICATION,        // 15
  ALGORITHM_BLINK_RECOGNITION,            // 16
  ALGORITHM_GAZE_RECOGNITION,             // 17
  ALGORITHM_FACE_ORIENTATION,             // 18
  ALGORITHM_FALLDOWN_RECOGNITION,         // 19
  ALGORITHM_SEGMENT,                      // 20
  ALGORITHM_FACE_ACTION_RECOGNITION,      // 21
  ALGORITHM_CUSTOM0,                      // 22
  ALGORITHM_CUSTOM1,                      // 23
  ALGORITHM_CUSTOM2,                      // 24
  ALGORITHM_BUILTIN_COUNT,                // 25

  ALGORITHM_CUSTOM_BEGIN = 128, // 128

} eAlgorithm_t;

Nos exemplos seguintes vamos usar os algoritmos de Reconhecimento de Objetos, Reconhecimento Facial e Reconhecimento de Emoções. Depois de ganhar alguma experiência com estes, escrever código para os outros é fácil.

Exemplo de Código: Reconhecimento de Objetos

Nesta secção vamos obter os resultados de deteção do algoritmo Object Recognition. Já usamos o Reconhecimento de Objetos antes ao testar a interface I2C, mas só obtivemos o nome e ID do objeto detetado. O código seguinte obtém o nome do objeto, o seu ID, o ponto central e a caixa delimitadora:

// (c) www.makerguides.com
#include "DFRobot_HuskylensV2.h"

#define TASK ALGORITHM_OBJECT_RECOGNITION

HuskylensV2 huskylens;

void setup() {
  Serial.begin(115200);
  Wire.begin();
  while (!huskylens.begin(Wire)) {
    Serial.println(F("Can't init HUSKYLENS!"));
    delay(100);
  }
  huskylens.switchAlgorithm(TASK);
  Serial.println("running...");
}

void loop() {
  static char text[128];

  while (!huskylens.getResult(TASK)) {
    delay(100);
  }

  while (huskylens.available(TASK)) {
    Result *r = huskylens.popCachedResult(TASK);
    sprintf(text, "%10s (%d) x=%3d y=%3d w=%3d h=%3d",
            r->name.c_str(),
            r->classID,
            r->xCenter,
            r->yCenter,
            r->width,
            r->height);
    Serial.println(text);
  }

  delay(1000);
}

O código é muito semelhante ao anterior, com três diferenças importantes. Primeiro, definimos uma constante TASK que especifica o algoritmo AI para o qual queremos obter resultados.

#define TASK ALGORITHM_OBJECT_RECOGNITION

Segundo, na função setup chamamos huskylens.switchAlgorithm(TASK) para executar automaticamente o algoritmo AI que queremos usar:

huskylens.switchAlgorithm(TASK);

Finalmente, na função loop, já não fazemos cast do tipo de retorno de huskylens.popCachedResult(), mas usamos o tipo Result tal como está.

Result *r = huskylens.popCachedResult(TASK);

Dependendo do algoritmo AI, o objeto Result é preenchido com diferentes dados de deteção. No caso do ALGORITHM_OBJECT_RECOGNITION, podemos obter o name, classID, ponto central (xCenter, yCenter) e dimensões da caixa delimitadora (width, height):

    Result *r = huskylens.popCachedResult(TASK);
    sprintf(text, "%10s (%d) x=%3d y=%3d w=%3d h=%3d",
            r->name.c_str(),
            r->classID,
            r->xCenter,
            r->yCenter,
            r->width,
            r->height);
    Serial.println(text);
 

Se carregar e executar o código no seu Arduino, o HUSKYLENS deve ativar automaticamente o algoritmo de Reconhecimento de Objetos:

Select Object Recognition algorithm
Selecionar algoritmo de Reconhecimento de Objetos

e deve ver os nomes e outras informações dos objetos detetados impressos no Monitor Serial:

Detection results on Serial Monitor
Resultados de deteção no Monitor Serial

Resultados e Microprocessador

Note que alguns dos resultados dependem não só do algoritmo AI, mas também do microprocessador ligado ao HUSKYLENS.

Para microprocessadores com mais memória que o Arduino, por exemplo o ESP32, obterá resultados mais detalhados para alguns dos algoritmos (ver Differences in Data Acquisition). Pode ver isto no ficheiro Result.h da biblioteca DFRobot_HuskylensV2, que tem a seguinte definição:

#if defined(ESP32) || defined(NRF5) || defined(ESP8266)
#define LARGE_MEMORY 1
#endif

Isto significa que ESP32, ESP8266 e NRF5 são reconhecidos como tendo memória grande e os objetos Result, como FaceResult com mais informação são então definidos e retornados:

#ifdef LARGE_MEMORY
class FaceResult : public Result {
public:
  FaceResult(const void *buf);

public:
  int16_t leye_x;
  int16_t leye_y;
  int16_t reye_x;
  int16_t reye_y;
  int16_t nose_x;
  int16_t nose_y;
  int16_t lmouth_x;
  int16_t lmouth_y;
  int16_t rmouth_x;
  int16_t rmouth_y;
};

Na próxima secção, vamos ligar um ESP32 ao HUSKYLENS e obter os resultados mais completos para o algoritmo de Reconhecimento Facial.

Ligação do HUSKYLENS 2 ao ESP32

O ESP32 lite que estou a usar aqui tem a mesma limitação máxima de corrente de saída de 500mA devido ao regulador de tensão ME6211 incorporado. Portanto, ligamos novamente o ESP32 e o HUSKYLENS via a placa adaptadora de alimentação para evitar sobrecarregar o regulador de tensão.

Abaixo está o diagrama completo de ligações. É essencialmente o mesmo que o do Arduino. No entanto, o VCC está ligado à saída 3.3V do ESP32 e o SCL e SDA estão ligados aos pinos 23 e 19, respetivamente:

Ligação do HUSKYLENS 2 ao ESP32

Os pinos I2C de hardware vão depender da sua placa ESP32. Consulte a folha de dados da sua placa ESP32 ou veja o nosso tutorial Find I2C and SPI default pins para identificar os pinos I2C para uma placa diferente.

Exemplo de Código: Reconhecimento Facial

Neste exemplo de código vamos obter os resultados de deteção do algoritmo Face Recognition. Ele retorna as coordenadas do olho esquerdo e direito, do nariz e dos cantos esquerdo e direito da boca. Veja os pontos brancos na imagem seguinte que mostram esses marcos:

Note que o código seguinte só compila para microprocessadores ESP32, ESP8266 ou NRF5, mas não para Arduino, razão pela qual ligámos um ESP32 ao HUSKYLENS na secção anterior.

// (c) www.makerguides.com
#include "DFRobot_HuskylensV2.h"

#define TASK ALGORITHM_FACE_RECOGNITION

HuskylensV2 huskylens;

void setup() {
  Serial.begin(115200);
  Wire.begin();
  while (!huskylens.begin(Wire)) {
    Serial.println(F("Can't init HUSKYLENS!"));
    delay(100);
  }
  huskylens.switchAlgorithm(TASK);
  Serial.println("running...");
}

void loop() {
  static char text[128];

  while (!huskylens.getResult(TASK)) {
    delay(100);
  }

  while (huskylens.available(TASK)) {
    FaceResult *r = static_cast<FaceResult *>(huskylens.popCachedResult(TASK));
    sprintf(text, "%3d  [%3d %3d  %3d %3d  %3d %3d  %3d %3d  %3d %3d]",
            r->classID,
            r->leye_x,
            r->leye_y,
            r->reye_x,
            r->reye_y,
            r->nose_x,
            r->nose_y,
            r->lmouth_x,
            r->lmouth_y,
            r->rmouth_x,
            r->rmouth_y);
    Serial.println(text);
  }

  delay(1000);
}

Constantes e Objetos

Começamos por definir uma constante TASK para o algoritmo AI, o ALGORITHM_FACE_RECOGNITION. Depois criamos o objeto HuskylensV2 como habitual:

#define TASK ALGORITHM_FACE_RECOGNITION

HuskylensV2 huskylens;

Setup

A função setup mantém-se igual. Iniciamos a comunicação Serial e depois tentamos ligar ao HUSKYLENS. Se falhar e vir “Can’t init HUSKYLENS!” no Monitor Serial, verifique as ligações!

void setup() {
  Serial.begin(115200);
  Wire.begin();
  while (!huskylens.begin(Wire)) {
    Serial.println(F("Can't init HUSKYLENS!"));
    delay(100);
  }
  huskylens.switchAlgorithm(TASK);
  Serial.println("running...");
}

Caso contrário, o algoritmo AI ALGORITHM_FACE_RECOGNITION no HUSKYLENS é ativado via huskylens.switchAlgorithm(TASK) e estamos prontos para detetar faces.

Loop

Há uma alteração importante na função loop. Estamos a fazer cast do resultado retornado pela função huskylens.popCachedResult() para o tipo FaceResult. Este tipo contém as coordenadas dos olhos, nariz e boca da face detetada, que depois imprimimos:

    FaceResult *r = static_cast<FaceResult *>(huskylens.popCachedResult(TASK));
    sprintf(text, "%3d  [%3d %3d  %3d %3d  %3d %3d  %3d %3d  %3d %3d]",
            r->classID,
            r->leye_x,
            r->leye_y,
            r->reye_x,
            r->reye_y,
            r->nose_x,
            r->nose_y,
            r->lmouth_x,
            r->lmouth_y,
            r->rmouth_x,
            r->rmouth_y);
    Serial.println(text);

Se carregar este código no seu ESP32 deve ver a seguinte saída no Monitor Serial, se forem detetadas faces:

Face Recognition results on Serial Monitor
Resultados de Reconhecimento Facial no Monitor Serial

Note que pode executar código semelhante no Arduino UNO, mas só obterá o ponto central e a caixa delimitadora, devido à menor memória do Arduino, por exemplo, poderia alterar a função loop da seguinte forma:

    Result *r = static_cast<Result *>(huskylens.popCachedResult(TASK));
    sprintf(text, "%3d  [%3d %3d  %3d %3d]",
            r->classID,
            r->xCenter,
            r->yCenter,
            r->width,
            r->height);
    Serial.println(text);

Exemplo de Código: Semáforo de Emoções

Neste último exemplo, vamos construir um Semáforo de Emoções. Ele usa o algoritmo Face Emotion Recognition do HUSKYLENS para detetar emoções como “Raiva”, “Neutro” ou “Felicidade” em faces e usamos essa informação para ligar um LED vermelho, amarelo ou verde.

Vou usar um Arduino aqui, mas um ESP32 também funcionaria. Primeiro, precisamos de ligar os LEDs. O diagrama seguinte mostra como ligá-los ao Arduino UNO:

Connecting LEDs to Arduino UNO
Ligar LEDs ao Arduino UNO

Liguei o LED vermelho ao pino 11, o LED amarelo ao pino 10 e o LED verde ao pino 9. Não se esqueça do resistor de 220 Ohm ou similar para limitar a corrente nos LEDs. A foto abaixo mostra a ligação na breadboard:

LEDs connected to Arduino UNO
LEDs ligados ao Arduino UNO

Agora estamos prontos para escrever o código para o nosso Semáforo de Emoções. Ele adiciona funções para controlar os LEDs e estende a função loop para ligar os LEDs dependendo do resultado (emoção) retornado pelo algoritmo de Reconhecimento de Emoções Faciais:

// (c) www.makerguides.com
#include "DFRobot_HuskylensV2.h"

#define RED_LED 11
#define YELLOW_LED 10
#define GREEN_LED 9

#define TASK ALGORITHM_EMOTION_RECOGNITION

HuskylensV2 huskylens;

void initLEDs() {
  pinMode(RED_LED, OUTPUT);
  pinMode(YELLOW_LED, OUTPUT);
  pinMode(GREEN_LED, OUTPUT);
  switchOffLEDs();
}

void switchOffLEDs() {
  digitalWrite(RED_LED, LOW);
  digitalWrite(YELLOW_LED, LOW);
  digitalWrite(GREEN_LED, LOW);
}

void switchOnLED(int led) {
  digitalWrite(led, HIGH);
}

void setup() {
  Serial.begin(115200);
  initLEDs();
  Wire.begin();
  while (!huskylens.begin(Wire)) {
    Serial.println(F("Can't init HUSKYLENS!"));
    delay(100);
  }
  huskylens.switchAlgorithm(TASK);
  Serial.println("running...");
}

void loop() {
  while (!huskylens.getResult(TASK)) {
    delay(100);
  }

  while (huskylens.available(TASK)) {
    Result *r = static_cast<Result *>(huskylens.popCachedResult(TASK));
    Serial.println(r->name);
    switchOffLEDs();
    if (r->name == "Happiness") {
      switchOnLED(GREEN_LED);
    }
    if (r->name == "Neutral") {
      switchOnLED(YELLOW_LED);
    }
    if (r->name == "Anger") {
      switchOnLED(RED_LED);
    }
  }

  delay(1000);
}

Definições

Começamos por definir os pinos para os LEDs e o TASK como ALGORITHM_EMOTION_RECOGNITION :

#define RED_LED 11
#define YELLOW_LED 10
#define GREEN_LED 9

#define TASK ALGORITHM_EMOTION_RECOGNITION

Funções dos LEDs

De seguida implementamos algumas funções para inicializar e controlar os três LEDs:

void initLEDs() {
  pinMode(RED_LED, OUTPUT);
  pinMode(YELLOW_LED, OUTPUT);
  pinMode(GREEN_LED, OUTPUT);
  switchOffLEDs();
}

void switchOffLEDs() {
  digitalWrite(RED_LED, LOW);
  digitalWrite(YELLOW_LED, LOW);
  digitalWrite(GREEN_LED, LOW);
}

void switchOnLED(int led) {
  digitalWrite(led, HIGH);
}

Setup

Na função setup inicializamos a comunicação serial e I2C e os LEDs. Depois ligamos ao HUSKYLENS via huskylens.begin(Wire) e iniciamos o algoritmo AI como habitual via huskylens.switchAlgorithm(TASK):

void setup() {
  Serial.begin(115200);
  initLEDs();
  Wire.begin();
  while (!huskylens.begin(Wire)) {
    Serial.println(F("Can't init HUSKYLENS!"));
    delay(100);
  }
  huskylens.switchAlgorithm(TASK);
  Serial.println("running...");
}

Loop

Finalmente, temos a função loop, onde obtemos o resultado da deteção de Emoção e dependendo da emoção detetada ligamos o LED vermelho, amarelo ou verde:

    Result *r = static_cast<Result *>(huskylens.popCachedResult(TASK));
    Serial.println(r->name);
    switchOffLEDs();
    if (r->name == "Happiness") {
      switchOnLED(GREEN_LED);
    }
    if (r->name == "Neutral") {
      switchOnLED(YELLOW_LED);
    }
    if (r->name == "Anger") {
      switchOnLED(RED_LED);
    }
  }

Note que além de “Felicidade”, “Raiva” e “Neutro” existem outras emoções como “Medo”, “Nojo”, “Triste” e “Surpresa”, às quais o código atual não reage. Mas pode facilmente estendê-lo para essas emoções também.

Se executar o código no seu Arduino, o HUSKYLENS deve ativar o algoritmo de Reconhecimento de Emoções Faciais:

Select Face Emotion Recognition on HUSKYLENS
Selecionar Reconhecimento de Emoções Faciais no HUSKYLENS

e no Monitor Serial deve ver uma saída semelhante à seguinte. Também os LEDs correspondentes às emoções detetadas devem acender:

Emotion detection results on Serial Monitor
Resultados de deteção de emoções no Monitor Serial

E é tudo! Os exemplos de código e diagramas de ligações acima devem facilitar o seu início com o HUSKYLENS 2.

Conclusões

Este tutorial mostrou-lhe como começar com o sensor de visão AI HUSKYLENS 2. Aprendeu como ligá-lo a um Arduino ou ESP32 e como obter resultados de deteção para os vários algoritmos AI incorporados no HUSKYLENS 2. Recomendo também que leia o Tutorial for HUSKYLENS 2 and Arduino Code Programming da DFRobot.

O HUSKYLENS 2 torna extremamente fácil familiarizar-se com várias aplicações AI como reconhecimento de objetos e faces, reconhecimento de gestos manuais e pose, OCR e muitas outras. Pode facilmente treinar/ajustar alguns dos algoritmos AI e até descarregar os seus próprios modelos AI personalizados. Para mais detalhes veja DFRobot’s Wiki for the HUSKYLENS 2.

A maior vantagem de um sensor AI como o HUSKYLENS 2 é que pode executar modelos AI localmente no dispositivo. Não precisa de uma ligação Wi-Fi a um serviço na cloud com latências potencialmente elevadas ou problemas de ligação.

As desvantagens são um consumo de energia potencialmente mais elevado e uma precisão inferior dos modelos. Eu medi uma corrente de até 420mA para o modelo de Reconhecimento Óptico de Caracteres (OCR), que parece ser o modelo com maior consumo de energia.

A precisão dos modelos varia. Achei que o reconhecimento de emoções faciais funciona muito bem, enquanto o modelo de reconhecimento de objetos produziu muitas classificações erradas. Provavelmente vai querer usar o seu próprio modelo personalizado com um número menor de classes para tarefas de reconhecimento de objetos ou experimentar a função Self-Learning Classifier.

Se tiver alguma dúvida, sinta-se à vontade para deixá-la na secção de comentários.

Boas experiências a criar 😉