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/wp-content/uploads/2017/12/marlon-brando-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.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.