[Stove AI] Машинное обучение 055 — Создание распознавателя лиц с использованием гистограммы LBP
(Библиотеки Python и номера версий, используемые в этой статье: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2)
сообщение в блоге передо мной[Stove AI] Машинное обучение 052-OpenCV создает детектор лиц, носа и глазВ разделе мы говорили о методе и кодовой реализации обнаружения лица, но во многих практических случаях нам нужно сделать распознавание лица, то есть определить, является ли лицо на изображении Чжан Санем или Ли Си, поэтому в этом статью мы рассмотрим Посмотрите, как использовать гистограмму LBP для построения распознавателя лиц.
1. Введение в локальные бинарные паттерны
Local Binary Pattern (LBP) — это оператор, используемый для описания локальных особенностей текстуры изображения. Локальный текстурный анализ имеет много потенциальных применений, таких как проверка промышленных поверхностей, удаленный мониторинг, анализ изображений и т. д.
Основная идея LBP: исходный оператор LBP представляет собой окно 3 * 3 с центральным пикселем в качестве порога и сравнивает значения серого соседних 8 пикселей с центральным пикселем.Это 0, поэтому получается бинаризованное изображение этих 9 пикселей, поэтому название — локальная бинаризация, как показано на следующем рисунке. От левого центрального пикселя бинаризованного изображения в качестве начальной точки направление против часовой стрелки является квадратом, и бинаризованное значение берется для получения двоичного значения шаблона в изображении.Это значение является кодом LBP. время, мы называем значение LBP центрального пикселя 11110001. Если значение LBP вычисляется для всех пикселей изображения, получается карта характеристик LBP изображения.
Относительно инвариантности оттенков серого: очевидно, что если все значения оттенков серого в исходном локальном изображении увеличиваются на одно значение или вычитаются на одно значение одновременно, это эквивалентно увеличению или уменьшению яркости, но в это время полученный код LBP остается неизменным, так называемая инвариантность оттенков серого. Следует отметить, что инвариантность оттенков серого применима только к монотонным изменениям значений оттенков серого. Как показано ниже
Вышеприведенный LBP-оператор имеет недостаток, он покрывает только небольшую область в пределах фиксированного радиуса, что явно не может удовлетворить потребности текстур разного размера и частоты, поэтому некоторые люди улучшают его и расширяют поле 3*3 на любое поле. замените квадратное поле круглым полем.На следующем рисунке показан случай, когда центральный пиксель является центром круга, R является радиусом, а точки P равномерно выбираются в качестве точек выборки на круге.
На приведенном выше рисунке размер R определяет размер круга, отражающий масштаб двумерного пространства, а размер P определяет количество точек выборки, отражающих разрешение углового пространства. Точно так же мы также можем изменить значения R и P для достижения различных масштабных и угловых разрешений (как показано ниже). Это также является теоретической основой «анализа с несколькими разрешениями» в будущем.
Хотя приведенный выше оператор LBP может достигать нескольких разрешений, он не инвариантен к вращению, и вращение изображения будет получать разные значения LBP.Значение LBP начального определения серии принимает минимальное значение в качестве значения LBP для поле.
В приложениях LBP, таких как распознавание лиц и анализ текстуры, мы обычно не используем карту LBP в качестве вектора признаков для классификации и распознавания, а используем статистическую гистограмму карты признаков LBP в качестве вектора признаков.
Шаги использования гистограммы LBP для извлечения признаков обычно следующие:
1) Сначала разделите окно обнаружения на 16×16 небольших областей (ячеек)
2) Для пикселя в каждой ячейке сравниваем с ним значение серого соседних 8 пикселей.Если значение окружающего пикселя больше значения центрального пикселя, позиция пикселя помечается как 1, в противном случае - 0. Таким образом, можно сравнить 8 точек в окрестности 3*3, чтобы сгенерировать 8-битное двоичное число, то есть можно получить значение LBP центрального пикселя окна.
3) Затем вычислить гистограмму каждой ячейки, то есть частоту каждого числа (предполагается, что это десятичное число значение LBP); затем нормализовать гистограмму
4) Наконец, полученная статистическая гистограмма каждой ячейки соединяется в вектор признаков, то есть вектор признаков текстуры LBP всего изображения, после чего для классификации можно использовать SVM или другие алгоритмы машинного обучения.
Для углубленной теории LBP вы можете обратиться к сообщению в блоге:Принцип извлечения признаков LBP (локальный двоичный шаблон)иЛокальные двоичные шаблоны для классификации текстур
2. Подготовьте набор данных
Набор данных, используемый в этом проекте,набор данных лицаПодмножество , где я выбираю только три изображения лица для тестирования. Набор данных состоит из двух частей: в папке поезда есть три подпапки, каждая подпапка представляет изображения лиц человека, а тестовая папка содержит только различные изображения лиц без подпапок. Итак, сначала нам нужно загрузить эти изображения в память и определить функцию ниже для загрузки изображений.
# 定义一个函数来加载图片数据集
def load_train_set(imgs_folder,face_cascade):
'''
从imgs_folder中加载图片数据和标记,注意imgs_folder中包含有多个子文件夹,每个子文件夹的名称就是label
'''
folders=glob(os.path.join(imgs_folder,'*'))
imgs_paths=[]
[imgs_paths.extend(glob(os.path.join(folder, '*.*'))) for folder in folders]
face_imgs=[]
labels=[]
# 对每一张图片都检测画面上的人脸
for img_path in imgs_paths:
image = cv2.imread(img_path, 0)
label=os.path.split(img_path)[0]
img_folder=os.path.split(img_path)[0]
faces = face_cascade.detectMultiScale(image, 1.1, 2, minSize=(100,100))
for (x, y, w, h) in faces:
face_imgs.append(image[y:y+h, x:x+w])
labels.append(os.path.split(img_folder)[1])
# 此处有点不合理,本数据集中每张图片只有一个人脸,故而可以用这个方式,
# 如果有多个不同人的脸,则不能用折冲方式。
# 将labels转换为数字
label_encoder=LabelEncoder()
encode_labels=label_encoder.fit_transform(labels)
return face_imgs, encode_labels, label_encoder,labels
Проверьте, работает ли вышеуказанная функция, и отобразите загруженную фотографию лица.
# 测试上面函数是否正常
face_cascade=cv2.CascadeClassifier('E:\PyProjects\DataSet\FireAI\cascade_files/haarcascade_frontalface_alt.xml')
face_imgs, labels, label_encoder,labels=load_train_set('E:\PyProjects\/DataSet\FireAI\/faces_dataset/train',face_cascade)
print(len(face_imgs)) # 有53张脸,但是检测得到56个结果,显然有几张图片中检测了多张脸
# 显示任一张人脸
# 由于cv2读取的是BGR,而plt是RGB,故而需要转化一下
plt.imshow(face_imgs[3],cmap='gray')
Из распечатанного результата видно, что есть еще три картинки, а значит есть три картинки, которые не являются фотографиями лица вперемешку, поэтому ее нужно найти и удалить. Определите функцию для поиска неправильного изображения
def find_false_faces(face_imgs):
'''
将所有脸部照片显示出来,如果发现有错误的,按d键,记录下错误的脸部照片
'''
need_del_ids=[]
for idx,face in enumerate(face_imgs):
cv2.namedWindow('check', cv2.WINDOW_NORMAL)
cv2.resizeWindow('check', 500, 500)
cv2.imshow('check', face)
key = cv2.waitKey(0)
if key==27: # 如果输入时Esc,则退出循环
print('esc to exit')
break
elif key==100: # 如果输入d键,则记录该脸对应的id
need_del_ids.append(idx)
cv2.destroyAllWindows()
print('finished...')
return need_del_ids
Следовательно, необходимо удалить эти три изображения и соответствующую информацию о метках из исходного набора данных.
# 从数据集中删除这三张照片对应的信息
face_imgs=np.delete(np.array(face_imgs), need_del_ids, axis=0)
encode_labels=np.delete(np.array(encode_labels), need_del_ids, axis=0)
labels=np.delete(np.array(labels), need_del_ids,axis=0)
print(face_imgs.shape) # 53张图没错,元素已经变成了np.ndarray,故而只有行
3. Создание распознавателя гистограмм LBP
Распознаватель гистограммы LBP здесь эквивалентен модели классификации, cv2 уже упаковал для нас эту модель классификации, и нам нужно только вызвать ее.
# 构建createLBPHFaceRecognizer分类模型
from cv2.face import LBPHFaceRecognizer_create
recognizer=LBPHFaceRecognizer_create()
recognizer.train(face_imgs, encode_labels) # 模型训练
Как только модель распознавания лиц обучена, ее можно использовать для распознавания лиц.Давайте посмотрим на результаты распознавания лица на новом изображении.
# 用训练好的模型预测新照片
def predict_imgs(new_imgs_folder, face_cascade,recognizer,label_encoder):
'''
用训练好的人脸识别器来识别人脸'''
img_paths=glob(new_imgs_folder+'/*.*')
predicted_imgs=[]
for img_path in img_paths:
image=cv2.imread(img_path)
gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
faces=face_cascade.detectMultiScale(gray,1.1, 2, minSize=(100,100))
for (x, y, w, h) in faces:
cv2.rectangle(image,(x,y),(x+w,y+h),(0,0,255),3)
predicted_index, conf = recognizer.predict(gray[y:y+h, x:x+w])
predicted_label=label_encoder.inverse_transform([predicted_index])[0]
cv2.putText(image, predicted_label,(x,y-20), cv2.FONT_HERSHEY_SIMPLEX, 2, (0,0,255), 3)
predicted_imgs.append(image)
return predicted_imgs
Получены следующие результаты:
Конечно, этот распознаватель может распознавать только те лица, которые уже есть в обучающем изображении, и будет неточно предсказывать лица, которых нет в обучающем наборе. Например, попробуйте сфотографировать сестру Фэн, чтобы сделать предсказание.
Подсчитано, что эта фотография сестры Фэн похожа на Person3, поэтому эта модель предсказывает ее как Person3.
########################резюме########################## ######
1. Модель гистограммы LBP может быть быстро обучена и быстро распознана, и имеет широкий спектр приложений в области распознавания лиц.
#################################################################
Примечание. Эта часть кода была загружена в (мой гитхаб), добро пожаловать на скачивание.
Использованная литература:
1. Классические примеры машинного обучения Python, Пратик Джоши, перевод Тао Цзюньцзе и Чена Сяоли.