Виола-Джонс в Python с openCV, обнаружением рта и носа

У меня есть алгоритм Виолы-Джонса в Python. Я использую haarcascade xml, который загружаю из openCV корневого файла. Но в openCV не было XML-файла для рта и носа, поэтому я скачал эти файлы с EmguCV. Результат для обнаружения лица в порядке, но обнаружение глаз не очень хорошее, а нос со ртом очень плохое. Пробовал менять параметры в face_cascade.detectMultiScale, не помогло вообще.


Мой код:

import cv2
import sys

def facedet(img):
    face_cascade = cv2.CascadeClassifier('/home/kattynka/opencv/data/haarcascades/haarcascade_frontalface_default.xml')
    eye_cascade = cv2.CascadeClassifier('/home/kattynka/opencv/data/haarcascades/haarcascade_eye.xml')
    mouth_cascade = cv2.CascadeClassifier('/home/kattynka/opencv/data/haarcascades/haarcascade_mcs_mouth.xml')
    nose_cascade = cv2.CascadeClassifier('/home/kattynka/opencv/data/haarcascades/haarcascade_mcs_nose.xml')

    img = cv2.imread(img)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    faces = face_cascade.detectMultiScale(gray, 1.3, 5)

    for (x,y,w,h) in faces:
        cv2.rectangle(img, (x,y), (x+w,y+h), (255,0,0), 2)
        roi_gray = gray[y:y+h, x:x+w]
        roi_color = img[y:y+h, x:x+w]
        eyes = eye_cascade.detectMultiScale(roi_gray)
        nose =  nose_cascade.detectMultiScale(roi_gray)
        mouth = mouth_cascade.detectMultiScale(roi_gray)

        for (ex,ey,ew,eh) in eyes:
            cv2.rectangle(roi_color, (ex,ey), (ex+ew, ey+eh), (0,255,0), 2)
        for (nx, ny, nw, nh) in nose:
            cv2.rectangle(roi_color, (nx, ny), (nx + nw, ny + nh), (0, 0, 255), 2)
        for (mx, my, mw, mh) in mouth:
            cv2.rectangle(roi_color, (mx, my), (mx + mw, my + mh), (0, 0, 0), 2)

    cv2.namedWindow('image', cv2.WINDOW_NORMAL)
    cv2.imshow('image',img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


if __name__ == '__main__':
    #img = sys.argv[1]
    facedet(img)

Мой вопрос

Что я делаю неправильно? Есть ли какое-нибудь простое решение, которое даст мне лучший результат?


Вывод:

введите здесь описание изображения

введите здесь описание изображения

введите здесь описание изображения

введите здесь описание изображения


person Kattynka    schedule 09.07.2016    source источник
comment
Только одно примечание: эти фотографии общедоступны? Они принадлежат вам? В противном случае, пожалуйста, удалите.   -  person Berriel    schedule 09.07.2016
comment
Фотографии общедоступны, их можно загрузить с сайта ibug.doc.ic.ac. uk/resources/facial-point-annotations .   -  person Kattynka    schedule 10.07.2016


Ответы (3)


Каскады Хаара хорошо работают для лиц, но не так хорошо для более мелких отдельных частей. Лучшим решением будет обнаружение всех ориентиров лица вместе. Хорошим алгоритмом для этого является «Выравнивание лица за одну миллисекунду с ансамблем деревьев регрессии Вахида Каземи и Жозефины Салливан, CVPR 2014», который реализован в Dlib (http://dlib.net/face_landmark_detection.py.html).

person Mikael Rousson    schedule 13.07.2016

Это работает очень хорошо для меня.

Я обнаружил, что если вы разделите лицо на 2 части и заставите глаза искать глаза в верхней части, а рот в нижней части, это работает очень хорошо.

face
--------
| eyes |
|------|
|mouth |
--------

Это грубая иллюстрация того, что я сделал с кодом ниже.

Я знаю, что каскад, который я использую, это smile, но рот, похоже, не работает.

import cv2
import sys

mouthCascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_smile.xml')
faceCascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
eyeCascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_eye.xml')
video_capture = cv2.VideoCapture(0)

while True:
    # Capture frame-by-frame
    ret, frame = video_capture.read()

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    mouth = mouthCascade.detectMultiScale(gray, 1.3, 5)
    faces = faceCascade.detectMultiScale(
                gray,
                scaleFactor=1.1,
                minNeighbors=5,
                minSize=(30, 30)
            )
            # Draw a rectangle around the faces
    for (x, y, w, h) in faces:
        cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2)
            # Draw a rectangle around the faces
        roi_gray_mouth = gray[y+(int(h/2)):y+h, x:x+w]
        roi_color_mouth = frame[y+(int(h/2)):y+h, x:x+w]

        roi_gray_eye = gray[y-(int(h/2)):y+h, x:x+w]
        roi_color_eye = frame[y-(int(h/2)):y+h, x:x+w]

        mouth = mouthCascade.detectMultiScale(roi_gray_mouth)
        eyes = eyeCascade.detectMultiScale(roi_gray_eye)
        for (ex,ey,ew,eh) in mouth:
            cv2.rectangle(roi_color_mouth, (ex, ey), (ex+ew, ey+eh), (0, 255, 0), 2)

        for (eex,eey,eew,eeh) in eyes:
            d = int(eew / 2)
            cv2.circle(roi_color_eye, (int(eex + eew / 4) + int(d / 2), int(eey + eeh / 4) + int(d / 2)), int(d) ,(0,0,255),2)

    # Display the resulting frame
    cv2.imshow('Video', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# When everything is done, release the capture
video_capture.release()
cv2.destroyAllWindows()
person JareBear    schedule 11.12.2019

импорт cv2 импорт системы

face_cascade = cv2.CascadeClassifier('/home/kattynka/opencv/data/haarcascades/haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('/home/kattynka/opencv/data/haarcascades/haarcascade_eye.xml')
mouth_cascade = cv2.CascadeClassifier('/home/kattynka/opencv/data/haarcascades/haarcascade_mcs_mouth.xml')
nose_cascade = cv2.CascadeClassifier('/home/kattynka/opencv/data/haarcascades/haarcascade_mcs_nose.xml')

img = cv2.imread(img)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

faces = face_cascade.detectMultiScale(gray, 1.3, 5)

for (x,y,w,h) in faces:
    cv2.rectangle(img, (x,y), (x+w,y+h), (255,0,0), 2)
    roi_gray = gray[y:y+h, x:x+w]
    roi_color = img[y:y+h, x:x+w]
    eyes = eye_cascade.detectMultiScale(gray, 1.3, 5)
    nose =  nose_cascade.detectMultiScale(gray, 1.3, 5)
    mouth = mouth_cascade.detectMultiScale(gray, 1.7, 11)

    for (ex,ey,ew,eh) in eyes:
        cv2.rectangle(img, (ex,ey), (ex+ew, ey+eh), (0,255,0), 2)
    for (nx, ny, nw, nh) in nose:
        cv2.rectangle(img, (nx, ny), (nx + nw, ny + nh), (0, 0, 255), 2)
    for (mx, my, mw, mh) in mouth:
        cv2.rectangle(img, (mx, my), (mx + mw, my + mh), (0, 0, 0), 2)

cv2.namedWindow('image', cv2.WINDOW_NORMAL)
cv2.imshow('image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

вы можете попробовать этот код. Это сработало для меня.

person MAT    schedule 22.03.2017