[Stove AI] Машинное обучение 052-OpenCV создает детектор лиц, носа и глаз

машинное обучение искусственный интеллект Python OpenCV

[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, Пратик Джоши, перевод Тао Цзюньцзе и Чена Сяоли.