A visão computacional é um campo interdisciplinar que envolve uma série de procedimentos de processamento de imagem e algoritmos sofisticados de inteligência artificial e aprendizado de máquina para extrair significados de imagens e vídeos, como detectar objetos e faces, reconhecer caracteres, identificar placas de carro e até fazer aquela selfie engraçada com filtros faciais do Instagram ou Facebook. Uma das bibliotecas mais consagradas desse assunto é a OpenCV, de código aberto, disponível em C/C++ otimizado, Python e Java.
Para construir a aplicação, é possível aliar a visão computacional com uma bela, ou melhor, fofa interface de usuário em Qt, que é um framework de desenvolvimento em C++/QML (Qt Modeling Language) multiplataforma, o qual possui uma IDE chamada QtCreator.
Neste artigo iremos iniciar com Qt e OpenCV por meio de uma aplicação para detecção de faces frontais em fotos com uma simples interface de usuário. Apesar da simplicidade da nossa aplicação de demonstração, é possível alcançar resultados bastante interessantes e mais sofisticados com o uso destas ferramentas poderosas, como no exemplo abaixo que realiza o reconhecimento de caracteres, detecta faces, lê QR Codes, códigos de barras em fotos e as armazena em uma galeria, acessíveis através de uma interface de usuário mais elegante com animações e transições mais suaves. Veja a demonstração a seguir:
Essa combinação de funcionalidades pode ser um tanto computacionalmente custosa, portanto, para alcançar uma boa performance é preciso escolher cautelosamente o hardware. Nesta empreitada, será necessário utilizar uma placa com memória RAM e frequência de CPU suficientemente altos para obter fluidez na tela e velocidade nos processamentos do OpenCV. Portanto, a configuração do QtCreator e instalação do OpenCV serão realizados para o Computador em Módulo (CoM) Apalis iMX6Q com 1GB de RAM, 4 núcleos de CPU na frequência máxima de 996 MHz com heatsink, a placa base Ixora e o módulo de câmera CSI OV5640.
Mãos à obra!
Para começar o desenvolvimento com Qt e OpenCV, vamos compilar e instalar a imagem Boot2Qt (B2Qt), fazendo uso do Kernel do Linux Embarcado fornecido pela Toradex. A B2Qt e sua toolchain são fornecidas pela Qt Company, especificamente para sistemas embarcados com uma série de otimizações, possuindo os mais diversos CoMs suportados, como Apalis e Colibri iMX6, Colibri iMX7 e VFxx, Raspberry Pi, BeagleBone Black e entre outros.
Instalando a imagem B2Qt: OpenCV + Qt
Agora vamos percorrer os passos para gerar com Yocto uma imagem B2Qt para o CoM Apalis iMX6Q com OpenCV. Os passos iniciais de eliminação das dependências, clone do repositório e configuração das variáveis de ambiente estão devidamente indicados no tutorial do Qt de compilação da B2Qt.
Como estamos utilizando o CoM Apalis iMX6Q, iremos adicionar a layer da Toradex e o pacote do OpenCV.
# Adicionando o instalador Toradex
[build-apalis-imx6] $ cd ../sources
[sources] $ git clone https://munoz0raul@bitbucket.org/munoz0raul/meta-toradex-installer.git
[sources] $ cd ../build-apalis-imx6/
# Adicione o layer no bblayers.conf
[build-apalis-imx6] $ vi conf/bblayers.conf
+ ${BSPDIR}/sources/meta-toradex-installer \
# Adicione o OpenCV no local.conf
[build-apalis-imx6] $ vi conf/local.conf
+ IMAGE_INSTALL_append = “ opencv ”
# Avise o assembler para usar instruções thumb
[build-apalis-imx6]$ vi ../sources/meta-openembedded/meta-oe/recipes-support/opencv/opencv_3.3.bb
+ CXXFLAGS += " -Wa,-mimplicit-it=thumb"
# Compilando a imagem. Este passo pode durar algumas horas!
[build-apalis-imx6]$ bitbake b2qt-embedded-qt5-image
Para instalar a imagem, será necessário preparar um cartão SD formatado em FAT32. Os passos para tal e a instalação da B2Qt no CoM estão presentes neste artigo.
Para utilizar o módulo de câmera CSI, é necessário também alterar a device tree, isto é, na interrupção do boot, rode os comandos:
Apalis iMX6 # setenv fdt_file imx6q-apalis-ixora-v1.1.dtb Apalis iMX6 # saveenv Apalis iMX6 # boot
É possível também utilizar uma Webcam USB, caso você não possua o módulo de câmera analógico.
Verifique que a instalação do OpenCV foi bem sucedida testando em Python:
root@b2qt-apalis-imx6:~# python3 Python 3.5.2 (default, Nov 21 2017, 14:47:49) [GCC 6.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import cv2 >>> cv2.__version__ '3.3.0-dev'
Certifique-se procurando as bibliotecas:
root@b2qt-apalis-imx6:~# find /usr/lib -name "*opencv*"
Agora vamos gerar a SDK com as bibliotecas do OpenCV. Volte para o ambiente de compilação da imagem e siga os passos a seguir:
# Force as libs do OpenCV na SDK [build-apalis-imx6]$ vi ../sources/meta-qt5/recipes-qt/meta/meta-toolchain-qt5.bb + TOOLCHAIN_TARGET_TASK_append = " opencv " # Gerando a sdk. Este passo pode durar poucas horas! [build-apalis-imx6]$ bitbake meta-toolchain-b2qt-embedded-qt5-sdk # Instalando o Kit de Compilação [build-apalis-imx6]$ cd tmp/deploy/sdk [sdk]$ ./b2qt-x86_64-meta-toolchain-b2qt-embedded-qt5-sdk-apalis-imx6.sh Boot to Qt for Embedded Linux SDK installer version 2.2.2 ========================================================= Enter target directory for SDK (default: /opt/b2qt/2.2.2): /opt/b2qt-opencv3.3/2.2.2 You are about to install the SDK to "/opt/b2qt-opencv3.3/2.2.2/". Proceed[Y/n]? Y
Verifique que as bibliotecas do OpenCV estão presentes na SDK pela busca:
[sdk]$ find /opt/b2qt-opencv3.3/2.2.2/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/ -name opencv
Configurando o Kit de Compilação do QtCreator
O QtCreator permite que sejam configurados kits de compilação para diversas plataformas. Assim, se faz necessário indicar os caminhos de compiladores, debuggers e entre outros. Para mais informações a respeito da configurações de kits de compilação, acesse este link.
A aplicação
A fim de incluir as bibliotecas do OpenCV no projeto em Qt, precisamos indicar no arquivo .pro os caminhos. O exemplo de detecção de rostos em imagem que será apresentado precisará apenas de 3 bibliotecas:
+ INCLUDEPATH += \ + /opt/b2qt/2.2.2/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/include/opencv \ + LIBS += -lopencv_core \ + -lopencv_imgproc \ + -lopencv_highgui \
Algoritmo
A aplicação de exemplo desenvolvida é uma câmera que detecta faces através de cascatas de classificadores Haar (Haar Feature-based Cascades Classifiers), com uma interface de usuário bastante simples.
O algoritmo utilizado para detecção de rostos foi proposto por Paul Viola e Michael Jones no artigo “Rapid Object Detection using a Boosted Cascade of Simple Features” em 2001, cuja estratégia é baseada em aprendizado de máquina com treinamento a partir de imagens negativas (que não contém faces) e positivas (que contém faces) para gerar o classificador.
É possível encontrar arquivos XML de classificadores fornecidos pelo OpenCV no sistema de arquivos do CoM em /usr/share/OpenCV/haarcascades/ inclusive com outros tipos de objetos treinados, como olhos, sorriso.
Código
O desenvolvimento da aplicação utilizou QML, a linguagem declarativa de interfaces do Qt e C++, onde são exploradas as bibliotecas do OpenCV para detectar faces nas imagens tiradas da câmera.
No QML, existem 2 tipos importantes para invocar a câmera: VideoOutput e Camera, em que o primeiro disponibiliza a saída do segundo. Assim, é possível selecionar a câmera e configurar o VideoOutput para disponibilizar o stream de vídeo do dispositivo.
Estes recursos foram utilizados para mostrar a saída da câmera e tirar foto, que é capturada para a localização padrão do Qt, a qual é enviada ao C++ para a rotina de detecção de faces.
Neste exemplo é carregado o classificador direto do sistema de arquivos do CoM utilizando a classe CascadeClassifier do OpenCV, que provê um método de detecção, cuja saída é o vetor de retângulos onde as faces se localizam. A seguir encontra-se o trecho de código referente à classe citada:
CascadeClassifier faceCascade;
faceCascade.load(faceClassifierPath) // carrega classificador
vector<Rect> faces;
faceCascade.detectMultiScale(gray,// Mat da imagem em escala de cinza
faces, // vetor de retangulos das faces
1.1, // fator de escala
3, // numero min vizinhos
0 | CASCADE_SCALE_IMAGE, // flags
Size(30,30)); // tam min do objeto detectado
for(int i=0; i<faces.size(); i++){
Rect r = faces[i];
Point center;
int radius;
center.x = cvRound(r.x + r.width*0.5);
center.y = cvRound(r.y + r.height*0.5);
radius = cvRound((r.width + r.height)*0.25);
circle(src, center, radius, Scalar(255, 0, 0), 3, 8, 0);
}
Para usar a aplicação, basta rodá-la com o AppController da imagem B2Qt:
root@b2qt-apalis-imx6:~# /usr/bin/appcontroller /caminho/do/binario
Esta aplicação está disponível no Github.

Saiba mais
Compilação e instalação do OpenCV 3.1.0 na Raspberry Pi Zero W
Contagem de objetos em movimento com OpenCV e Python usando Raspberry Pi








Cara Luísa, excelente artigo.
Uma pergunta, eu preciso de uma licença do QT for Device Creation ou posso baixar o Boot2QT e o toolchain com a versão free?
Abraços,
Obrigada!
Sobre a licença: pra não ter erro, é sempre bom consultar a documentação do Qt, que é em geral muito boa:
Nesse link https://www1.qt.io/licensing-comparison/ podemos ver a imagem pre-built e as layers pra customizar essa imagem pre-built nas últimas 2 linhas da tabela, que aparecem respectivamente como licença comercial e GPLV2/GPLV3.
Olá bom dia Luisa você desenvolve algum produto? Poderia entrar em contato se sim por gentileza! tiagoborges@pm.mt.gov.br
Obrigada!