What type of result predict function of fisherface recognizer returns
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 2
this 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 ...
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)
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.again if you're using the python wrappers, it will output an (id, distance) tuple, not json. something is fishy here
ok can you tell me what actually is this id ? its value changes from 1 to 4 for some faces.
it is the person-id you fed in during the training.
(but how can we know without seeing your code ?)
i have attached the code so you can take a look.
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.
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.
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.
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)