Генерация набора данных для распознавания лиц Python-OpenCV

Python OpenCV

существуетпредыдущий постВ статье мы узнали, как установить и настроить OpenCV и Python, а затем написали код для работы с распознаванием лиц. Теперь нам предстоит перейти к следующему шагу, который заключается в разработке программы распознавания лиц, то есть не только обнаружения, но и идентификации человека.

Давай, сделай распознавание лиц

Чтобы запустить программу распознавания лиц, сначала нам нужно обучить распознаватель на предварительно обрезанных и помеченных фотографиях лиц. Например, нашему распознавателю нужно идентифицировать двух человек, один из которых имеет идентификатор 1, а другой — идентификатор 2, поэтому в наборе данных все фотографии человека 1 будут иметь идентификатор 1, и то же самое верно для человека 2. Затем мы используем эти фотографии набора данных, чтобы обучить распознаватель идентифицировать человека 1 из видео.

Делим то, что нам предстоит сделать, на три части:

  1. Создать набор данных
  2. тренироваться
  3. Идентифицировать

В этой статье мы попробуем написать программу для генерации набора данных.

Создать набор данных

Напишем скрипт генерации набора данных.

Сначала откройте нашу среду Python, будь то IDE, такая как Pycharm, или простой Блокнот. Что нужно подготовить заранее, так это поместить его в каталогhaarcascade_frontalface_default.xml, я также использовал этот XML-файл в предыдущей статье, которая поставляется с OpenCV.

Затем используйте cv2 для получения данных камеры и XML-файлов:

import cv2
cam = cv2.VideoCapture(0)
detector=cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

Наш набор данных должен сначала собрать несколько примеров фотографий лиц с камеры, конечно, только одного и того же человека. Затем программа добавит идентификаторы к этим примерам фотографий и сохранит фотографии в папке, назовем эту папку dataSet.

Давайте создадим папку dataSet в том же каталоге, что и скрипт py. Чтобы не путать разные фотографии лиц, нам нужно установить правило именования фотографий.

Например, соглашение об именахUser.[ID].[SampleNumber].jpg. Если это десятая фотография человека 2, мы можем назвать ее какUser.2.10.jpg.

Зачем определять такой формат? Из-за этого при загрузке фотографий для обучения мы можем просто судить о фотографиях лиц пользователей только по именам файлов фотографий.

Затем мы пытаемся использовать более простой метод через ввод оболочки, чтобы получить идентификатор человека и инициализировать переменную калькулятора для хранения количества примеров людей.

Id = raw_input('enter your id: ')
sampleNum = 0

Затем мы добавляем основной цикл, в котором мы будем скармливать 20 примеров из видеопотока и сохранять все примеры в уже созданной папке dataSet.

Вот версия кода, который я написал ранее для распознавания лиц:

while True:
    ret, img = cap.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = detector.detectMultiScale(gray, 1.3, 5)
    for (x, y, w, h) in faces:
        cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)

    cv2.imshow('frame', img)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

Теперь мы преобразуем его в генератор набора данных:

while True:
    ret, img = cap.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = detector.detectMultiScale(gray, 1.3, 5)
    for (x, y, w, h) in faces:
        cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)

        # 增加例子数
        sampleNum = sampleNum + 1
        # 把照片保存到数据集文件夹
        cv2.imwrite("dataSet/user." + str(Id) + '.' + str(sampleNum) + ".jpg", gray[y:y + h, x:x + w])

        cv2.imshow('frame', img)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

Мы добавили две строки кода, чтобы подсчитать количество примеров и сохранить фотографию лица в формате jpg в соответствии с нашим соглашением об именах.

Одна из вещей, которую стоит отметить, заключается в том, чтоgray[y : y + h, x : x + w]. Здесь мы рассматриваем изображение в градациях серого как двумерный массив (или двумерный вектор), а затем используем python[]Захватите область лица, обнаруженную OpenCV.

Но такой код быстро сгенерировал бы много фотографий, скажем, 20 за секунду. Мы не хотим быть такими быстрыми, нам нужен более качественный материал, например фотографии, сделанные с разных ракурсов, в данном случае требуется медленнее.

Чтобы быть медленнее, нам нужно увеличить задержку между кадрами. При этом материалов нам нужно не слишком много, всего 20.

while True:
    ret, img = cap.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = detector.detectMultiScale(gray, 1.3, 5)
    for (x, y, w, h) in faces:
        cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)

        # 增加例子数 
        sampleNum = sampleNum + 1
        # 把照片保存到数据集文件夹
        cv2.imwrite("dataSet/User." + str(Id) + '.' + str(sampleNum) + ".jpg", gray[y:y + h, x:x + w])  #

        cv2.imshow('frame', img)
    # 延迟100毫秒 
    if cv2.waitKey(100) & 0xFF == ord('q'):
        break
    # 超过20张就可以停了
    elif sampleNum > 20:
        break

Хорошо, продолжайте, теперь код будет задерживать 100 мс между кадрами, 100 мс нам достаточно, чтобы сдвинуть угол лица (больше, если не хватает). И он остановился после 20 выстрелов.

Наконец, не забудьте освободить ресурсы:

cap.release()
cv2.destroyAllWindows()

Выпустите полный код:

import cv2

detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
cap = cv2.VideoCapture(0)
sampleNum = 0
Id = raw_input('enter your id: ')

while True:
    ret, img = cap.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = detector.detectMultiScale(gray, 1.3, 5)
    for (x, y, w, h) in faces:
        cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)

        # incrementing sample number
        sampleNum = sampleNum + 1
        # saving the captured face in the dataset folder
        cv2.imwrite("dataSet/User." + str(Id) + '.' + str(sampleNum) + ".jpg", gray[y:y + h, x:x + w])  #

        cv2.imshow('frame', img)
    # wait for 100 miliseconds
    if cv2.waitKey(100) & 0xFF == ord('q'):
        break
    # break if the sample number is morethan 20
    elif sampleNum > 20:
        break

cap.release()
cv2.destroyAllWindows()

генерировать результаты

Как показано на рисунке, было сгенерировано множество обучающих материалов.

первый

оригинальный, если есть какие-либо ошибки, пожалуйста, укажите и обратите больше вниманияжареная рыба.