OpenCV , Python , Rozpoznawanie osoby na podstawie twarzy

0

Cześć , potrzebuję pomocy w projekcie który robię na zaliczenie na 4 roku polibudy. Tematem tego projektu jest "rozpoznawanie użytkownika na podstawie twarzy" , mam stworzyć skrypt w Pythonie OpenCV ,który będzie wykrywał twarz i porównywał ją z wzorcem który już jest zapisany na komputerze i przetworzony przez algorytmy uczące się i tworzące plik YML. Moim problemem jest funkcja "*****.predict(roi_gray)" która zwraca dwa parametry jednym jest "pewność" rozpoznania użytkownika a drugim imię przy każdorazowym rozpoznaniu użytkownika. To co chciałbym osiągnąć i nie wiem jak to wyświetlanie pewności i imienia dla użytkowników którzy są rozpoznani mniej.
Obecny wynik pracy programu

Teraz jest tak: Rafał 87.5555%

A chciałbym tak :

Rafał 87,555%
Piotr 20.03%
Radek 10.04%

Jakby ktoś był tak uprzejmy i bez zbędnego mędrkowania podrzucił mi jakiś totorial albo nazwę konkretnej funkcji to byłbym wdzięczny. Jeśli zły temat to niech moderator Najpierw coś podpowie a potem wrzuci do odpowiedniego działu Pozdro :)

PS: inspirowałem się filmikami Youtub tego gościa

fragment kodu:

id_, conf = recognizer.predict(roi_gray)
        #print(conf)
        if conf>= 50:# and conf <=85:
            print (id_)
            print (labels[id_])
            font = cv2.FONT_HERSHEY_SIMPLEX
            name = labels[id_]
            stroke = 2
            color= (255 , 255 , 255)
            cv2.putText(frame, name+str(conf) ,(x+20,y+20), font , 1, stroke)#, cv2.LINE_AA)
2

Z Twojego "fragmentu kodu" nic nie wynika, nie widzimy, co jest zwracane. Jak to jest z jakiejś sieci neuronowej, to niech zwraca, to co sieć daje na wyjściu, to może być liczba od 1 do 100, na przykład, którą Zamienisz na procenty.

0

Kod trenera klasyfikatora

import cv2
import os
import nympy as np
from PIL import Image

face_cascade = cv2.CascadeClassifier('cascades/data/haarcascade_frontal_face_alt2.xml')
recognizer = cv2.face.LBPHFRecognizer_create()

BASE_DIR = os.path.dirname(os.path.abspath(__file__))

image_dir = os.path.join(os.path.abspath("images"))# folder musi byc w tym samym folderze co program **.py 

current_id = 0 
label_ids = {}
y_labels = []
x_trin = []

for root, dirs , files in os.path.walk(image_dir):
    for file in files:
        if file.endswitch("png") or file.endswitch("jpg"):
            path = os.path.join(root , file)
            label = os.path.basename(os.path.dirname(path)).replace(" ", "-" ).lower()
            print(label ,path)
            if not label in label_ids:
                pass
            else:
                label_ids[label] = curren_id
                current_id +=1

            id_ = label_ids[label]
            #x_label.append(label) # jakis numer
            #y_label.append(path) # NUMPy array
            pil_image = Image.open(path).convert("L") #grayscale
            size = (300, 300)
            final_image = pil_image.resize(size , Image.ANTIALIAS)
            image_array = np.array(pil_image , "uint8")
            #print(image_array) #konwersja pixeli na tablice liczb      
            faces=face_cascade.detectMultiScale(gray,scaleFactor=1.5,minNeighbors=5)                
            for x,y,w,h in faces:
                roi = image_array[y+50:y+h+50 , x+50:x+w+50]
                x_train.append(roi)
                y_labels.append(id_)
#print (y_labels)
print (x_train)

with open("label.pickle", "wb") as f:
    pickle.dump(label_ids , f)

recognizer.train(x_train, np.array(y_labels))
recognizer.save("trainner.yml")

Kod programu

import numpy as np
import cv2
import pickle

face_cascade = cv2.CascadeClassifier('/home/michal/Pulpit/Praca_inzynierska/Haar_cascades/haarcascade_frontalface_alt2.xml') #implementacja
eye_cascade = cv2.CascadeClassifier('/home/michal/Pulpit/Praca_inzynierska/Haar_cascades/eye.xml') 
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read("trainner.yml")

labels = {"faces_name": 1}
with open("labels.pickle", 'rb') as f:
    og_labels = pickle.load(f)
    labels = {v:k for k,v in og_labels.items()}
cap = cv2.VideoCapture(0)

if (cap.isOpened==False):
    print "blad otwarcia pliku"

while (cap.isOpened):
    ret ,  frame = cap.read()
    gray = cv2.cvtColor(frame , cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(gray , scaleFactor = 1.5 , minNeighbors = 5  )
    for (x ,y ,w ,h ) in faces:
        #print(x ,y ,w , h) 
        roi_gray = gray[y:y+h , x:x+w ] #(ycord_start , ycord_end)
        roi_color = frame[y:y+h , x:x+w ]
        #rozpoznawanie twarzy za pomoca deep learning
        id_, conf = recognizer.predict(roi_gray)
        #print(conf)
        if conf>= 50:# and conf <=85:
            print (id_)
            print (labels[id_])
            font = cv2.FONT_HERSHEY_SIMPLEX
            name = labels[id_]
            stroke = 2
            color= (255 , 255 , 255)
            cv2.putText(frame, name+str(conf) ,(x+20,y+20), font , 1, stroke)#, cv2.LINE_AA)
        img_item = "obrazek.jpg"
        cv2.imwrite(img_item , roi_color )

#rysowanie ramki na wykrytej twarzy
        color = (255 , 0 , 0)
        stroke = 2
        end_cord_x = x + w
        end_cord_y = y + h
        cv2.rectangle(frame , (x,y) , (end_cord_x , end_cord_x) ,stroke)
        #eyes = eye_cascade.detectMultiScale(roi_gray)
        #for (ex ,ey ,ew ,eh ) in eyes:
        #   cv2.rectangle(frame , (ex,ey) , (ex+ew,ey+eh) ,(0,255,0),2)
    cv2.imshow('frame' , frame)
    if cv2.waitKey(1) == 0xFF & ord('q'):
        break

cap.release()
cv2.destroyAllWindows()
1

wyniki predykcji dla każdej buźki możesz wrzucać do listy (zmienna results)

while (cap.isOpened):
    results = []
    ...
    for (x ,y ,w ,h ) in faces:
        ...
        id_, conf = recognizer.predict(roi_gray)
        ...
        results.append((id_, conf))
        ...
    print(results)
    cv2.imshow('frame' , frame)
0

https://i1.wp.com/sefiks.com/[...]o-facial-expression.png?ssl=1

Chciałbym żeby algorytm patrząc na jedną osobę zwracał kilka danych kto to może być tak jak w obrazku z emocjami.
Nie chcę bawić się w klasyczne sieci neuronowe bo potrzeba baaardzo dużo danych i uczy sie je kilka godzin.

1

Rozpoznawanie twoarzy najłatwiej zrobić na zasadzie Template Matchingu.
Poniżej masz przykład ale troche z inną sytuacją.
Do jednej osoby potrzebujesz zdjecie twarzy przy profilu pod kątem lewo prawo 60 75 90 105 120. Wtedy działa lepiej.
Powodzenia.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0