Ошибка получения эмбеддингов из ROI с использованием Deepface Deepface.represent

Вопрос или проблема

У меня проблема с Deepface, который не может получить эмбеддинги из обрезанного ROI, определенного Retinaface.

Я пытаюсь изучить распознавание объектов с помощью моего набора данных (изображений) нескольких знаменитостей для начала и, возможно, думаю использовать это для своей личной фотоколлекции. Я попробовал метод каскадов Хаара для обнаружения лиц и LBPHFaceRecognize из OpenCV для распознавания лиц, что сработало хорошо. Затем я захотел попробовать Retinaface для обнаружения лиц и получения ROI. ROI сохраняется в списке, и я использую Deepface для получения эмбеддингов из выбранного ROI и сохранения в другом списке. Я пытаюсь сохранить эмбеддинги в списке, но продолжаю получать
raise ValueError(
ValueError: Лицо не было обнаружено в numpy массиве. Пожалуйста, убедитесь, что изображение является фотографией лица или подумайте о том, чтобы установить параметр enforce_detection в False.

Хотя на всех изображениях есть лицо, которое явно обнаруживается. Вот мой код для справки:

import os
import cv2 as cv
from retinaface import RetinaFace
from deepface import DeepFace
import numpy as np
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

artist =  ['50cent']   # type: ignore #MJ the GOAT!! , 'Kanye', 'Eminem', 'MichaelJackson'
ROOT_DIR = 'asset/Face_Recon_Dataset'     #Путь к набору данных изображений
faces_roi =[]
labels = []
embeddings = []
# теперь нарисуем прямоугольник на координатах лица
# Фактический диапазон лица имеет:
# x1, y1) = (28, 51)  # верхний левый угол
# (x2, y2) = (61, 98)  # нижний правый угол
""" Это определяет прямоугольную ограничивающую рамку вокруг обнаруженного лица.
- x1 (28): левая граница лица
- y1 (51): верхняя граница лица
- x2 (61): правая граница лица
- y2 (98): нижняя граница лица """

def get_roi():
    for artist_name in artist:
        # получение индекса имени художника
        label = artist.index(artist_name)
        image_folder = os.path.join(ROOT_DIR, artist_name)    # получение фактической папки, в которой находятся изображения
        for artist_images in os.listdir(image_folder):       # перечисление всех изображений внутри этого каталога
            image = os.path.join(image_folder, artist_images)
            resp = RetinaFace.detect_faces(image)
            # убедимся, что лицо существует
            if isinstance(resp, dict):
                img = cv.imread(image)
                for face_id, face_data in resp.items():
                    # print(face_id)
                    # print("x1: ", face_data['facial_area'][0])
                    # print("y1: ", face_data['facial_area'][1])
                    # print("x2: ", face_data['facial_area'][2])
                    # print("y2: ", face_data['facial_area'][3], "\n")
                    # Чтение изображения
                    
                    # обнаружение лиц
                    x1 = face_data['facial_area'][0]
                    y1 = face_data['facial_area'][1]
                    x2 = face_data['facial_area'][2]
                    y2 = face_data['facial_area'][3]
                        
                    # Рисование ограничивающей рамки для лица 
                    # faces_rect = cv.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2)
                    face_roi = img[y1:y2, x1:x2]

                    # маркировка обрезанных лиц ROI с его именем
                    faces_roi.append(face_roi)

                    labels.append(label)
    print(len(faces_roi))
    print(len(labels))
    print("Изображения метят и индексируются")
    print("Инициализация процесса получения эмбеддингов.....")
    get_embeddings()

def get_embeddings():
    """ Используем deepface для извлечения эмбеддингов из каждого лицевого ROI """
    print("Начало получения эмбеддингов: 🚀🚀 ")
    for roi in faces_roi:
        face_roi_resized = cv.resize(roi, (160, 160))  # Изменение размера лицевого ROI до 160x160 пикселей
        embedding = DeepFace.represent(face_roi_resized, model_name="Facenet")
        print(embedding)
        embeddings.append(embedding)
    print("Векторы сохранены в списке..")


get_roi()

# Время тестировать и обучать эту модель с использованием SVM классификатора
# маркировка эмбеддингов и индексирование в массив numpy
X = np.array(embeddings)  # признаковая часть
y = np.array(labels)      # метка

# Разделите данные на обучающие и тестовые наборы
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Обучение классификатора SVM
svm_model = SVC(kernel="linear")  # Линейное ядро - хороший стандарт для эмбеддингов
svm_model.fit(X_train, y_train)

# Оценка модели
y_pred = svm_model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f"Точность модели SVM: {accuracy * 100:.2f}%")

Может ли кто-нибудь помочь мне понять, почему эта ошибка так настойчива, даже если существует обрезанный ROI и какой лучший способ справиться с этой ошибкой??

Ответ или решение

Доброго времени суток!

Ваш вопрос касается ошибки, возникающей при использовании библиотеки DeepFace для извлечения эмбеддингов из области интереса (ROI), выявленных с помощью RetinaFace. Ошибка, с которой вы столкнулись, «ValueError: Face could not be detected in numpy array. Please confirm that the picture is a face photo or consider to set enforce_detection param to False» говорит о том, что библиотека DeepFace не может обнаружить лицо на переданном изображении.

Вот несколько шагов, которые могут помочь вам решить эту проблему:

1. Проверка формата изображения

Убедитесь, что ваша ROI (область интереса) действительно содержит изображение лица в правильном формате. Когда вы создаете face_roi, используйте:

if face_roi.size == 0:
    print(f"Empty ROI for {artist_images}.")
    continue

Это поможет вам убедиться, что ROI не пустой.

2. Проверка размеров и цветового формата

DeepFace ожидает, что изображение будет в формате RGB и с размерами 160×160 пикселей. Измените код получения эмбеддингов следующим образом:

face_roi_resized = cv.cvtColor(cv.resize(roi, (160, 160)), cv.COLOR_BGR2RGB)

Это гарантирует, что изображение будет правильно отформатировано.

3. Параметр enforce_detection

Если вы уверены, что ваше изображение содержит лицо, но проблема не исчезает, вы можете установить параметр enforce_detection в False. Этот параметр предотвратит проверку наличия лица перед извлечением эмбеддингов. Измените строку, где вы вызываете DeepFace.represent:

embedding = DeepFace.represent(face_roi_resized, model_name="Facenet", enforce_detection=False)

4. Логирование

Чтобы лучше понять, что происходит, вы можете добавить больше логов в ваш код, особенно после того, как вы получили ROI:

print(f"Processing {artist_images}, ROI shape: {face_roi.shape}.")

Это поможет вам быстро определить, какие изображения обрабатываются и есть ли на них лица.

5. Проверьте RetinaFace

Иногда RetinaFace может не обнаруживать лицо в входном изображении. Убедитесь, что вы обрабатываете все возможные случаи. Если вы используете несколько изображений, возможно, стоит добавить обработку для случаев, когда лицо не будет найдено.

Заключение

Надеюсь, эти шаги помогут вам устранить ошибку при извлечении эмбеддингов с использованием DeepFace. Проверяйте корректность ROI, убедитесь, что изображения имеют правильный формат, и используйте параметры, позволяющие обойти проверку. Если у вас возникнут дальнейшие вопросы, не стесняйтесь спрашивать!

Удачи вам в вашем проекте по распознаванию лиц!

Оцените материал
Добавить комментарий

Капча загружается...