Python качество набора данных face_recognition - PullRequest
1 голос
/ 31 января 2020

Я создаю набор данных с несколькими изображениями для каждого человека для пакета python face_recognition . Это добавит классификатор поверх модели bultin. Смотрите также этот пример: face_recognition_knn.py . вот мой код:

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


# grab the paths to the input images in our dataset
print("[INFO] quantifying faces...")
imagePaths = list(paths.list_images('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(f"[INFO] processing image {i+1}/{len(imagePaths)} -> {imagePath}")
    name = imagePath.split(os.path.sep)[-2]

    # load the input image and convert it from BGR (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='hog') #can be cnn

    # 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('encodings.pickle', "wb")
f.write(pickle.dumps(data))
f.close()

Затем я пытаюсь идентифицировать этих людей с помощью этого кода:

import face_recognition
import pickle
import cv2
import numpy as np
import requests
from datetime import datetime

# load the known faces and embeddings
print("[INFO] loading encodings...")
data = pickle.loads(open("encodings.pickle", "rb").read())

def processa_imagem(url):
    # load the input image and convert it from BGR to RGB and returns file with cofidence
    image = cv2.imread(url)
    if image is None:
        print(f'Image not found: {imagem}')
    #image = np.array(image, dtype=np.uint8)
    rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

    # detect the (x, y)-coordinates of the bounding boxes corresponding
    # to each face in the input image, then compute the facial embeddings
    # for each face
    print("[INFO] recognizing faces...")
    boxes = face_recognition.face_locations(rgb,
        model='hog')
    encodings = face_recognition.face_encodings(rgb, boxes)

    # initialize the list of names for each face detected
    names = []

    # loop over the facial embeddings
    for encoding in encodings:
        # attempt to match each face in the input image to our known
        # encodings
        ##  ATTENTION! the ideal is face_recognition.api.batch_face_locations but i dont have a GPU 
        matches = face_recognition.face_distance(data["encodings"],
            encoding)
        name = "unkown"

        # check to see if we have found a match
        if max(matches) > 0.7:
            # 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)


    # 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(image, (left, top), (right, bottom), (255, 0, 0), 2)
        y = top - 15 if top - 15 > 15 else top + 15
        cv2.putText(image, name, (left, y), cv2.FONT_HERSHEY_SIMPLEX,
            0.75, (255, 0, 0), 2)
    now = datetime.now()
    current_time = now.strftime("%H%M%S%f")

    #file_path = f'static/face-{current_time}.jpg'
    file_path = f'face-{current_time}.jpg'

    cv2.imwrite(file_path,image)

    return (file_path, ', '.join(names))

В свой набор данных я добавил, в среднем, около 10 фотографий каждого человека. Скрипт использует face_recognition.face_distance, и он хорошо работает для распознавания кого-то в наборе данных.

Проблема в том, что, когда я использую это с кем-то, что OUT. Для этих людей иногда я все еще получаю примерно 0,90 достоверных ложноположительных результатов.

Некоторые изображения в наборе данных имеют низкое качество. Может в этом причина? Должен ли я изменить свой подход, используя более подробные фотографии (2 или 3) и, возможно, кодировать их с помощью jitters ?

Спасибо за любой вклад!

...