首页 > 解决方案 > opencv python的人脸识别

问题描述

我有一个通过 open cv python 进行人脸识别的代码

import face_recognition as fr
import os
import cv2
import face_recognition
import numpy as np
from time import sleep


def get_encoded_faces():
    """
    looks through the faces folder and encodes all
    the faces

    :return: dict of (name, image encoded)
    """
    encoded = {}

    for dirpath, dnames, fnames in os.walk("./faces"):
        for f in fnames:
            if f.endswith(".jpg") or f.endswith(".png"):
                face = fr.load_image_file("faces/" + f)
                encoding = fr.face_encodings(face)[0]
                encoded[f.split(".")[0]] = encoding

    return encoded


def unknown_image_encoded(img):
    """
    encode a face given the file name
    """
    face = fr.load_image_file("faces/" + img)
    encoding = fr.face_encodings(face)[0]

    return encoding


def classify_face(im):
    """
    will find all of the faces in a given image and label
    them if it knows what they are

    :param im: str of file path
    :return: list of face names
    """
    faces = get_encoded_faces()
    faces_encoded = list(faces.values())
    known_face_names = list(faces.keys())

    img = cv2.imread(im, 1)
    #img = cv2.resize(img, (0, 0), fx=0.5, fy=0.5)
    #img = img[:,:,::-1]

    face_locations = face_recognition.face_locations(img)
    unknown_face_encodings = face_recognition.face_encodings(img, face_locations)

    face_names = []
    for face_encoding in unknown_face_encodings:
        # See if the face is a match for the known face(s)
        matches = face_recognition.compare_faces(faces_encoded, face_encoding)
        name = "Unknown"

        # use the known face with the smallest distance to the new face
        face_distances = face_recognition.face_distance(faces_encoded, face_encoding)
        best_match_index = np.argmin(face_distances)
        if matches[best_match_index]:
            name = known_face_names[best_match_index]

        face_names.append(name)

        for (top, right, bottom, left), name in zip(face_locations, face_names):
            # Draw a box around the face
            cv2.rectangle(img, (left-20, top-20), (right+20, bottom+20), (255, 0, 0), 2)

            # Draw a label with a name below the face
            cv2.rectangle(img, (left-20, bottom -15), (right+20, bottom+20), (255, 0, 0), cv2.FILLED)
            font = cv2.FONT_HERSHEY_DUPLEX
            cv2.putText(img, name, (left -20, bottom + 15), font, 1.0, (255, 255, 255), 2)


    # Display the resulting image
    while True:

        cv2.imshow('Video', img)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            return face_names 


print(classify_face("test-image");

它正在拍摄我们保存以进行测试的图像,但我希望它从相机拍摄图像然后识别它所以这里的任何人都可以告诉我如何更改测试图像,这样它将从相机拍摄测试图像而不是我们保存在数据库中的图像测试 ...........

标签: pythonopencv

解决方案


如果你想从相机检查单帧然后只需使用

cap = cv2.VideoCapture(0)
status, img = cap.read()

代替

img = cv2.imread(im, 1)

如果你想检查流中的面孔,那么你需要把所有的都放在循环中

def classify_face(im):

    faces = get_encoded_faces()
    faces_encoded = list(faces.values())
    known_face_names = list(faces.keys())

    cap = cv2.VideoCapture(0)

    while True:

        status, img = cap.read()

        face_locations = face_recognition.face_locations(img)
        unknown_face_encodings = face_recognition.face_encodings(img, face_locations)

        face_names = []
        for face_encoding in unknown_face_encodings:
            # See if the face is a match for the known face(s)
            matches = face_recognition.compare_faces(faces_encoded, face_encoding)
            name = "Unknown"

            # use the known face with the smallest distance to the new face
            face_distances = face_recognition.face_distance(faces_encoded, face_encoding)
            best_match_index = np.argmin(face_distances)
            if matches[best_match_index]:
                name = known_face_names[best_match_index]

            face_names.append(name)

            for (top, right, bottom, left), name in zip(face_locations, face_names):
                # Draw a box around the face
                cv2.rectangle(img, (left-20, top-20), (right+20, bottom+20), (255, 0, 0), 2)

                # Draw a label with a name below the face
                cv2.rectangle(img, (left-20, bottom -15), (right+20, bottom+20), (255, 0, 0), cv2.FILLED)
                font = cv2.FONT_HERSHEY_DUPLEX
                cv2.putText(img, name, (left -20, bottom + 15), font, 1.0, (255, 255, 255), 2)

        cv2.imshow('Video', img)

        print(face_names)

        if cv2.waitKey(1) & 0xFF == ord('q'):
            return

编辑:用于视频流的完整代码(稍作改动)。这个对我有用。但是,如果之前的功能确实对您有用,那么这个版本可能对您没有帮助 - 功能classify_face与之前的示例几乎相同。

import os
import cv2
import face_recognition as fr
import numpy as np


def get_encoded_faces(folder="./faces"):
    """
    looks through the faces folder and encodes all
    the faces

    :return: dict of (name, image encoded)
    """
    encoded = {}

    for dirpath, dnames, fnames in os.walk(folder):
        for f in fnames:
            if f.lower().endswith(".jpg") or f.lower().endswith(".png"):

                fullpath = os.path.join(dirpath, f)
                face = fr.load_image_file(fullpath)

                # normally face_encodings check if face is on image - and it can get empty result
                height, width = face.shape[:2]
                encoding = fr.face_encodings(face, known_face_locations=[(0, width, height, 0)])
                if len(encoding) > 0:
                    encoding = encoding[0]
                    encoded[f.split(".")[0]] = encoding

    return encoded


def classify_face(im):
    """
    will find all of the faces in a given image and label
    them if it knows what they are

    :param im: str of file path
    :return: list of face names
    """
    faces = get_encoded_faces()
    faces_encoded = list(faces.values())
    known_face_names = list(faces.keys())

    cap = cv2.VideoCapture(0)

    while True:

        status, img = cap.read()
        #print('status:', status)

        face_locations = fr.face_locations(img)
        unknown_face_encodings = fr.face_encodings(img, face_locations)

        face_names = []
        for location, face_encoding in zip(face_locations, unknown_face_encodings): # I moved `zip()` in this place

            # See if the face is a match for the known face(s)
            matches = fr.compare_faces(faces_encoded, face_encoding)
            name = "Unknown"

            # use the known face with the smallest distance to the new face
            face_distances = fr.face_distance(faces_encoded, face_encoding)

            best_match_index = np.argmin(face_distances)
            if matches[best_match_index]:
                name = known_face_names[best_match_index]

            face_names.append(name)

            top, right, bottom, left = location
            # Draw a box around the face

            cv2.rectangle(img, (left-20, top-20), (right+20, bottom+20), (255, 0, 0), 2)

            # Draw a label with a name below the face
            cv2.rectangle(img, (left-20, bottom -15), (right+20, bottom+20), (255, 0, 0), cv2.FILLED)
            font = cv2.FONT_HERSHEY_DUPLEX
            cv2.putText(img, name, (left -20, bottom + 15), font, 1.0, (255, 255, 255), 2)

        print('face_names:', face_names)
        cv2.imshow('Video', img)

        if cv2.waitKey(1) & 0xFF == ord('q'):
            return face_names 

# --- main ---

print(classify_face("test-image"))

cv2.destroyAllWindows()

推荐阅读