RuntimeWarning in face_recognition

I get an error once when the first face is detected:

/usr/local/lib/python3.6/dist-packages/face_recognition/api.py:222: RuntimeWarning: invalid value encountered in less_equal
return list(face_distance[known_face_encodings, face_encoding_to_check) <= tolerance)

Maybe my encodings.pickle file is not correct.

I use this one:

# USAGE
# When encoding on laptop, desktop, or GPU (slower, more accurate):
# python encode_faces.py --dataset dataset --encodings encodings.pickle --detection-method cnn
# When encoding on Raspberry Pi (faster, more accurate):
# python encode_faces.py --dataset dataset --encodings encodings.pickle --detection-method hog

# import the necessary packages
from imutils import paths
import face_recognition
import argparse
import pickle
import cv2
import os

# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--dataset", required=True,
	help="path to input directory of faces + images")
ap.add_argument("-e", "--encodings", required=True,
	help="path to serialized db of facial encodings")
ap.add_argument("-d", "--detection-method", type=str, default="cnn",
	help="face detection model to use: either `hog` or `cnn`")
args = vars(ap.parse_args())

# grab the paths to the input images in our dataset
print("[INFO] quantifying faces...")
imagePaths = list(paths.list_images(args["dataset"]))

# initialize the list of known encodings and known names
knownEncodings = []
knownNames = []

# loop over the image paths
for (i, imagePath) in enumerate(imagePaths):
	# extract the person name from the image path
	print("[INFO] processing image {}/{}".format(i + 1,
		len(imagePaths)))
	name = imagePath.split(os.path.sep)[-2]

	# load the input image and convert it from RGB (OpenCV ordering)
	# to dlib ordering (RGB)
	image = cv2.imread(imagePath)
	rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

	# detect the (x, y)-coordinates of the bounding boxes
	# corresponding to each face in the input image
	boxes = face_recognition.face_locations(rgb,
		model=args["detection_method"])

	# compute the facial embedding for the face
	encodings = face_recognition.face_encodings(rgb, boxes)

	# loop over the encodings
	for encoding in encodings:
		# add each encoding + name to our set of known names and
		# encodings
		knownEncodings.append(encoding)
		knownNames.append(name)

# dump the facial encodings + names to disk
print("[INFO] serializing encodings...")
data = {"encodings": knownEncodings, "names": knownNames}
f = open(args["encodings"], "wb")
f.write(pickle.dumps(data))
f.close()

My script for face_recognition looks like this:

# import the necessary packages
from imutils.video import VideoStream
from imutils.video import FPS
import face_recognition
import argparse
import imutils
import pickle
import time
import cv2
import requests
from optparse import OptionParser

# load the known faces and embeddings along with OpenCV's Haar
# cascade for face detection
print("[INFO] loading encodings + face detector...")
data = pickle.loads(open("encodings.pickle", "rb").read())
detector = cv2.CascadeClassifier("haarcascade_frontalface_alt2.xml")

# initialize the video stream and allow the camera sensor to warm up
print("[INFO] starting video stream...")
vs = VideoStream(src=0).start()
time.sleep(2.0)

# start the FPS counter
fps = FPS().start()
count = 0
		
# loop over frames from the video file stream
while True:
	# grab the frame from the threaded video stream and resize it
	# to 500px (to speedup processing)
	frame = vs.read()
	frame = imutils.resize(frame, width=800)
	#frame = imutils.rotate(frame, 180)
	# convert the input frame from (1) BGR to grayscale (for face
	# detection) and (2) from BGR to RGB (for face recognition)
	gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
	rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
	
	# detect faces in the grayscale frame
	rects = detector.detectMultiScale(gray, scaleFactor=1.5, 
		minNeighbors=6, minSize=(30, 30),
		flags=cv2.CASCADE_SCALE_IMAGE)
	
	# OpenCV returns bounding box coordinates in (x, y, w, h) order
	# but we need them in (top, right, bottom, left) order, so we
	# need to do a bit of reordering
	boxes = [(y, x + w, y + h, x) for (x, y, w, h) in rects]

	# compute the facial embeddings for each face bounding box
	encodings = face_recognition.face_encodings(rgb, boxes)
	names = []
	
	# loop over the facial embeddings
	for encoding in encodings:
		# attempt to match each face in the input image to our known
		# encodings
		
		matches = face_recognition.compare_faces(data["encodings"],
			encoding)
		name = "Unknown"
		
		# check to see if we have found a match
		if True in matches:
			# find the indexes of all matched faces then initialize a
			# dictionary to count the total number of times each face
			# was matched
			matchedIdxs = [i for (i, b) in enumerate(matches) if b]
			counts = {}

			# loop over the matched indexes and maintain a count for
			# each recognized face face
			for i in matchedIdxs:
				name = data["names"][i]
				counts[name] = counts.get(name, 0) + 1

			# determine the recognized face with the largest number
			# of votes (note: in the event of an unlikely tie Python
			# will select first entry in the dictionary)
			name = max(counts, key=counts.get)
		
		# update the list of names
		names.append(name.capitalize())

	# loop over the recognized faces
	for ((top, right, bottom, left), name) in zip(boxes, names):
		# draw the predicted face name on the image
		cv2.rectangle(frame, (left, top), (right, bottom),
			(0, 255, 0), 2)
		y = top - 15 if top - 15 > 15 else top + 15
		cv2.putText(frame, name, (left, y), cv2.FONT_HERSHEY_SIMPLEX,
			0.75, (0, 255, 0), 2)
		
		print(name)
		
		count += 1
	
	# update the FPS counter
	fps.update()
	
	cv2.imshow('frame',frame)
	if cv2.waitKey(1) & 0xFF == ord('q'):
		cv2.destroyAllWindows()
		break

