Использование 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
Хаар-каскад, который я использовал, был фронтальным каскадом лица, который обнаруживал только фронтальные фотографии лица. Вы можете добавить больше классификаторов, которые заставят его работать независимо от угла камеры.
Мои ссылки:
Если вы хотите увидеть больше моего контента, нажмите на эту ссылку.