[Stove AI] Машинное обучение 052-OpenCV создает детектор лиц, носа и глаз
(Библиотеки Python и номера версий, используемые в этой статье: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2, opencv-python 3.4.2)
Есть два важных понятия, которые необходимо прояснить: обнаружение лица: относится к обнаружению лица на изображении или видео, а также к обнаружению конкретного местоположения лица и распознаванию лица: определение того, есть ли лицо на изображении или видео. это Чжан Сан или Ли Си или кто-то еще. Таким образом, распознавание лиц является основой и предпосылкой распознавания лиц.
В этой главе мы узнаем, как создать детектор лица, детектор носа и детектор глаз с помощью OpenCV.
1. Создайте детектор лиц
Как упоминалось ранее, детектор лица — это процесс определения положения лица на изображении, для построения детектора лица мы будем использовать каскад Хаара. Каскады Хаара реализуются путем извлечения большого количества простых признаков из изображений в разных масштабах, таких как края, углы, линии, прямоугольники и т. д., а затем обучения их путем создания серии простых классификаторов.
Каскад Хаара — это каскадный классификатор, основанный на функциях Хаара. Так называемый каскадный классификатор — это процесс объединения нескольких слабых классификаторов в сильный классификатор. Слабый классификатор означает, что производительность ограничена, а точность прогнозирования не очень хорошая. Высокий классификатор , так что конкатенация здесь — это на самом деле метод Boost в машинном обучении, то есть метод ансамбля. Таким образом, классификатор Хаара = Хаар-подобные функции + метод интегрального графа + AdaBoost + каскад. Для ознакомления с концепциями функций типа Хаара и интегральных графиков вы можете обратиться к сообщению в блоге:Анализ метода классификатора Хаара для обнаружения лиц.
1.1 Распознавание лиц на одном изображении
# 构建单张图片的人脸检测器
def img_face_detector(img_path,face_cascade_file):
image=cv2.imread(img_path)
face_cascade=cv2.CascadeClassifier(face_cascade_file)
if face_cascade.empty():
raise IOError('Unable to load the face cascade classifier xml file!')
gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
face_rects=face_cascade.detectMultiScale(gray,1.3,5)
# 在检测到的脸部周围画矩形框
for (x,y,w,h) in face_rects:
cv2.rectangle(image,(x,y),(x+w,y+h),(0,0,255),3)
return image
# 测试一下这个人脸检测器:
image1=img_face_detector('E:\PyProjects\DataSet\FireAI/face1.jpg',
'E:\PyProjects\DataSet\FireAI\cascade_files/haarcascade_frontalface_alt.xml')
image1=cv2.cvtColor(image1,cv2.COLOR_BGR2RGB)
plt.imshow(image1)
Выполняя обнаружение лиц на следующих изображениях, мы получаем следующие результаты:
1.2 Распознавание лиц в видеопотоке
Суть видеопотока на самом деле состоит в изображении, и изображение может воспроизводиться с определенной частотой кадров в секунду (fps). Поэтому, когда мы анализируем видео, нам нужно захватить картинку из видеопотока и проанализировать картинку.
# 对视频流进行人脸检测
def video_face_detector(face_cascade_file):
face_cascade=cv2.CascadeClassifier(face_cascade_file)
if face_cascade.empty():
raise IOError('Unable to load the face cascade classifier xml file!')
capture=cv2.VideoCapture(0)
while True:
_,frame=capture.read() # 捕获当前帧
gray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
face_rects=face_cascade.detectMultiScale(gray,1.3,5)
# 在检测到的脸部周围画矩形框
for (x,y,w,h) in face_rects:
cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),3)
cv2.imshow('Video Face Detector', frame)
key=cv2.waitKey(1) # 按ESC退出检测
if key==27:
break
capture.release()
cv2.destroyAllWindows()
2. Создание детектора носа
2.1 обнаружение носа на одном изображении
# 构建单张图片的鼻子检测器
def img_nose_detector(img_path,face_cascade_file,nose_cascade_file,show_face=True):
image=cv2.imread(img_path)
face_cascade=cv2.CascadeClassifier(face_cascade_file)
if face_cascade.empty():
raise IOError('Unable to load the face cascade classifier xml file!')
nose_cascade=cv2.CascadeClassifier(nose_cascade_file)
if nose_cascade.empty():
raise IOError('Unable to load the nose cascade classifier xml file!')
gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
face_rects=face_cascade.detectMultiScale(gray,1.3,5)
# 在检测到的脸部周围画矩形框
for (x,y,w,h) in face_rects:
if show_face: cv2.rectangle(image,(x,y),(x+w,y+h),(0,0,255),3)
roi=gray[y:y+h,x:x+w]
nose_rects=nose_cascade.detectMultiScale(roi,1.3,5)
for (x_nose,y_nose,w_nose,h_nose) in nose_rects:
cv2.rectangle(image,(x+x_nose,y+y_nose),(x+x_nose+w_nose,y+y_nose+h_nose),
(0,255,0),3)
break # 一张脸上只能有一个鼻子,故而此处break
return image
2.2 обнаружение носа в видеопотоке
Точно так же код для обнаружения носа в видеопотоке:
# 对视频流进行鼻子检测
def video_nose_detector(face_cascade_file,nose_cascade_file):
face_cascade=cv2.CascadeClassifier(face_cascade_file)
if face_cascade.empty():
raise IOError('Unable to load the face cascade classifier xml file!')
nose_cascade=cv2.CascadeClassifier(nose_cascade_file)
if nose_cascade.empty():
raise IOError('Unable to load the nose cascade classifier xml file!')
capture=cv2.VideoCapture(0)
while True:
_,frame=capture.read() # 捕获当前帧
gray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
face_rects=face_cascade.detectMultiScale(gray)
# 在检测到的脸部周围画矩形框
for (x,y,w,h) in face_rects:
cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),3)
roi=gray[y:y+h,x:x+w]
nose_rects=nose_cascade.detectMultiScale(roi,1.3,5)
for (x_nose,y_nose,w_nose,h_nose) in nose_rects:
cv2.rectangle(frame,(x+x_nose,y+y_nose),(x+x_nose+w_nose,y+y_nose+h_nose),
(0,255,0),3)
break # 一张脸上只能有一个鼻子,故而此处break
cv2.imshow('Video Face Detector', frame)
key=cv2.waitKey(1) # 按ESC退出检测
if key==27:
break
capture.release()
cv2.destroyAllWindows()
Точно так же можно построить детекторы глаз для одиночных изображений и видеопотоков, и можно увидеть определенный код (мой гитхаб)
Конечно, вы также можете создать функцию для одновременного обнаружения носа и глаз, только нужно немного изменить исходную функцию обнаружения носа.
########################резюме########################## ######
1. Здесь построен детектор лица, носа и глаз с использованием каскада Хаара, который хорошо может обнаруживать различную структурную информацию в картинках и видеопотоках.
2. Из результатов видно, что, хотя это может быть эффективно обнаружено, некоторые лица, носы, глаза и т. д. обнаружить трудно.В это время может потребоваться настройка параметров функции обнаружения detectMultiScale() , Если параметры настройки все еще не идеальны, необходимо изменить только xml каскадного файла обнаружения признаков cascade_file.
#################################################################
Примечание. Эта часть кода была загружена в (мой гитхаб), добро пожаловать на скачивание.
Использованная литература:
1. Классические примеры машинного обучения Python, Пратик Джоши, перевод Тао Цзюньцзе и Чена Сяоли.