
Raspberry Pi – Reconeixement facial
Abans de res! aquesta setmana estaré pel VMworld a Barcelona amb un grupet de bloggers i cracs, el que vulgui compartir bons moments que em passi un mail i ens veiem aquí! Bo, al torró, us deixo aquest document amb els passos seguits per aconseguir que una Raspberry Pi amb una camara USB connectada, reconegui cares!
Haurem d'instal·lar OpenCV i posteriorment mitjançant l'ús d'un script aprendrem les cares que ens interessin, jo li ensenya la màgia i la de la meva txabala. Amb un altre script arrencarem la funció de reconeixement i en detectar la meva cara executarà un script i un altre diferent en reconèixer-lo a la txabala.
El primer serà instal·lar els prerequisits d'OpenCV o algun que puguem necessitar:
[sourcecode language =”plain”]sudo apt-get install build-essential cmake pkg-config python-dev libgtk2.0-dev libgtk2.0 zlib1g-dev libpng-dev libjpeg-dev libtiff-dev libjasper-dev libavcodec-dev swig unzip vim
sudo apt-get install python-numpy python-opencv
sudo apt-get instal·lar python-pip
sudo apt-get install python-dev
sudo pip instal·lar picamera
sudo pip instal·lar rpio
sudo apt-get install v4l2ucp v4l-utils libv4l-dev[/sourcecode]
Ens descarregamos OpenCV, lo compilamos y lo instalamos:
[sourcecode language =”plain”]wget http://downloads.sourceforge.net/project/opencvlibrary/opencv-unix/2.4.9/opencv-2.4.9.zip
Descomprimeix opencv-2.4.9.zip
cd opencv-2.4.9
cmake -DCMAKE_BUILD_TYPE=ALLIBERAMENT -DCMAKE_INSTALL_PREFIX=/usr/local -DBUILD_PERF_TESTS=OFF -DBUILD_opencv_gpu=OFF -DBUILD_opencv_ocl=OFF
make
sudo make install[/sourcecode]
Bé, per al reconeixement facial, nos descarregaremos primerament una petita BD de caras, perquè tingui millor precisió i a la qual afegirem la nostra cara o les que ens interessin a posteriori. Ens baixem la BD d'exemple de la Database of Faces d'AT&T Laboratories Cambridge, prèviament creem la carpeta on posarem tot el nostre contingut i ho descomprimim:
[sourcecode language =”plain”]mkdir /home/pi/recoFacial
cd /home/pi/recoFacial
wget http://www.cl.cam.ac.uk/Research/DTG/attarchive/pub/data/att_faces.zip
unzip att_faces.zip[/sourcecode]
Ens baixem ara aquest XML i el descomprimim a /home/pi/recoFacial/:
[sourcecode language =”plain”]wget http://www.bujarra.com/wp-content/uploads/2016/08/haarcascade_frontalface_alt.zip
unzip haarcascade_frontalface_alt.zip[/sourcecode]
Al final del document, us deixo un parell de fitxers de python, un serà per aprendre cares (capture.py) i l'altre per reconèixer-les (reconocimiento.py), haureu de fer-los executables:
[sourcecode language =”plain”]chmod +x reconocimiento.py capture.py[/sourcecode]
I una recomanació, seria elevar el nombre d'imatges que captura per reconèixer-nos la cara quan l'aprèn, en aquest cas, en capture.py, en comptes de 20 imatges per defecte, podrem posar per exemple a 100.
Per aprendre una cara executarem:
[sourcecode language =”plain”]python capture.py nomPersona[/sourcecode]
Per començar a detectar i reconèixer cares:
[sourcecode language =”plain”]python reconocimiento.py[/sourcecode]
capture.py
[sourcecode language =”plain”]
import cv2, sys, numpy, us
size = 4
fn_haar = 'haarcascade_frontalface_alt.xml’
fn_dir = 'att_faces/orl_faces’
fn_name = sys.argv[1]
path = os.path.join(fn_dir, fn_name)
if not os.path.isdir(path):
os.mkdir(path)
(im_width, im_height) = (112, 92)
haar_cascade = cv2. CascadeClassifier(fn_haar)
webcam = cv2. VideoCapture(0)
count = 0
while count > 100:
(rval, im) = webcam.read()
im = cv2.flip(im, 1, 0)
gray = cv2.cvtColor(im, cv2. COLOR_BGR2GRAY)
mini = cv2.resize(gray, (gray.shape[1] / size, gray.shape[0] / size))
faces = haar_cascade.detectMultiScale(mini)
faces = sorted(faces, key = lambda x: x[3])
si cares:
face_i = cares[0]
(x, y, w, h) = [v * Mida per a V en face_i]
cara = gris[y:y + h, x:x + w]
face_resize = cv2.resize(cara, (im_width, im_height))
pin=ordenat([Int(n[:n.trobar(‘.’)]) per a n a os.listdir(path)
si n[0]!=’.’ ]+[0])[-1] + 1
cv2.imwrite('%s/%s.png’ % (path, pin), face_resize)
cv2.rectangle(im, (x, y), (x + w, y + h), (0, 255, 0), 3)
cv2.putText(im, fn_name, (x – 10, y – 10), CV2. FONT_HERSHEY_PLAIN,
1,(0, 255, 0))
recompte += 1
cv2.imshow('OpenCV', im)
clau = cv2.waitKey(10)
si clau == 27:
trencar
[/sourcecode]
reconocimiento.py
[sourcecode language =”plain”]
import cv2, sys, numpy, us
size = 4
fn_haar = 'haarcascade_frontalface_alt.xml’
fn_dir = 'att_faces/orl_faces’
# Part 1: Creació de fisherRecognizer
print('Formando…’)
# Crear una llista d'imatges i una llista de nombres corresponents
(Imatges, Etiquetes, Noms, id) = ([], [], {}, 0)
per (subdirs, dirs, fitxers) a os.walk(fn_dir):
per a subdir en dirs:
Noms[id] = subdir
subjectpath = os.path.join(fn_dir, subdir)
per al nom del fitxer a os.listdir(Temàtica):
camí = camí del tema + ‘/’ + Filename
lable = id
imatges.append(cv2.imread(path, 0))
lables.append(Int(etiqueta))
id += 1
(im_width, im_height) = (112, 92)
# Crear una matriu Numpy de les dos llistes anteriors
(Imatges, Etiquetes) = [numpy.array(Lis) per a lis en [Imatges, Etiquetes]]
# OpenCV entrena un model a partir de les imatges
model = cv2.createFisherFaceRecognizer()
model.train(Imatges, Etiquetes)
# Part 2: Utilitzar fisherRecognizer en funcionament la camara
haar_cascade = cv2. CascadeClassifier(fn_haar)
webcam = cv2. VideoCapture(0)
while True:
(rval, frame) = webcam.read()
frame = cv2.flip(frame,1,0)
gray = cv2.cvtColor(frame, cv2. COLOR_BGR2GRAY)
mini = cv2.resize(gray, (gray.shape[1] / size, gray.shape[0] / size))
faces = haar_cascade.detectMultiScale(mini)
for i in range(len(faces)):
face_i = cares[i]
(x, y, w, h) = [v * Mida per a V en face_i]
cara = gris[y:y + h, x:x + w]
face_resize = cv2.resize(cara, (im_width, im_height))
# Intentat reconèixer la cara
prediction = model.predict(face_resize)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 3)
# Escrivint el nom de la cara reconeguda
# [1]
if prediction[1]>500:
cv2.putText(frame,
'% s – %.0f’ % (Noms[prediction[0]],prediction[1]),
(x-10, y-10), CV2. FONT_HERSHEY_PLAIN,1,(0, 255, 0))
#La variable cara tendra el nom de la persona reconeguda
cara = '%s’ % (Noms[prediction[0]])
#En cas que la cara sigui d' Hector
if cara == "HECTOR":
os.system("/home/pi/hector.sh")
#En cas que la cara sigui de Seila
elif cara == "SEILA":
os.system("/home/pi/seila.sh")
#Si la cara és desconeguda, posar desconegut
else:
cv2.putText(frame,
'Desconegut',
(x-10, y-10), CV2. FONT_HERSHEY_PLAIN,1,(0, 255, 0))
#No hi ha ningú
s.system("/home/pi/nadie.sh")
cv2.imshow('OpenCV', frame)
clau = cv2.waitKey(10)
si clau == 27:
trencar
[/sourcecode]