How to make unrecognized faces in opencv2 be labeled "unknown"?

1.4k Views Asked by At

I am trying to run some python 2.7 code with opencv2. Currently if a subject enters the frame the code labels them as the one it looks like most in its photo database. Instead of this I would like it to label untrained faces as "unknown" this is my code so far:

import cv2
import numpy as np

faceDetect=cv2.CascadeClassifier('haarcascade_frontalface_default.xml');
cam=cv2.VideoCapture(0);
rec=cv2.createLBPHFaceRecognizer();
rec.load("recognizer\\trainingData.yml")
id=0
font=cv2.cv.InitFont(cv2.cv.CV_FONT_HERSHEY_SIMPLEX,1,1,0,0)
#font=cv2.cv.InitFont(cv2.cv.CV_FONT_HERSHEY_COMPLEX_SMALL,3,1,0,1)
while (True):
   ret, img=cam.read();
   gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
   faces=faceDetect.detectMultiScale(gray,1.3,5);
   for (x,y,w,h) in faces:
        #cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,255),2)
        id,conf=rec.predict(gray[y:y+h, x:x+w])
        if(id==1):
            id="Admin"
            cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,255),2)
        elif(id==2):
            id="Sonja"
            cv2.rectangle(img,(x,y),(x+w,y+h),(255,255,255),2)
            cv2.rectangle(img,(x,y),(x+w,y+h),(255,255,255),2)
        cv2.cv.PutText(cv2.cv.fromarray(img),str(id),(x,y+h),font,(255,255,255));
    cv2.imshow("Image",img);
    if(cv2.waitKey(1)==ord('q')):
        break;
cam.release()
cv2.destroyAllWindows()

And the trainer is run through this code:

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

recognizer=cv2.createLBPHFaceRecognizer();
path='dataSet'

def getImagesWithID(path):
   imagePaths=[os.path.join(path,f) for f in os.listdir(path)]
   faces=[]
   IDs=[]
   for imagePath in imagePaths:
        faceImg=Image.open(imagePath).convert('L');
        faceNp=np.array(faceImg,'uint8')
        ID=int(os.path.split(imagePath)[-1].split('.')[1])
        faces.append(faceNp)
        print ID
        IDs.append(ID)
        cv2.imshow("training",faceNp)
        cv2.waitKey(10)
    return np.array(IDs), faces

Ids, faces= getImagesWithID(path)
recognizer.train(faces, Ids)
recognizer.save('recognizer/trainingData.yml')
cv2.destroyAllWindows()
4

There are 4 best solutions below

8
On

I assume that your rec.predict method returns the id of the recognized faces. In which case you can add an 'else' condition in the for (x,y,w,h) in faces: loop for the faces that don't have an id, like so:

        if(id==1):
            id="Admin"
            cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,255),2)
            cv2.putText(img,"Admin",x+h/2,y+w+40),cv2.FONT_HERSHEY_SIMPLEX,0.6,(0,255,255),2)
        elif(id==2):
            id="Sonja"
            #cv2.rectangle(img,(x,y),(x+w,y+h),(255,255,255),2)
            cv2.rectangle(img,(x,y),(x+w,y+h),(255,255,255),2)
            cv2.putText(img,"Sonja",x+h/2,y+w+40),cv2.FONT_HERSHEY_SIMPLEX,0.6,(255,255,255),2)
        else:
            cv2.rectangle(img,(x,y),(x+w,y+h),(0,0,255),2)#Red
            cv2.putText(img,"Unknown",(x+h/2,y+w+40),cv2.FONT_HERSHEY_SIMPLEX,0.6,(0,0,255),2)

Also, I've implemented the putText method differently than the one you've shown.

2
On

If you print the value of conf you can see that the value will be less than 70 if the face is in the dataset you made otherwise the value of conf will be more than 70. The value 70 is set by me if you want the system be more accurate check the value of conf and give any other value as your wish.

1
On
import cv2
import numpy as np
from time import sleep


faceDetect=cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
cam=cv2.VideoCapture(0)
rec=cv2.createLBPHFaceRecognizer()
rec.load("recognizer/trainingData.yml")
id=0
font=cv2.cv.InitFont(cv2.cv.CV_FONT_HERSHEY_COMPLEX_SMALL,1,1,0,1)
while True:
    ret,img=cam.read();
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    faces=faceDetect.detectMultiScale(gray, 1.3, 5)
    for(x,y,w,h) in faces:
        cv2.rectangle(img, (x,y), (x+w,y+h), (255, 0, 0), 2)
        id,conf=rec.predict(gray[y:y+h, x:x+w])
        if(conf<70):
            if(id==1):
                id="Admin"
            if(id==2):
                id="Sonja"
        else:
            id="unknown"

        cv2.cv.PutText(cv2.cv.fromarray(img), str(id), (x,y+h), font,255)
        print ('ok')
    cv2.imshow("Face",img)
    if (cv2.waitKey(1) & 0xFF==ord('q')):
        break
cam.release()
cv2.destroyAllWindows()
0
On
if conf<70:
        if id !=0 & id !=1:
            cv2.putText(img,"unknown",(x,y),cv2.FONT_HERSHEY_SIMPLEX,1,(0,255,0),2,cv2.LINE_AA)