Detekce, popis a klasifikace obličeje z RGB obrazu¶
Druhá část cvičení se zaměří na detekci obličeje pomocí tradičních metod zpracování obrazu.
Stažení modelů¶
Natrénované modely tradičními způsoby jsou umístěné ve složce models
. Jedná se o modely typu:
Detekce obličeje¶
Prvním úkolem je ve vstupním obrazu detekovat umístění obličeje nebo obličejů. Jednak nám to umožní vyfiltrovat nedůležité části obrazu před dalším zpracováním a typicky tak zpracování urychlit a zpřesnit, ale především nám to pomůže při výskytu více obličejů v jednom obrázku.
Jenže, jak na to? Zkusme si představit jak vypadá typický obličej. Oči a obočí jsou tmavší než tváře, stejně tak jsou tmavší než nos. Jenže modelovat explicitně podobu obličeje je poměrně pracné. Především, když můžeme použít hrubou sílu a nechat si vymodelovat typický obličej ne na úrovni pixelů, ale na úrovni rozdílů intenzit vhodně zvolených oblastí napříč rozlišeními.
K tomu je možné použít například Haarovu funkci všemožně naškálovanou a narotovanou jak je podrobněji popsáno v článku Paula Violy a Michaela Jonese: "Rapid Object Detection using a Boosted Cascade of Simple Features" a klasifikátor, který bude detekovat ty oblasti obrázku, které obsahují předučenou kombinaci rozdílů intenzit podle vybraných funkcí.
Pro učení klasifikátoru je zapotřebí algoritmu dodat velké množství obrázků obličeje (a obrázků, které obličej neobsahují), na kterých proběhne, zjednodušeně řečeno, určení hodnot všech Haarových funkcí a výběr funkcí (a prahů) vhodných pro rozlišení zda obrázek obsahuje nebo neobsahuje obličej. Tím vznikne model, který je při dostatečných schopnostech generalizace možné následně používat pro detekci i neznámých obličejů. Model zde z dat učit nebudeme, použijeme model již natrénovaný pro detekci obličeje dívajícího se přímo do kamery, který je distribuovaný s OpenCV. Pro jistotu jej ale přikládáme přímo do složky s notebookem.
Importy knihoven, konfigurací a modelů¶
import os
import io
import cv2
import numpy as np
import matplotlib.pyplot as plt
import pytesseract
from improutils import *
from collections import OrderedDict
%matplotlib inline
np.set_printoptions(formatter={'float': lambda x: "{0:0.3f}".format(x)})
MAIN_FOLDER = 'models/'
FACE_FRONTAL = MAIN_FOLDER + 'haarcascade_frontalface_default.xml'
EYES_NO_GLASSES = MAIN_FOLDER + 'haarcascade_eye.xml'
EYES_WITH_GLASSES = MAIN_FOLDER + 'haarcascade_eye_tree_eyeglasses.xml'
FACE_FRONTAL_ALT = MAIN_FOLDER + 'lbpcascade_frontalface_improved.xml'
FACE_PROFILE = MAIN_FOLDER + 'lbpcascade_profileface.xml'
Příprava obrázku a detekce¶
1) Nasnímejte obrázky obličejů¶
Využijte jakýkoli známý přístup a nasnímejte obrázky obličeje / obličejů a uložte je do složky data
. Převeďte do odstínů šedi pro detekci Haarovou kaskádou (popř. dalšími modely).
image = load_image('data/face0.jpg') ###
image_gray = to_gray(image) ###
plot_images(image_gray)
2) Vytvořte potřebné detektory¶
Vytvořte objekt / objekty detektorů využívající již předučené modely.
# face_detector = cv2.CascadeClassifier(FACE_FRONTAL) ###
### další modely ...
FACE_FRONTAL_detector = cv2.CascadeClassifier(FACE_FRONTAL)
EYES_NO_GLASSES_detector = cv2.CascadeClassifier(EYES_NO_GLASSES)
EYES_WITH_GLASSES_detector = cv2.CascadeClassifier(EYES_WITH_GLASSES)
FACE_FRONTAL_ALT_detector = cv2.CascadeClassifier(FACE_FRONTAL_ALT)
FACE_PROFILE_detector = cv2.CascadeClassifier(FACE_PROFILE)
3) Detekujte obličeje.¶
Uvedené parametry funkce detectMultiScale()
specifikují úroveň škálování a citlivost filtru. Seznamte se s parametry v dokumentaci.
Vizualizujte nalezené obličeje pomocí obdélníků. Každý obličej jinou barvou.
# Detects faces
faces = FACE_FRONTAL_detector.detectMultiScale(image_gray) # experimentujte s nastavením
###
viz = image.copy()
for face in faces:
cv2.rectangle(viz, (face[0], face[1]), (face[0] + face[2], face[1] + face[3]), (0, 255, 0), 15)
plot_images(viz)
3) Experimentujte s dalšími modely na datech z internetu¶
Vyzkoušejte si následující:
- Limitace detektoru obličejů - srovnání Haar a LBP (natočení hlavy, velikosti obličejů aka rozlišení, ...)
- Detekce obličeje z profilu
- Detekce očí s brýlemi a bez
###
images = [
(load_image('data/face0.jpg')),
(load_image('data/face1.jpg')),
(load_image('data/prof0.jpg')),
(load_image('data/prof1.jpg')),
]
def visualize(detector, images):
out = []
for image in images:
faces = detector.detectMultiScale(image)
viz = image.copy()
for face in faces:
cv2.rectangle(viz, (face[0], face[1]), (face[0] + face[2], face[1] + face[3]), (0, 255, 0), 15)
out.append(viz)
plot_images(*out)
visualize(FACE_FRONTAL_detector, images)
visualize(EYES_NO_GLASSES_detector, images)
visualize(EYES_WITH_GLASSES_detector, images)
visualize(FACE_FRONTAL_ALT_detector, images)
visualize(FACE_PROFILE_detector, images)
Zajímavost na doma - OpenFace¶
Tento přístup má jistě mnohá úskalí. Pokud se dotyčný nedívá přímo do kamery nebo pokud má výrazně nakloněnou hlavu, detekce ani popis nemusí fungovat správně. Poté je potřeba dělat trochu více magie, kterou nechcete psát stále dokola. A proto vznikla knihovna OpenFace: https://cmusatyalab.github.io/openface/
Doporučuji vyzkoušet.