# stop the timer and display FPS information
fps.stop()
print("[INFO] elasped time: {:.2f}".format(fps.elapsed()))
print("[INFO] approx. FPS: {:.2f}".format(fps.fps()))

# do a bit of cleanup
cv2.destroyAllWindows()
vs.stop()

I use the detection_method hog, because cnn is not working.
After the first image it says “killed” and the scripts ends.

Would you be able to provide the full error so I can see which part of your code is hitting this error?

I think I’ve seen this error before and I think it’s happening when trying to do matching against an image missing a face.

If you print your ‘encoding’ variable as the first part of the for loop on line 55, this should always have a value based on the code you’ve written. So if you run this code without a face in view of the camera it will crash.

I think you are missing logic to skip the face recognition in the event that there is no face. E.g.
instead of

for encodings in encodings:

I would use

if encodings:
     for encodings in encodings:

so that you can handle nulls (images where no face was found) there.

Hi mgreaves,

if there is no face detected, the encondigs array is empty and there are no errors.
When a face is detected, the array has an item and the error occurs.

I printed out data[“encodings”] and when a face is detected, the array looks like:

data = pickle.loads(open("encodings.pickle", "rb").read())
print data["encodings"]
array([nan, nan, nan, ... ])

Sorry for taking so long to get back to you, been really busy these past few days.

I think you may need to regenerate your pickle file if you haven’t since patching your DLIB.

I know in the other thread you were mentioning that you were getting the expected responses after printing out the encodings.

I’m also not sure off the top of my head if you need to do anything to get the info back into a numpy array from a pickle file other than just opening it.

Hey,

no problem, i am glad that you take the time for it.
Brilliant, i recreate my pickle file and thats it.
But, it would be too easy. Now i have the next thing.
The Videostream comes in a decent FPS, but as soon as my face gets detected/recognized, the performance break down to 5 FPS.
When i cover my face, the stream continous with a much higher FPS.

I tried another approach for face recognition using DNN model res10_300x300_ssd_iter_140000.caffemodel.
But neither the performance nor the accuracy are satisfactory.
I trained 3 faces including 140 images, but it seems i need much more images to get a stable recognition.
Currently it swaps between the trained faces when i moved my head slighly.

Overall i must say, i have in comparrison to the hardware a better result on my raspberry pi 3 with openCV. :-(

But i dont give up. So when you all have any suggestions to improve performance and accuracy, maybe by taking another approach. Please let me know.

Glad you got it to work!

I wrote all this out but apparently the forums don’t like emojis and truncated my message.

I would time your code to see where the potential fps loss is coming from.

For improving performance (in terms of fps) I would recommend resizing the image to be even smaller.

For increased accuracy you may want to review the sample code for the matching via webcam. The sample code uses np.linalg to find the best match which may be more performant and accurate than your implementation.

I would also re-assess using the CNN model for matching to see if there is any improvement now that your dlib is working as expected.

Good luck with your coding!

Also on the note of np.linalg: numpy functions will almost always significantly outperform for loops when processing data in arrays.

I would recommend reading up on some of the features that numpy provides to see if there is anything that works better for you. :)

Hello,

after some testing, i found a well working solution with the cnn model.
The training phase was quite tricky because my training script stopped working when the image resolution was to high. It took me some time to find the reason for that. :-)

The framerate is not great, but sufficient for my purpose.

Thanks to everyone for helping me out.

Best regards
Markus

Install face_recognition:
sudo pip3 install face_recognition

Download demo:
git clone --single-branch GitHub - ageitgey/face_recognition: The world's simplest facial recognition api for Python and the command line

run demo:

cd examples
python3 facerec_from_webcam_faster.py

When a face is detected, the array has an item and the error occurs.

/usr/local/lib/python3.6/dist-packages/face_recognition/api.py:222: RuntimeWarning: invalid value encountered in less_equal
return list(face_distance[known_face_encodings, face_encoding_to_check) <= tolerance)

@Flaty…how did you “recreate pickle file”? Thx