Использование Keras и OpenCV

Хотя идея использования машинного обучения для распознавания лиц известна давно, все же весьма полезно создать это программное обеспечение самостоятельно.

Концепция:

Цель этой статьи — создать сеть распознавания лиц с бинарной классификацией, чтобы разрешить доступ одному человеку, а не другому.

Я буду использовать open-cv для доступа к встроенной камере компьютера и использовать классификаторы haar-cascade для обнаружения лиц на изображении. После сбора данных я буду использовать сверточную нейронную сеть для обучения модели на данных.

После этого, когда OpenCV обнаружит человека, которому был предоставлен доступ, он нарисует квадрат вокруг его/ее лица со словами «доступ подтвержден» на квадрате.

Код:

from numpy import unique
from numpy import argmax
import os
import cv2
from PIL import Image
import numpy as np
from tensorflow.keras import Sequential
from tensorflow.keras import optimizers
from tensorflow.keras.layers import Dense
from tensorflow.keras.layers import Conv2D
from tensorflow.keras.layers import MaxPooling2D
from tensorflow.keras.layers import Flatten
from tensorflow.keras.layers import Dropout
from tensorflow.keras.layers import BatchNormalization
from tensorflow.keras.layers import Dropout

Помимо стандартных библиотек numpy и os для доступа к данным и обработки данных, я также использую open-cv и PIL для обработки изображений.

def data_path():
    file = 'XXXXXXXX'
    os.chdir(file)
    files = os.listdir()
    files.remove('.DS_Store')
    return file,files

Это функция доступа к данным на вашем компьютере. Чтобы эта функция работала, измените файл переменных на соответствующий каталог, в котором находятся ваши данные.

def data_setup(files,file):
    pixels = [0]*len(files)
    answers = list()
    print(len(files))
    for i in range(len(files)):
        image = Image.open(files[i])
        pixels[i]= np.asarray(image)
        pixels[i] = pixels[i].astype('float32')
        pixels[i] /= 210.0
        if files[i][0] == 'm':
            answers.append(1)
        elif files[i][0] == 'n':
            answers.append(0)
    dataset = np.array(pixels)
    for i in range(len(dataset)):
        dataset[i] = dataset[i].reshape(320,320)
    return np.asarray(dataset),np.asarray(answers)

Эта функция получает доступ к данным и преобразует все фотографии в изображения размером 320 на 320 пикселей. Затем он возвращает значения X и y, то есть данные и истинные значения.

def train(data,answers):
    x_train = data
    y_train = answers
    x_train = np.array(x_train)
    x_train = x_train.reshape((x_train.shape[0], x_train.shape[1], x_train.shape[2], 1))
    print(x_train.shape)
    in_shape = x_train.shape[1:]
    print(len(data),len(answers))
    model = Sequential()
    model.add(Conv2D(10, (3,3), activation='relu', kernel_initializer='he_uniform', input_shape=in_shape))
    model.add(MaxPooling2D((2, 2)))
    model.add(Conv2D(10, (3,3), activation='relu', kernel_initializer='he_uniform', input_shape=in_shape))
    model.add(MaxPooling2D((2, 2)))
    model.add(Flatten())
    model.add(Dense(1,activation ='sigmoid'))
    model.compile(optimizer='adam', loss='binary_crossentropy',metrics = ['accuracy'])
    model.fit(x_train, y_train, epochs=100, batch_size=100, verbose = 2, validation_split = 0.33)
    return model

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

def face_recognition(model):
    dirx = 'XXXXXXXXXXXXXXXXXXXXXXXXXX'
    os.chdir(dirx)
    face_cascade = cv2.CascadeClassifier('cascades/data/haarcascade_frontalface_alt.xml')
    cap = cv2.VideoCapture(0)
    while True:
        ret,frame = cap.read()
        gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
        faces = face_cascade.detectMultiScale(gray,scaleFactor = 1.05, minNeighbors = 5)
        for (x,y,w,h) in faces:
            print('Face Detected')
            roi_gray = gray[y:y+h,x:x+w]
            roi_color = frame[y:y+h,x:x+w]
            roi_gray = roi_gray.astype('float32')
            roi_gray /= 210.0
            classify = cv2.resize(roi_gray,(320,320))
            if classify.shape == (320,320):
                classify = classify.reshape((1, classify.shape[0], classify.shape[1], 1))
                color = (255,0,0)
                stroke = 2
                end_cord_x = x+w
                end_cord_y = y+h
                pred = model.predict(classify)
                print(pred)
                if pred == 1:
                    cv2.rectangle(frame,(x,y),(end_cord_x,end_cord_y),color,stroke)
                    cv2.putText(frame, 'Access', (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (36,255,12), 2)
                elif pred == 0:
                    cv2.rectangle(frame,(x,y),(end_cord_x,end_cord_y),color,stroke)
                    cv2.putText(frame, 'Denied Access', (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (36,255,12), 2)
        if cv2.waitKey(20) & 0xFF == ord('q'):
            break
        cv2.imshow('frame',frame)

Этот скрипт применяет модель и делает прогнозы в режиме реального времени, создавая и помечая поля, в которых есть лица. Чтобы эта функция работала, вы должны еще раз определить, в каком каталоге находится haar-cascade. Возможно, вам потребуется взять папку из внешнего места, чтобы переместить ее в нужный каталог.

file,files=data_path()
data,answers = data_setup(files,file)
model = train(data,answers)
face_recognition(model)

Эта заключительная часть программы управляет всеми функциями и запускает распознавание лиц в реальном времени.

Как вы можете улучшить мою программу:

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

  • Мультиклассовая классификация

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

  • Добавьте больше классификаторов haar-cascade

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

Мои ссылки:

Если вы хотите увидеть больше моего контента, нажмите на эту ссылку.