«Это 30-й день моего участия в ноябрьском испытании обновлений. Подробную информацию об этом событии см.:Вызов последнего обновления 2021 г."
Введение в распознавание лиц
Обнаружение лиц — это задача определения положения и размера лиц на изображении, которая часто является основой для создания приложений обработки лиц (например, распознавание выражений, обнаружение сонливости, классификация пола, распознавание лиц или взаимодействие человека с компьютером и т. д.). ) Поскольку такие приложения требуют в качестве входных данных местоположения и размера обнаруженного лица. Поэтому автоматическое распознавание лиц играет решающую роль и является одной из наиболее изучаемых тем в области искусственного интеллекта.
Обнаружение лица не представляет сложности для людей, но часто сопряжено со многими проблемами для компьютеров (такими как изменение внешнего вида, преобразование масштаба, вращение, преобразование выражения лица, окклюзия или условия освещения и т. д.). В этом разделе мы будем использоватьOpenCV
Предоставляет популярные методы обнаружения лиц, включая методы машинного обучения и глубокого обучения, для обнаружения лиц на изображениях.
Распознавание лиц с помощью OpenCV
OpenCV
Предусмотрено два метода обнаружения лиц, в том числе:
- Детектор лиц на основе каскада Хаара
- Детектор лиц на основе глубокого обучения
Детектор лиц на основе каскада Хаара
OpenCV
на основеViola
иJones
Предложен алгоритм обнаружения лиц, основанный на системе обнаружения объектов. Кроме того, фреймворк обнаружения объектов может также использоваться для обнаружения других объектов, таких как: номерные знаки или кошачьи морды и т. д. В этом разделе мы будем использовать эту структуру для обнаружения лиц.
OpenCV
Для распознавания лиц предусмотрены 4 каскадных классификатора, которые можноОфициальный OpenCVЗагрузите эти файлы каскадного классификатора:
- haarcascade_frontalface_alt.xml (FA1)
- haarcascade_frontalface_alt2.xml (FA2)
- haarcascade_frontalface_alt_tree.xml (FAT)
- haarcascade_frontalface_default.xml (FD)
Производительность этих каскадных классификаторов можно оценить с использованием разных наборов данных, и в целом эти классификаторы имеют одинаковую точность, поэтому в дальнейшем для упрощения процедуры мы используем только два из них (точнее, только Загрузить каскадный классификатор).FA2
иFD
), вы также можете выбрать другие интересующие вас классификаторы, чтобы проверить их эффективность.OpenCV
при условииcv2.CascadeClassifier()
Функция используется для загрузки классификатора из файла:
# 加载级联分类器
# 第一行代码
cas_alt2 = cv2.CascadeClassifier("haarcascade_frontalface_alt2.xml")
cas_default = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
Далее вы можете использоватьcv2.CascadeClassifier.detectMultiScale()
Проверяется выполнение функции:
# 第二行代码,人脸检测就这么简单
faces_alt2 = cas_alt2.detectMultiScale(gray)
faces_default = cas_default.detectMultiScale(gray)
cv2.CascadeClassifier.detectMultiScale()
Функция обнаруживает объекты и возвращает их в виде списка прямоугольников. Для визуализации, наконец, напишитеshow_detection()
функция визуализации:
def show_detection(image, faces):
"""在每个检测到的人脸上绘制一个矩形进行标示"""
for (x, y, w, h) in faces:
cv2.rectangle(image, (x, y), (x + w, y + h), (255, 0, 0), 5)
return image
# 调用 show_detection() 函数标示检测到的人脸
img_faces_alt2 = show_detection(img.copy(), faces_alt2)
img_faces_default = show_detection(img.copy(), faces_default)
Что, две строки кода все еще кажутся громоздкими, тогда пора вызывать детектор и определять лица одной строкой, этоOpenCV
который предоставилcv2.face.getFacesHAAR()
функция:
# 一行代码实现基于 Haar 级联的人脸检测器,学一送一
retval, faces_haar_alt2 = cv2.face.getFacesHAAR(img, "haarcascade_frontalface_alt2.xml")
retval, faces_haar_default = cv2.face.getFacesHAAR(img, "haarcascade_frontalface_default.xml")
cv2.CascadeClassifier.detectMultiScale()
требует изображения в градациях серого в качестве входных данных, в то время какcv2.face.getFacesHAAR()
необходимостьBGR
изображение в качестве входных данных. также,cv2.CascadeClassifier.detectMultiScale()
Выведите обнаруженные лица в виде списка прямоугольников, например, если обнаружено два лица, вывод будет иметь вид:
[[809 494 152 152] [168 503 188 188]]
иcv2.face.getFacesHAAR()
Функция возвращает обнаруженное лицо в следующем формате:
[[[ 809 493 151 151]] [[ 167 503 189 189]]]
Поэтому, если вы используетеcv2.face.getFacesHAAR()
Функция обнаружения, вызываемая при отрисовке рамки обнаруженияnp.squeeze()
Функция удаляет лишние размеры:
faces_haar_alt2 = np.squeeze(faces_haar_alt2)
faces_haar_default = np.squeeze(faces_haar_default)
Полный код от загрузки изображения до обнаружения и рисования лица выглядит следующим образом:
# 可视化函数
def show_img_with_matplotlib(color_img, title, pos):
img_RGB = color_img[:, :, ::-1]
ax = plt.subplot(2, 2, pos)
plt.imshow(img_RGB)
plt.title(title, fontsize=8)
plt.axis('off')
# 加载图像
img = cv2.imread("test_face_detection.jpg")
# 将 BGR 图像转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 加载分类器
cas_alt2 = cv2.CascadeClassifier("haarcascade_frontalface_alt2.xml")
cas_default = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
# 检测人脸
faces_alt2 = cas_alt2.detectMultiScale(gray)
faces_default = cas_default.detectMultiScale(gray)
retval, faces_haar_alt2 = cv2.face.getFacesHAAR(img, "haarcascade_frontalface_alt2.xml")
faces_haar_alt2 = np.squeeze(faces_haar_alt2)
retval, faces_haar_default = cv2.face.getFacesHAAR(img, "haarcascade_frontalface_default.xml")
faces_haar_default = np.squeeze(faces_haar_default)
# 绘制人脸检测框
img_faces_alt2 = show_detection(img.copy(), faces_alt2)
img_faces_default = show_detection(img.copy(), faces_default)
img_faces_haar_alt2 = show_detection(img.copy(), faces_haar_alt2)
img_faces_haar_default = show_detection(img.copy(), faces_haar_default)
# 可视化
show_img_with_matplotlib(img_faces_alt2, "detectMultiScale(frontalface_alt2): " + str(len(faces_alt2)), 1)
show_img_with_matplotlib(img_faces_default, "detectMultiScale(frontalface_default): " + str(len(faces_default)), 2)
show_img_with_matplotlib(img_faces_haar_alt2, "getFacesHAAR(frontalface_alt2): " + str(len(faces_haar_alt2)), 3)
show_img_with_matplotlib(img_faces_haar_default, "getFacesHAAR(frontalface_default): " + str(len(faces_haar_default)), 4)
plt.show()
Вывод программы показан ниже:
Как показано на рисунке выше, с помощьюhaar
Различные каскадные классификаторы признаков обнаруживают разные лица. Наконец, следует отметить, что,cv2.CascadeClassifier.detectMultiScale()
функция имеетminSize
иmaxSize
параметр для установки минимального размера (менееminSize
объекты не будут обнаружены) и максимальный размер (больше чемmaxSize
объекты не будут обнаружены), аcv2.face.getFacesHAAR()
Функция не предоставляет этот параметр.
Детектор лиц на основе глубокого обучения
За исключением основанного наHaar
В дополнение к каскадным детекторам лиц OpenCV предоставляетДетектор лиц на основе глубокого обучения,OpenCV
глубокая нейронная сеть (Deep Neural Networks
, DNN
) детектор лица на основе использованияResNet-10
Сетевой однокадровый детектор MultiBox (SSD
) Рамка.
OpenCV
серединаDNN
модулей с использованием популярных фреймворков глубокого обучения (например,Caffe
,TensorFlow
,Torch
иDarknet
) через предварительно обученную глубокую сеть для прямого вычисления (т. е. этап логического вывода). Это означает, что мы можем использовать предварительно обученную сеть для выполнения полного прямого вычисления и использовать выходные данные для прогнозирования в нашем приложении, не тратя часы на обучение сети.
Затем наша предварительно обученная модель детектора лиц с глубоким обучением выполняет обнаружение лиц, используя следующие две модели:
- Детектор лиц (FP16): версия реализации Caffe с плавающей запятой 16, чтобы использовать этот детектор, сначала загрузите файл модели (deploy.prototxt) и файлы конфигурации (res10_300x300_ssd_iter_140000_fp16.caffemodel);
- Детектор лиц (UINT8): 8-битная квантованная версия реализации TensorFlow, чтобы использовать этот детектор, сначала загрузите файл модели (opencv_face_detector.pbtxt) и файлы конфигурации (opencv_face_detector_uint8.pb).
Далее мы расскажем, как использовать предварительно обученную модель детектора лиц с глубоким обучением для обнаружения лиц Первым шагом также является загрузка предварительно обученной модели:
# 加载预训练的模型, Caffe 实现的版本
net = cv2.dnn.readNetFromCaffe("deploy.prototxt", "res10_300x300_ssd_iter_140000_fp16.caffemodel")
# 加载预训练的模型, Tensorflow 实现的版本
# net = cv2.dnn.readNetFromTensorflow("opencv_face_detector_uint8.pb", "opencv_face_detector.pbtxt")
Для большей точности синий, зеленый и красный каналы должны выполняться отдельно.(104, 177, 123)
Канал означает вычитание и изменение размера изображения до изображения BGR 300 x 300, вOpenCV
можно использовать с помощьюcv2.dnn.blobFromImage()
функция для выполнения этой предварительной обработки:
blob = cv2.dnn.blobFromImage(image, 1.0, (300, 300), [104., 117., 123.], False, False)
Следующим шагом являетсяblob
Установите в качестве входных данных, чтобы получить результат, выполните прямые вычисления для всей сети, чтобы вычислить выходные данные:
# 将 blob 设置为输入并获取检测结果
net.setInput(blob)
detections = net.forward()
Последним шагом является повторение обнаружений и построение результатов, визуализация их только в том случае, если соответствующая достоверность больше минимального порога:
# 迭代所有检测结果
for i in range(0, detections.shape[2]):
# 获取当前检测结果的置信度
confidence = detections[0, 0, i, 2]
# 如果置信大于最小置信度,则将其可视化
if confidence > 0.7:
detected_faces += 1
# 获取当前检测结果的坐标
box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
(startX, startY, endX, endY) = box.astype('int')
# 绘制检测结果和置信度
text = "{:.3f}%".format(confidence * 100)
y = startY -10 if startY - 10 > 10 else startY + 10
cv2.rectangle(image, (startX, startY), (endX, endY), (255, 0, 0), 3)
cv2.putText(image, text, (startX, y), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 2)
# 可视化
show_img_with_matplotlib(image, "DNN face detector: " + str(detected_faces), 1)
plt.show()
Результаты обнаружения детектора лиц на основе глубокого обучения следующие:
Как видно из рисунка выше, все три фронтальных лица могут быть обнаружены с высокой степенью достоверности обеими моделями глубокого обучения.