使用欧氏距离进行人脸识别

问题描述 投票:0回答:2

我有一个用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()
python opencv raspberry-pi raspbian
2个回答
0
投票

如果要比较数据集中的人脸与视频中出现的人脸之间的欧氏距离,您必须首先从视频中提取各个帧,检测各个帧中的人脸,然后将人脸图像与视频中的图像进行比较数据集。

使用Opencv可以轻松完成。


0
投票

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")

你可以试试这个。

© www.soinside.com 2019 - 2024. All rights reserved.