What type of result predict function of fisherface recognizer returns

asked 2016-10-24 03:20:52 -0500

irum gravatar image

updated 2016-10-24 04:29:31 -0500

i am doing face recognition in python using openCV and fisherface algorithm. the predict function prediction = model.predict(image) gives results like this distance : (2, 483.88206400085585) i do not know what actually is this distance': (2, 483.88206400085585). In this result483.8806400085585 is the distance but i do not have any idea about the 2this value changes between 1 to 4. that is my code:

# facerec.py
import cv2, sys, numpy, os
import json
size = 3
fn_dir2 = 'unknown'
fn_haar = 'haarcascade_frontalface_default.xml'
fn_dir = 'att_faces'
path2='/home/irum/Desktop/Face-Recognition/thakarrecog/unknown/UNKNOWNS'
path='/home/irum/Desktop/Face-Recognition/thakarrecog/att_faces'
# Part 1: Create fisherRecognizer
print('Training...')

# Create a list of images and a list of corresponding names
(images, lables, names, id) = ([], [], {}, 0)


for (subdirs, dirs, files) in os.walk(fn_dir):
    for subdir in dirs:
        names[id] = subdir 
        subjectpath = os.path.join(fn_dir, subdir) 
        for filename in os.listdir(subjectpath):

            path = subjectpath + '/' + filename
            lable = id
            images.append(cv2.imread(path, 0))
            lables.append(int(lable))
        id += 1



(im_width, im_height) = (112, 92)

# Create a Numpy array from the two lists above
(images, lables) = [numpy.array(lis) for lis in [images, lables]]

# OpenCV trains a model from the images

model = cv2.createFisherFaceRecognizer()
model.train(images, lables)

# Part 2: Use fisherRecognizer on camera stream
haar_cascade = cv2.CascadeClassifier(fn_haar)
# Capturing camera feed
webcam = cv2.VideoCapture(0)
webcam.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 1920)
webcam.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, 1080)

while True:
    # Reading Frames from live stream
    (rval, frame) = webcam.read()
    frame=cv2.flip(frame,1,0)
    #Convert frame into gray
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    #gray = cv2.GaussianBlur(gray, (21, 21), 0)
    # Resize the gary 
    mini = cv2.resize(gray, (gray.shape[1] / size, gray.shape[0] / size))
    # Detecting the face 
    faces = haar_cascade.detectMultiScale(mini,1.1, 5)
    for i in range(len(faces)):
        face_i = faces[i]
        (x, y, w, h) = [v * size for v in face_i]
        # Croping face
        face = gray[y:y + h, x:x + w]
        face_resize = cv2.resize(face, (im_width, im_height))
        # Eualize Histogram
        eq = cv2.equalizeHist(face_resize)

        # Try to recognize the face

        prediction  = model.predict(eq)
        print "Recognition Prediction" ,prediction
        # Draw rectangle around the face
        cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 3)

        # Write the name of recognized face

          result = {
                'face': {

                 'distance': prediction,
                 'coords': {
                   'x': str(faces[0][0]),
                   'y': str(faces[0][1]),
                   'width': str(faces[0][2]),
                   'height': str(faces[0][3])
                    }
                }
              }
        print "1 Result of Over all Prediction" ,result


        if prediction[0]>0 and prediction[0]<4 and prediction[1]<=500:

         result = {
            'face': {

             'distance': prediction[1],
             'coords': {
               'x': str(faces[0][0]),
               'y': str(faces[0][1]),
               'width': str(faces[0][2]),
               'height': str(faces[0][3])
                }
            }
          }

         dist = result['face']['distance']
         print "Known Face DISTANCE" , dist

         cv2.putText(frame,
                 '%s - %.0f' % (names[prediction[0]],prediction[1]),
                 (x-10, y-10), cv2.FONT_HERSHEY_DUPLEX,1,(255, 255, 0))
         break

        else:
        #if prediction[0]<=0 and prediction[0]>=4 and prediction[1]>600:
         print "for prediction more than 600"
         print "prediction", prediction 
         result = {
            'face': {

             'distance': prediction[1],
             'coords': {
               'x': str ...
(more)
edit retag flag offensive close merge delete

Comments

1

this does not look, like opencv's output at all (what are you using there, exactly ?)

(also, please honour a great man, and correct your spelling error)

berak gravatar imageberak ( 2016-10-24 03:27:40 -0500 )edit
1

i am using openCV to detect faces and then i start recognizing them using fisherface recognizer. and i didn't post my code above i posted the result of the FaceRecognizer.predict function.

irum gravatar imageirum ( 2016-10-24 03:34:10 -0500 )edit
1

again if you're using the python wrappers, it will output an (id, distance) tuple, not json. something is fishy here

berak gravatar imageberak ( 2016-10-24 03:38:11 -0500 )edit

ok can you tell me what actually is this id ? its value changes from 1 to 4 for some faces.

irum gravatar imageirum ( 2016-10-24 04:18:56 -0500 )edit
2

it is the person-id you fed in during the training.

(but how can we know without seeing your code ?)

berak gravatar imageberak ( 2016-10-24 04:24:46 -0500 )edit
1

i have attached the code so you can take a look.

irum gravatar imageirum ( 2016-10-24 04:30:32 -0500 )edit

ok now i get it.... secondly can you tell me how much confidence level should i take to tell confidently that the person is recognized correctly.

irum gravatar imageirum ( 2016-10-24 04:34:27 -0500 )edit
2

it depends on your data, you have to measure it.

for a threshold value, you'd want something larger than your average true-positive distance, and smaller than the average true negative one.

berak gravatar imageberak ( 2016-10-24 04:39:37 -0500 )edit

normally true positive is less than 500 and true negative is more than 700. between 500 and 700 sometimes it recognizes accurately but some times it confuses some faces with other faces. that is why i am not sure about the threshold value.

irum gravatar imageirum ( 2016-10-24 04:49:57 -0500 )edit
2

your numbers make sense, imho, but there's not much, you can do about it. (in the prediction phase)

in the end, you need to improve the training, to get a better accuracy (lighting/pose compensation, more or better images)

last, the weak part of the algorithm there is the linear-1-nearest-neighbour search used to classify the projected features. if you use something else there, like an SVM,ANN or such, you'll get a much better prediction (though it won't have a "distance" any more, and thresholding is not possible then)

berak gravatar imageberak ( 2016-10-24 04:57:12 -0500 )edit