Como adicionar OpenCV em aplicações Qt

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.

Hardware escolhido com aplicação OpenCV + Qt rodando
Figura 1: Hardware escolhido com aplicação OpenCV + Qt rodando
Tela inicial da aplicação OpenCV + Qt de detecção de faces frontais
Figura 2:  Tela inicial da aplicação OpenCV + Qt de detecção de faces frontais

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

Teste da aplicação OpenCV + Qt de detecção de faces frontais
Figura 3: Teste da aplicação OpenCV + Qt de detecção de faces frontais

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

Aplicação de visão computacional com OpenCV

Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.
Comentários:
Notificações
Notificar
3 Comentários
recentes
antigos mais votados
Inline Feedbacks
View all comments
Juliano Sansão
Juliano Sansão
21/05/2018 10:55

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,

Tiago
Tiago
Reply to  Luísa Burini
10/11/2018 12:06

Olá bom dia Luisa você desenvolve algum produto? Poderia entrar em contato se sim por gentileza! tiagoborges@pm.mt.gov.br
Obrigada!

Home » Linux Embarcado » Como adicionar OpenCV em aplicações Qt

EM DESTAQUE

WEBINARS

VEJA TAMBÉM

JUNTE-SE HOJE À COMUNIDADE EMBARCADOS

Talvez você goste: