Manual
do
Maker
.
com
Simplicidade passa longe dessa área de visão computacional e inteligência artificial. Não é só a questão de programar, serão suas mãos a configurar o sistema; instalar driver de placa de vídeo, suporte a CUDA, compilação do OpenCV etc.
Esse artigo só foi possível graças à ajuda dada pelo Leonardo Lontra, um especialista em IA e CV em sistemas embarcados, que tem participação no código do próprio OpenCV. Enfim, quer experimentar algo novo e incrível? Então prepare seu Linux para receber configurações!
O primeiro passo é criar um container docker. Dessa vez não é só instalar uma imagem pronta como o OpenFace. Vamos pegar um sistema "cru", então lapidá-lo. Para isso, será necessário ter o docker instalado. Para fazê-lo, sugiro que siga o tutorial da Digital Ocean, caso não o tenha feito ainda.
Depois de instalado, siga as operações como root para simplificar as coisas:
sudo su
service docker start
Para baixar a imagem oficial do Debian é bastante simples. Digite agora no terminal (seja ele qual for; konsole, gtkterm, xterm):
docker pull debian
Em pouco tem uma imagem mínima estará disponível no sistema. Daí você pode criar seu container (já descrevi nesse arquivo de CUDA):
docker run -p 9000:9000 -p 8000:8000 --name DobitAoByte --hostname OpenCV -t -i bamos/openface /bin/bash
Se não conectar diretamente ao console, verifique se a imagem está rodando:
docker ps
Se estiver rodando, aparecerá o nome no último campo:
Basta conectar-se ao container:
docker attach DobitoByte
E dê Enter 2 vezes.
Mude o nível de diretório para o home do root:
cd
Instale uns pacotes:
apt-get update
apt-get install git wget
Agora, clone o repositório do Lontra:
git clone https://github.com/lhelontra/build_opencv.git
Se você ainda não configurou no computador nativo, nem criar o container será possível. Faça esse procedimento primeiro no sistema nativo, se for o caso. Depois, faça no container.
Adicione o repositório (isso é para Debian):
deb http://httpredir.debian.org/debian/ stretch main contrib non-free
E faça a instalação dos pacotes necessários:
apt-get update
apt-get install linux-headers-* nvidia-driver
apt-get install nvidia-cuda-dev nvidia-cuda-toolkit nvidia-driver
Vai demorar um bocado até tudo estar pronto. Se houver problemas pelo caminho, solucione-os. O próximo passo é modificar o arquivo de configuração para compilar o OpenCV4 (tudo isso já no container):
apt-get install vim vim-common vim-scripts
cd build_opencv
vi configs/default_cuda.conf
Se não souber usar o vi, recomendo que utilize outra coisa; nano, pico, midnight-commander. Vá até a parte gui support e deixe-a assim:
# gui support
FLAGS+=" -D WITH_OPENGL=OFF"
FLAGS+=" -D WITH_GTK=ON"
FLAGS+=" -D WITH_QT=OFF"
Antes de iniciar a compilação, já precavenha-se do iminente erro relacionado ao v4l:
sudo su
mkdir /usr/include/ffmpeg
cd /usr/include/ffmpeg
ln -sf /usr/include/x86_64-linux-gnu/libavcodec/*.h ./
ln -sf /usr/include/x86_64-linux-gnu/libavformat/*.h ./
ln -sf /usr/include/x86_64-linux-gnu/libswscale/*.h ./
sudo apt-get install python-software-properties
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo add-apt-repository ppa:jonathonf/gcc-8.0
sudo apt-get update
sudo apt-get install gcc-8 g++8
Agora iniciando o processo de compilação:
./build_opencv.sh -c configs/default_cuda.conf --build
O que precisar confirmar com Y, não deixe de fazê-lo. Quando for perguntada a versão do GTK, escolha 3.
As dependências serão baixadas e instaladas automaticamente. O processo leverá um tempo gigantesco, mas deve funcionar no final.
Instalei alguns pacotes mais, você pode preceder a compilação com essa instalação:
sudo apt-get install qt5-default qttools5-dev-tools
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install wget unzip
sudo apt-get install build-essential cmake pkg-config
sudo apt-get install libjpeg8-dev libtiff5-dev libjasper-dev libpng12-dev
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
sudo apt-get install libxvidcore-dev libx264-dev
sudo apt-get install libgtk-3-dev
sudo apt-get install libatlas-base-dev gfortran
sudo apt-get install python2.7-dev python3.5-dev
Copie o pacote para /root.
cp /root/new/build_opencv/sources/opencv-4.0.0/build/opencv_4.0.0-1_amd64.deb /root/
Em outra aba de terminal, copie o pacote de dentro do container para o sistema nativo:
docker cp gtx1050:/root/opencv_4.0.0-1_amd64.deb .
Instale o pacote:
dpkg -i opencv_4.0.0-1_amd64.deb
Depois, copie a lib cv2.so para o novo path:
cp /usr/local/lib/pyhon2.7/dist-packages/cv2.so /usr/local/python/cv2/python-2.7/
E faça o teste de importação da lib (ainda vai ter coisa pra resolver, mas ao menos haverá pistas):
python -c "import cv2"
Tive um erro com a versão da libcudart.
Vá ao site da Nvidia e baixe o pacote. Depois:
apt-get install gnupg-curl
dpkg -i cuda-repo-ubuntu1604_10.0.130-1_amd64.deb
apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub
apt-get update
apt-get install cuda
Por fim, faça um reboot.
Ainda com probemas? Depois do reboot, voltei a ter o problema, mas a biblioteca estava lá onde deveria estar. Bem, eu tenho uma gambiarra na manga que funcionou:
import sys
sys.path.append("/usr/local/lib/pyhon2.7/dist-packages/")
import cv2
Agora, pegue os arquivos pbe pb.txt do arquivo opencv_face_detector.
Coloque-os no mesmo nível do script Python que fará o face detection. Eu chamei de facednn.py:
#!/usr/bin/env python
# # -*- coding: UTF-8 -*-
# Author: Djames Suhanko <djames.suhanko@gmail.com>
# Created: Qui 20 Dez 2018 21:12:35 -02
# Last Update: Qui 20 Dez 2018 21:12:35 -02
# File: <name>
# Notes:
from __future__ import division
import time
import sys
sys.path.append("/usr/local/lib/pyhon2.7/dist-packages/")
import cv2
def detectFaceOpenCVDnn(net, frame):
frameOpencvDnn = frame.copy()
frameHeight = frameOpencvDnn.shape[0]
frameWidth = frameOpencvDnn.shape[1]
blob = cv2.dnn.blobFromImage(frameOpencvDnn, 1.0, (300, 300), [104, 117, 123], False, False)
net.setInput(blob)
detections = net.forward()
bboxes = []
for i in range(detections.shape[2]):
confidence = detections[0, 0, i, 2]
if confidence > conf_threshold:
x1 = int(detections[0, 0, i, 3] * frameWidth)
y1 = int(detections[0, 0, i, 4] * frameHeight)
x2 = int(detections[0, 0, i, 5] * frameWidth)
y2 = int(detections[0, 0, i, 6] * frameHeight)
bboxes.append([x1, y1, x2, y2])
cv2.rectangle(frameOpencvDnn, (x1, y1), (x2, y2), (0, 255, 0), int(round(frameHeight/150)), 8)
return frameOpencvDnn, bboxes
if __name__ == "__main__" :
# OpenCV DNN supports 2 networks.
# 1. FP16 version of the original caffe implementation ( 5.4 MB )
# 2. 8 bit Quantized version using Tensorflow ( 2.7 MB )
DNN = "TF"
if DNN == "CAFFE":
modelFile = "res10_300x300_ssd_iter_140000_fp16.caffemodel"
configFile = "deploy.prototxt"
net = cv2.dnn.readNetFromCaffe(configFile, modelFile)
else:
modelFile = "opencv_face_detector_uint8.pb"
configFile = "opencv_face_detector.pbtxt"
net = cv2.dnn.readNetFromTensorflow(modelFile, configFile)
conf_threshold = 0.7
source = 0
if len(sys.argv) > 1:
source = sys.argv[1]
cap = cv2.VideoCapture(0)
hasFrame, frame = cap.read()
vid_writer = cv2.VideoWriter('output-dnn-{}.avi'.format(str(source).split(".")[0]),cv2.VideoWriter_fourcc('M','J','P','G'), 15, (frame.shape[1],frame.shape[0]))
frame_count = 0
tt_opencvDnn = 0
while(1):
hasFrame, frame = cap.read()
if not hasFrame:
break
frame_count += 1
t = time.time()
outOpencvDnn, bboxes = detectFaceOpenCVDnn(net,frame)
tt_opencvDnn += time.time() - t
fpsOpencvDnn = frame_count / tt_opencvDnn
label = "OpenCV DNN ; FPS : {:.2f}".format(fpsOpencvDnn)
cv2.putText(outOpencvDnn, label, (10,50), cv2.FONT_HERSHEY_SIMPLEX, 1.4, (0, 0, 255), 3, cv2.LINE_AA)
cv2.imshow("Face Detection Comparison", outOpencvDnn)
vid_writer.write(outOpencvDnn)
if frame_count == 1:
tt_opencvDnn = 0
k = cv2.waitKey(10)
if k == 27:
break
cv2.destroyAllWindows()
vid_writer.release()
Depois, execute-o:
python facednn.py
E o resultado será algo como a imagem de destaque, mas provavelmente com um susto menor.
Meus agradecimentos ao meu mestre Leonardo Lontra, que sempre me orienta em ambos, visão computacional e inteligência artificial, além de ajudar a resolver os problemas que aparecem no trajeto. Esse código de exemplo também é uma cortesia dele. Não deixem de visitar seu repositório, lá está cheio de tesouros.
Fiz um vídeo curto só para mostrar a robustez da detecção, tire as crianças da sala para não assustá-las com minhas caretas. Quem usa o haarcascade com frontal face sabe que se deslocar o rosto ou inclinar a cabeça, já era a detecção, impressione-se!
Deixe seu like no vídeo, inscreva-se no canal e clique no sininho para receber notificações. Até a próxima!
Autor do blog "Do bit Ao Byte / Manual do Maker".
Viciado em embarcados desde 2006.
LinuxUser 158.760, desde 1997.