我有一个用Python做人脸识别的项目。我想将欧几里得距离放入我的代码中,以了解实时视频和我的数据集(图像)之间的距离。
我很困惑,因为它是实时的。例如,许多项目只是解释图像“X”和图像“Y”之间的欧几里得距离。有人可以帮助我了解如何对实时视频执行此操作吗?
这是代码:
import sys
import os
impo rt numpy as np
from face_recognition_system.videocamera import VideoCamera
from face_recognition_system.detectors import FaceDetector
import face_recognition_system.operations as op
import cv2
from cv2 import __version__
def get_images(frame, faces_coord, shape):
if shape == "rectangle":
faces_img = op.cut_face_rectangle(frame, faces_coord)
frame = op.draw_face_rectangle(frame, faces_coord)
elif shape == "ellipse":
faces_img = op.cut_face_ellipse(frame, faces_coord)
frame = op.draw_face_ellipse(frame, faces_coord)
faces_img = op.normalize_intensity(faces_img)
faces_img = op.resize(faces_img)
return (frame, faces_img)
def add_person(people_folder, shape):
person_name = raw_input('What is the name of the new person: ').lower()
folder = people_folder + person_name
if not os.path.exists(folder):
raw_input("I will now take 20 pictures. Press ENTER when ready.")
os.mkdir(folder)
video = VideoCamera()
detector = FaceDetector('face_recognition_system/frontal_face.xml')
counter = 1
timer = 0
cv2.namedWindow('Video Feed', cv2.WINDOW_AUTOSIZE)
cv2.namedWindow('Saved Face', cv2.WINDOW_NORMAL)
while counter < 21:
frame = video.get_frame()
face_coord = detector.detect(frame)
if len(face_coord):
frame, face_img = get_images(frame, face_coord, shape)
# save a face every second, we start from an offset '5' because
# the first frame of the camera gets very high intensity
# readings.
if timer % 100 == 5:
cv2.imwrite(folder + '/' + str(counter) + '.jpg',
face_img[0])
print 'Images Saved:' + str(counter)
counter += 1
cv2.imshow('Saved Face', face_img[0])
cv2.imshow('Video Feed', frame)
cv2.waitKey(50)
timer += 5
else:
print "This name already exists."
sys.exit()
def recognize_people(people_folder, shape):
try:
people = [person for person in os.listdir(people_folder)]
except:
print "Have you added at least one person to the system?"
sys.exit()
print "This are the people in the Recognition System:"
for person in people:
print "-" + person
print 30 * '-'
print " POSSIBLE RECOGNIZERS TO USE"
print 30 * '-'
print "1. EigenFaces"
print "2. FisherFaces"
print "3. LBPHFaces"
print 30 * '-'
choice = check_choice()
detector = FaceDetector('face_recognition_system/frontal_face.xml')
if choice == 1:
recognizer = cv2.face.createEigenFaceRecognizer()
threshold = 4000
elif choice == 2:
recognizer = cv2.face.createFisherFaceRecognizer()
threshold = 300
elif choice == 3:
recognizer = cv2.face.createLBPHFaceRecognizer()
threshold = 105
images = []
labels = []
labels_people = {}
for i, person in enumerate(people):
labels_people[i] = person
for image in os.listdir(people_folder + person):
images.append(cv2.imread(people_folder + person + '/' + image, 0))
labels.append(i)
try:
recognizer.train(images, np.array(labels))
except:
print "\nOpenCV Error: Do you have at least two people in the database?\n"
sys.exit()
video = VideoCamera()
while True:
frame = video.get_frame()
faces_coord = detector.detect(frame, False)
if len(faces_coord):
frame, faces_img = get_images(frame, faces_coord, shape)
for i, face_img in enumerate(faces_img):
if __version__ == "3.1.0":
collector = cv2.face.MinDistancePredictCollector()
recognizer.predict(face_img, collector)
conf = collector.getDist()
pred = collector.getLabel()
else:
pred, conf = recognizer.predict(face_img)
print "Prediction: " + str(pred)
print 'Confidence: ' + str(round(conf))
print 'Threshold: ' + str(threshold)
if conf < threshold:
cv2.putText(frame, labels_people[pred].capitalize(),
(faces_coord[i][0], faces_coord[i][1] - 2),
cv2.FONT_HERSHEY_PLAIN, 1.7, (206, 0, 209), 2,
cv2.LINE_AA)
else:
cv2.putText(frame, "Unknown",
(faces_coord[i][0], faces_coord[i][1]),
cv2.FONT_HERSHEY_PLAIN, 1.7, (206, 0, 209), 2,
cv2.LINE_AA)
cv2.putText(frame, "ESC to exit", (5, frame.shape[0] - 5),
cv2.FONT_HERSHEY_PLAIN, 1.2, (206, 0, 209), 2, cv2.LINE_AA)
cv2.imshow('Video', frame)
if cv2.waitKey(100) & 0xFF == 27:
sys.exit()
def check_choice():
""" Check if choice is good
"""
is_valid = 0
while not is_valid:
try:
choice = int(raw_input('Enter your choice [1-3] : '))
if choice in [1, 2, 3]:
is_valid = 1
else:
print "'%d' is not an option.\n" % choice
except ValueError, error:
print "%s is not an option.\n" % str(error).split(": ")[1]
return choice
if __name__ == '__main__':
print 30 * '-'
print " POSSIBLE ACTIONS"
print 30 * '-'
print "1. Add person to the recognizer system"
print "2. Start recognizer"
print "3. Exit"
print 30 * '-'
CHOICE = check_choice()
PEOPLE_FOLDER = "face_recognition_system/people/"
SHAPE = "ellipse"
if CHOICE == 1:
if not os.path.exists(PEOPLE_FOLDER):
os.makedirs(PEOPLE_FOLDER)
add_person(PEOPLE_FOLDER, SHAPE)
elif CHOICE == 2:
recognize_people(PEOPLE_FOLDER, SHAPE)
elif CHOICE == 3:
sys.exit()
如果要比较数据集中的人脸与视频中出现的人脸之间的欧氏距离,您必须首先从视频中提取各个帧,检测各个帧中的人脸,然后将人脸图像与视频中的图像进行比较数据集。
使用Opencv可以轻松完成。
import streamlit as st
import torch
from facenet_pytorch import InceptionResnetV1, MTCNN
from tqdm import tqdm
from types import MethodType
import cv2
import tempfile
import os
### encoding image
def encode(img):
res = resnet(torch.Tensor(img))
return res
def detect_box(self, img, save_path=None):
# Detect faces
batch_boxes, batch_probs, batch_points = self.detect(img, landmarks=True)
# Select faces
if not self.keep_all:
batch_boxes, batch_probs, batch_points = self.select_boxes(
batch_boxes, batch_probs, batch_points, img, method=self.selection_method
)
# Extract faces
faces = self.extract(img, batch_boxes, save_path)
return batch_boxes, faces
def main():
st.title("Face recognition")
# File uploader
uploaded_file = st.file_uploader("Upload your ID here", type=['jpg', 'jpeg', 'png'])
if uploaded_file:
# Showing count
col1, col2 = st.columns([3, 1])
with col1:
st.write("Card Image")
photo_holder_1 = st.empty()
with col2:
st.write("Passport Image")
photo_holder_2 = st.empty()
file_extension = os.path.splitext(uploaded_file.name)[1].lower()
temp_file_path = None
# Save the uploaded file to a temporary location
with tempfile.NamedTemporaryFile(delete=False, suffix=file_extension) as temp_file:
temp_file.write(uploaded_file.read())
temp_file_path = temp_file.name
### get encoded features for id image
img = cv2.imread(temp_file_path)
# Display the image
resized_image_1 = cv2.resize(img, (500, 300))
photo_holder_1.image(resized_image_1)
cropped = mtcnn(img)
if cropped is not None:
id_embedding = encode(cropped)[0, :]
# File uploader
uploaded_file_2 = st.file_uploader("Upload your Passport photo here", type=['jpg', 'jpeg', 'png'])
if uploaded_file_2:
file_extension = os.path.splitext(uploaded_file_2.name)[1].lower()
temp_file_path = None
# Save the uploaded file to a temporary location
with tempfile.NamedTemporaryFile(delete=False, suffix=file_extension) as temp_file:
temp_file.write(uploaded_file_2.read())
temp_file_path = temp_file.name
# the image that needs to be compared
capt_img = cv2.imread(temp_file_path)
image_color = cv2.cvtColor(capt_img, cv2.COLOR_BGR2RGB)
# Display the image
resized_image_2 = cv2.resize(image_color, (200, 300))
photo_holder_2.image(resized_image_2)
thres = 0.7
batch_boxes, cropped_images = mtcnn.detect_box(capt_img)
if cropped_images is not None:
for box, cropped in zip(batch_boxes, cropped_images):
img_embedding = encode(cropped.unsqueeze(0))
# detect_dict = {}
euclidean_distance = torch.norm(id_embedding - img_embedding, p=2)
if euclidean_distance >= thres:
st.markdown("<p style='font-size:30px; color:red'><b>Score - UN-MATCH</b></p>", unsafe_allow_html=True)
else:
score = euclidean_distance
print ("Score - ",score.item())
# Display Score
st.markdown("<p style='font-size:30px; color:red'><b>Score - MATCH</b></p>", unsafe_allow_html=True)
if __name__ == "__main__":
### load model
resnet = InceptionResnetV1(pretrained='vggface2').eval()
mtcnn = MTCNN(
image_size=224, keep_all=True, thresholds=[0.4, 0.5, 0.5], min_face_size=60
)
mtcnn.detect_box = MethodType(detect_box, mtcnn)
print ("Starting.")
main()
print ("END")
你可以试试这个。