Создайте eye tracker, который сканирует только верхнюю 1/2 моего лица

#python #opencv

#python #opencv

Вопрос:

Мою оригинальную идею можно увидеть в приведенном ниже коде, но она все еще обнаруживает глаза на нижней половине моего лица. Цель состоит в том, чтобы заставить его сканировать только верхнюю половину моего лица, поэтому отсеивать неправильные совпадения.

 import cv2


face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml')

cap = cv2.VideoCapture(0)  # sets up webcam

while 1:  # capture frame, converts to greyscale, looks for faces
    ret, img = cap.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(gray, 1.3, 5)

    for (x, y, w, h) in faces:  # draws box around face
        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]
        half_point = y
        print("half point: "   str(half_point))
        eyes = eye_cascade.detectMultiScale(roi_gray)  # looks for eyes
        for (ex, ey, ew, eh) in eyes:  # draws boxes around eyes
            check_point = ey
            print("check_point: "   str(check_point))
            if check_point > half_point:
                pass
            else:
                cv2.rectangle(roi_color, (ex, ey), (ex   ew, ey   eh), (0, 255, 0), 2)

    cv2.imshow('img', img)
    if cv2.waitKey(1) amp; 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()
 

Комментарии:

1. используйте детектор лиц каскад Хаара и обрезайте границы от середины к вершине

2. Возможно, небольшая настройка, подобная этой roi_gray = gray[y h//2:y h, x:x w] , вам может потребоваться внести и это редактирование roi_color . Примечание: я не уверен y , указывает ли он вниз или вверх. Если он направлен вниз, то это должно быть roi_gray = gray[y:y h//2, x:x w] вместо этого.

3. Еще одно замечание… Я столкнулся с той же проблемой, с которой вы сталкиваетесь сейчас, в прошлом, и самым полезным изменением было использование eye_rectangles, reject_levels, confidence = self.CLF_EYES.detectMultiScale3(gray[y:y height, x:x width], scaleFactor = 1.1, minNeighbors = min_neighbors, minSize = (15, 15), outputRejectLevels = True) detectMultiScale3 уровней достоверности предложений note. Увеличение min_neighbors поможет игнорировать плохие совпадения, я рекомендую использовать min_neighbors = 7 или что-то около 7. Наконец, установка значения min_size сократит время вычислений.

Ответ №1:

Я изменил только строки 15 и 16

 cv2.rectangle(img, (x, y), (x   w, y   int(h / 2)), (255, 0, 0), 2)
roi_gray = gray[y:y   int(h / 2), x:x   w]
 

Полный код:

 import cv2


face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml')

cap = cv2.VideoCapture(0)  # sets up webcam

while 1:  # capture frame, converts to greyscale, looks for faces
    ret, img = cap.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(gray, 1.3, 5)

    for (x, y, w, h) in faces:  # draws box around face
        cv2.rectangle(img, (x, y), (x   w, y   int(h / 2)), (255, 0, 0), 2) #Modified
        roi_gray = gray[y:y   int(h / 2), x:x   w] #Modified
        roi_color = img[y:y   h, x:x   w]
        half_point = y
        print("half point: "   str(half_point))
        eyes = eye_cascade.detectMultiScale(roi_gray)  # looks for eyes
        for (ex, ey, ew, eh) in eyes:  # draws boxes around eyes
            check_point = ey
            print("check_point: "   str(check_point))
            if check_point > half_point:
                pass
            else:
                cv2.rectangle(roi_color, (ex, ey), (ex   ew, ey   eh), (0, 255, 0), 2)

    cv2.imshow('img', img)
    if cv2.waitKey(1) amp; 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()
 

Но я рекомендую использовать dlib insead. Это более надежно.

Вот мой пример:

 import numpy as np
import cv2
import dlib


cap = cv2.VideoCapture(0)

predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
detector = dlib.get_frontal_face_detector()

def draw_on_frame(eye):
    coordinates = np.array([])
    for i in eye:
        x = landmarks.part(i).x
        y = landmarks.part(i).y
        cv2.circle(frame, (x, y), 3, (0, 0, 255), -1)
        coordinates = np.append(coordinates, [x, y])
    x1, y1, w1, h1 = cv2.boundingRect(coordinates.reshape(-1, 2).astype(int))
    cv2.rectangle(frame, (x1, y1), (x1   w1, y1   h1), (0, 255, 0), 1)
    return x1, y1, w1, h1


while (cap.isOpened()):
    ret, frame = cap.read()
    if ret == True:
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        faces = detector(gray)

        for face in faces:
            landmarks = predictor(gray, face)

            left_eye = range(36, 42)
            right_eye = range(42, 48)

            left = draw_on_frame(left_eye)
            right = draw_on_frame(right_eye)

            roi_left = frame[left[1]:left[1] left[3], left[0]:left[0] left[2]]
            roi_right = frame[right[1]:right[1]   right[3], right[0]:right[0]   right[2]]

        cv2.imshow('frame', frame)
        if cv2.waitKey(1) amp; 0xFF == ord('q'):
          break

    else:
        break

cap.release()
cv2.destroyAllWindows()
 

Комментарии:

1. Stackoverflow не показывает номера строк — какой из 15, 16 них? Вы могли бы показать эти строки перед полным кодом. И вы могли бы описать, что вы сделали в этих строках.

2. Я изменил эти 2 строки: cv2.rectangle(img, (x, y), (x w, y int(h / 2)), (255, 0, 0), 2) roi_gray = серый[y:y int(h /2), x:x w]

3. добавьте это в ответ — чтобы все люди это увидели. Этот ответ также предназначен для других посетителей.