====== Cinematography panning and actor tracking ======
===== Introduction =====
Apres avoir finit mon dernier [[diy:projets:panorama|tutoriel]] sur les panorama, j'ai pensais à une autre utilisation du double servo
moteurs, afin de suivre une personne automatiquement, le raspberry pi serait le cameraman et moi l'acteur,
je n'aurrais qu'a jouer mon rôle, grâce à opencv et les gpio du raspberry pi tout cela est possible.
Premièrement je vous indiquerais comment installer la derniere version d'opencv 3.1 en ce jour sur un raspberry pi.
Puis comment je vais pouvoir avec opencv m'identifier sur une simple image, quel algorithme et avec une performance acceptable car la reconnaissance doit se faire en temp réel.
Comment je vais utiliser le fait de me traquer et de bouger la camera en même temp, il y aura beaucoup de flou,
est-ce que je traite une image flou ?, ou avec un traitement d'image (Sobel) je peux deduire qu'une image est flou et ne pas traiter, faire du traitement d'image sur une camera qui bouge dans tout les sens ne va pas être facile, mais on peut déja exclure la reconnaissance de mouvement (OMG, etc) car l'image n'est pas fixe et l'arriere plan aussi.
Question de performance, quel algo sera le meilleur ?
----
===== Installation de la derniere version d'opencv sur raspberry pi =====
==== Installation des dependances ====
sudo apt-get -q -y update
sudo apt-get -q -y install build-essential
sudo apt-get -q -y install cmake
sudo apt-get -q -y install pkg-config
sudo apt-get -q -y install libpng12-0 libpng12-dev libpng++-dev libpng3
sudo apt-get -q -y install libpnglite-dev libpngwriter0-dev libpngwriter0c2
sudo apt-get -q -y install zlib1g-dbg zlib1g zlib1g-dev
sudo apt-get -q -y install pngtools libtiff4-dev libtiff4 libtiffxx0c2 libtiff-tools
sudo apt-get -q -y install libjpeg8 libjpeg8-dev libjpeg8-dbg libjpeg-progs
sudo apt-get -q -y install ffmpeg libavcodec-dev libavcodec52 libavformat52 libavformat-dev
sudo apt-get -q -y install libgstreamer0.10-0-dbg libgstreamer0.10-0 libgstreamer0.10-dev
sudo apt-get -q -y install libxine1-ffmpeg libxine-dev libxine1-bin
sudo apt-get -q -y install libunicap2 libunicap2-dev
sudo apt-get -q -y install libdc1394-22-dev libdc1394-22 libdc1394-utils
sudo apt-get -q -y install swig
sudo apt-get -q -y install libv4l-0 libv4l-dev
sudo apt-get -q -y install python-numpy
sudo apt-get -q -y install libpython2.6 python-dev python2.6-dev
sudo apt-get -q -y install libpython2.7 python-dev python2.7-dev
sudo apt-get -q -y install libgtk2.0-dev pkg-config
sudo apt-get -q -y install mplayer
==== Téléchargement de la derniere version sur sourceforge.net ====
Allez sur ce [[https://sourceforge.net/projects/opencvlibrary/files/opencv-unix/|lien]]
Téléchargez la dernière version de opencv
Extraire le dossier et y rentrer
==== Compilation ====
Executez ceci
mkdir release
cd release
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D BUILD_PYTHON_SUPPORT=ON -D BUILD_EXAMPLES=ON ..
make
sudo make install
Après une bonne heure de compilation, vous avez opencv utilisable
----
===== Detection de ma personne =====
On aurrait pu utiliser la detection de mouvement décrit dans ce [[https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_video/py_bg_subtraction/py_bg_subtraction.html#background-subtraction|tuto]] en éliminant au préalable l'arrière plan, mais ceci n'est possible qu'avec un plan fixe, or
ce n'est pas le cas içi.
Mais on utilisera ceçi dans un prochain tuto, ... :-X
Le choix à été fait sur l'utilisation d'une reconnaissance de visage. voir ce [[https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_objdetect/py_face_detection/py_face_detection.html#face-detection|lien]] pour plus d'info.
En effet ca s'approche de ce que Yolo peut faire en temp réel, c'est du deep learning, on peut entrainer
l'algorithme à reconnaitre ce qu'on veut spécifiquement.
Voir ce [[https://docs.opencv.org/2.4/doc/user_guide/ug_traincascade.html|lien]] pour plus d'info.
On aurra pour faire ce tuto pas besoin d'entrainer l'algorithme car des fichiers existe déja pour reconnaître
diverses partie du corps humain.
Vous avez tous les fichiers dans le repertoire /usr/local/share/OpenCV/haarcascades/
Nous nous concentrerons sur le fichier haarcascade_frontalface_default.xml
pour suivre les visages.
Utilisons tous ceci pour voir ce que ça donne sur une image de foule prise sur google image.
Import basique opencv
import numpy as np
import cv2
Chargement de la video et de cascade
face_cascade = cv2.CascadeClassifier('haarcascades/haarcascade_frontalface_default.xml')
# face_cascade = cv2.CascadeClassifier('haarcascades/haarcascade_lowerbody.xml')
cap = cv2.VideoCapture(0)
width =cap.get(cv2.CAP_PROP_FRAME_WIDTH)
height =cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
Pour chaque frame du stream, on detect les visages, on les entoures, et on dessines un point au centre de
chaque rectangle/visage car permettront de centrer la camera sur un visage.
On quite en appuyant sur q pour quit
while(1):
ret, img = cap.read()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
print(faces)
continue
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)
middle =[cv2.KeyPoint(x +w /2, y +h /2, 1)]
img =cv2.drawKeypoints(img, middle, img)
# roi_gray = gray[y:y+h, x:x+w]
# roi_color = img[y:y+h, x:x+w]
# eyes = eye_cascade.detectMultiScale(roi_gray)
# for (ex,ey,ew,eh) in eyes:
# cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
cv2.imshow('img', img)
k = cv2.waitKey(30) & 0xff
if k == 27:
break
Pour finir on enregistre la dernière image et on free les fenêtres.
cv2.imwrite("haarDetection.jpg", img)
# cv2.waitKey(0)
cv2.destroyAllWindows()
On regarde ce que ça donne sur une image de foule
{{ :diy:projets:haardetection.jpg?direct&600 |}}
Le résultat est pas mal, ca suffira, et j'arrive a faire du 10fps en utilisant mon pc et non le raspberry pi, donc on verra par la suite, si jamais le raspberry pi n'est pas asser rapide on pourra faire un programme déporté sur un pc, à voir...
===== Petit cours d'optique (rappel géometrie) =====
Prenons l'exemple ou je vois avec opencv qu'un visage se trouve à une coordonnée telle que x=50 y=100.
Je connais la taille de l'image donc le point milieu.
Mais comment je sais de combien de degree j'incline mes deux servos ???
Pour cela faisons un petit rappel géometrique de collège
En attente ...