接着系列三,继续开始我们face_recognition项目.
下面介绍本项目其他一些功能。
案例一:让系统确定人脸(是鞠婧祎还是特朗普)
在knowe_people文件夹中创建recognize_faces_in_pictures.py文件并写入以下代码:
import face_recognition
# Load the jpg files into numpy arrays
jujingyi_image = face_recognition.load_image_file("鞠婧祎.jpg")
telangpu_image = face_recognition.load_image_file("特朗普.jpeg")
unknown_image = face_recognition.load_image_file("unknown.jpeg")
# Get the face encodings for each face in each image file
# Since there could be more than one face in each image, it returns a list of encodings.
# But since I know each image only has one face, I only care about the first encoding in each #image, so I grab index 0.
try:
jujingyi_face_encoding = face_recognition.face_encodings(jujingyi_image)[0]
telangpu_face_encoding = face_recognition.face_encodings(telangpu_image)[0]
unknown_face_encoding = face_recognition.face_encodings(unknown_image)[0]
except IndexError:
print("I wasn't able to locate any faces in at least one of the images. Check the image files. Aborting...")
quit()
known_faces = [
jujingyi_face_encoding,
telangpu_face_encoding
]
# results is an array of True/False telling if the unknown face matched anyone in the known_faces array
results = face_recognition.compare_faces(known_faces, unknown_face_encoding)
print("Is the unknown face a picture of jujingyi? {}".format(results[0]))
print("Is the unknown face a picture of telangpu? {}".format(results[1]))
print("Is the unknown face a new person that we've never seen before? {}".format(not True in results))
然后我们把一张在knowe_people文件夹中放入一张以前没有的特朗普照片命名为unknown.jpeg
然后终端切换到knowe_people目录下,输入以下命令,弹出窗口如下:
可见终端可以确定未知图片是特朗普,终端输出如下:Is the unknown face a picture of jujingyi? False
Is the unknown face a picture of telangpu? True
Is the unknown face a new person that we've never seen before? False
案例二:人脸识别之后在原图画上框并标注姓名
在knowe_people文件夹中创建identify_and_draw_boxes_on_faces.py文件并写入以下代码:
import face_recognition
from PIL import Image, ImageDraw
import numpy as np
# This is an example of running face recognition on a single image
# and drawing a box around each person that was identified.
# Load a sample picture and learn how to recognize it.
jujingyi_image = face_recognition.load_image_file("鞠婧祎1.jpeg")
jujingyi_face_encoding = face_recognition.face_encodings(jujingyi_image)[0]
# Load a second sample picture and learn how to recognize it.
obama_image = face_recognition.load_image_file("obama.jpg")
obama_face_encoding = face_recognition.face_encodings(obama_image)[0]
# Create arrays of known face encodings and their names
known_face_encodings = [
jujingyi_face_encoding,
obama_face_encoding
]
known_face_names = [
"鞠婧祎",
"obama"
]
# Load an image with an unknown face
unknown_image = face_recognition.load_image_file("two_people.jpg")
# Find all the faces and face encodings in the unknown image
face_locations = face_recognition.face_locations(unknown_image)
face_encodings = face_recognition.face_encodings(unknown_image, face_locations)
# Convert the image to a PIL-format image so that we can draw on top of it with the Pillow library
# See http://pillow.readthedocs.io/ for more about PIL/Pillow
pil_image = Image.fromarray(unknown_image)
# Create a Pillow ImageDraw Draw instance to draw with
draw = ImageDraw.Draw(pil_image)
# Loop through each face found in the unknown image
for (top, right, bottom, left), face_encoding in zip(face_locations, face_encodings):
# See if the face is a match for the known face(s)
matches = face_recognition.compare_faces(known_face_encodings, face_encoding)
name = "Unknown"
# If a match was found in known_face_encodings, just use the first one.
# if True in matches:
# first_match_index = matches.index(True)
# name = known_face_names[first_match_index]
# Or instead, use the known face with the smallest distance to the new face
face_distances = face_recognition.face_distance(known_face_encodings, face_encoding)
best_match_index = np.argmin(face_distances)
if matches[best_match_index]:
name = known_face_names[best_match_index]
# Draw a box around the face using the Pillow module
draw.rectangle(((left, top), (right, bottom)), outline=(0, 0, 255))
# Draw a label with a name below the face
text_width, text_height = draw.textsize(name)
draw.rectangle(((left, bottom - text_height - 10), (right, bottom)), fill=(0, 0, 255), outline=(0, 0, 255))
draw.text((left + 6, bottom - text_height - 5), name, fill=(255, 255, 255, 255))
# Remove the drawing library from memory as per the Pillow docs
del draw
# Display the resulting image
pil_image.show()
# You can also save a copy of the new image to disk if you want by uncommenting this line
# pil_image.save("image_with_boxes.jpg")
再在knowe_people放入一张未知图片,如图,命名为——two_people.jpg。
然后终端切换到knowe_people目录下,输入以下命令,弹出窗口如下:
由于右边是未知人物,在数据集中没有对应的信息(数据集中只有obama和鞠婧祎信息),输出unknown,修改代码:
import face_recognition
from PIL import Image, ImageDraw
import numpy as np
# This is an example of running face recognition on a single image
# and drawing a box around each person that was identified.
# Load a sample picture and learn how to recognize it.
obama_image = face_recognition.load_image_file("obama.jpg")
obama_face_encoding = face_recognition.face_encodings(obama_image)[0]
# Load a second sample picture and learn how to recognize it.
biden_image = face_recognition.load_image_file("biden.jpg")
biden_face_encoding = face_recognition.face_encodings(biden_image)[0]
# Create arrays of known face encodings and their names
known_face_encodings = [
obama_face_encoding,
biden_face_encoding
]
known_face_names = [
"Barack Obama",
"Joe Biden"
]
# Load an image with an unknown face
unknown_image = face_recognition.load_image_file("two_people.jpg")
# Find all the faces and face encodings in the unknown image
face_locations = face_recognition.face_locations(unknown_image)
face_encodings = face_recognition.face_encodings(unknown_image, face_locations)
# Convert the image to a PIL-format image so that we can draw on top of it with the Pillow library
# See http://pillow.readthedocs.io/ for more about PIL/Pillow
pil_image = Image.fromarray(unknown_image)
# Create a Pillow ImageDraw Draw instance to draw with
draw = ImageDraw.Draw(pil_image)
# Loop through each face found in the unknown image
for (top, right, bottom, left), face_encoding in zip(face_locations, face_encodings):
# See if the face is a match for the known face(s)
matches = face_recognition.compare_faces(known_face_encodings, face_encoding)
name = "Unknown"
# If a match was found in known_face_encodings, just use the first one.
# if True in matches:
# first_match_index = matches.index(True)
# name = known_face_names[first_match_index]
# Or instead, use the known face with the smallest distance to the new face
face_distances = face_recognition.face_distance(known_face_encodings, face_encoding)
best_match_index = np.argmin(face_distances)
if matches[best_match_index]:
name = known_face_names[best_match_index]
# Draw a box around the face using the Pillow module
draw.rectangle(((left, top), (right, bottom)), outline=(0, 0, 255))
# Draw a label with a name below the face
text_width, text_height = draw.textsize(name)
draw.rectangle(((left, bottom - text_height - 10), (right, bottom)), fill=(0, 0, 255), outline=(0, 0, 255))
draw.text((left + 6, bottom - text_height - 5), name, fill=(255, 255, 255, 255))
# Remove the drawing library from memory as per the Pillow docs
del draw
# Display the resulting image
pil_image.show()
# You can also save a copy of the new image to disk if you want by uncommenting this line
# pil_image.save("image_with_boxes.jpg")
然后终端切换到knowe_people目录下,输入以下命令,弹出窗口如下:
由于数据集中有未知人物拜登的信息,故能输出人名。
案例三:在不同精度上比较两张人脸是否是同一个人
通常情况下,我们不一定检查两张脸是否匹配(对或错),而且看看它们有多相似。您可以使用face_distance函数来实现这一点。
该模型的训练方式是,距离为0.6或更小的面孔应该是匹配的。但如果你想更严格一点,你可以找一个较小的距离。例如,使用0.55将更加减少false,
正面匹配有更多假阴性的风险。注意:这与“百分比匹配”并不完全相同。比例不是线性的。但是你可以假设距离较小的图像比距离较大的图像更相似。
首先在known_people文件夹中加入带匹配的照片obama2.jpg,如图。
在knowe_people文件夹中创建face_distance.py文件并写入以下代码:
import face_recognition
# Often instead of just checking if two faces match or not (True or False), it's helpful to see how similar they are.
# You can do that by using the face_distance function.
# The model was trained in a way that faces with a distance of 0.6 or less should be a match. But if you want to
# be more strict, you can look for a smaller face distance. For example, using a 0.55 cutoff would reduce false
# positive matches at the risk of more false negatives.
# Note: This isn't exactly the same as a "percent match". The scale isn't linear. But you can assume that images with a
# smaller distance are more similar to each other than ones with a larger distance.
# Load some images to compare against
known_obama_image = face_recognition.load_image_file("obama.jpg")
known_biden_image = face_recognition.load_image_file("biden.jpg")
# Get the face encodings for the known images
obama_face_encoding = face_recognition.face_encodings(known_obama_image)[0]
biden_face_encoding = face_recognition.face_encodings(known_biden_image)[0]
known_encodings = [
obama_face_encoding,
biden_face_encoding
]
# Load a test image and get encondings for it
image_to_test = face_recognition.load_image_file("obama2.jpg")
image_to_test_encoding = face_recognition.face_encodings(image_to_test)[0]
# See how far apart the test image is from the known faces
face_distances = face_recognition.face_distance(known_encodings, image_to_test_encoding)
for i, face_distance in enumerate(face_distances):
print("The test image has a distance of {:.2} from known image #{}".format(face_distance, i))
print("- With a normal cutoff of 0.6, would the test image match the known image? {}".format(face_distance < 0.6))
print("- With a very strict cutoff of 0.5, would the test image match the known image? {}".format(face_distance < 0.5))
print()
然后终端切换到knowe_people目录下,输入以下命令,弹出窗口如下:
终端输出说明:上述测试图像(obama)与已知图像#0(obama)之间的距离为0.35,也就是说匹配可能性比较高(正常的截断为0.6),测试图像是否与已知图像匹配。在非常严格的0.5截断下,测试图像会与已知图像匹配吗?会
测试图像到已知图像#1(biden)的距离为0.82-正常截断距离为0.6,测试图像是否与已知图像不匹配,在非常严格的0.5截断下,测试图像会与已知图像匹配吗?不会
小结:这次主要展示了本项目三个功能,更多内容见其他系列。
案例一:让系统确定人脸(是鞠婧祎还是特朗普)
案例二:人脸识别之后在原图画上框并标注姓名
案例三:在不同精度上比较两张人脸是否是同一个人