web-dev-qa-db-fra.com

Suivi de la position de la pupille avec Webcam, OpenCV et Python

J'essaie de construire un robot que je peux contrôler avec des mouvements oculaires de base. Je pointe une webcam vers mon visage et, selon la position de mon élève, le robot se déplacerait d'une certaine manière. Si la pupille se trouve dans les coins supérieur, inférieur, gauche et droit de l'œil, le robot se déplacerait respectivement vers l'avant, l'arrière, la gauche et la droite.

Mon plan initial consistait à utiliser une cascade de casques oculaires pour retrouver mon œil gauche. J'utiliserais ensuite houghcircle sur la région des yeux pour trouver le centre de la pupille. Je déterminais où se trouvait l'élève dans l'œil en déterminant la distance entre le centre du cercle arrondi et les limites de la région générale de l'œil.

Donc, pour la première partie de mon code, j'espère pouvoir suivre le centre de la pupille oculaire, comme le montre cette vidéo. https://youtu.be/aGmGyFLQAFM?t=38

Mais quand je lance mon code, il ne peut pas toujours trouver le centre de l'élève. Le cercle de hough est souvent tracé dans la mauvaise zone. Comment puis-je faire en sorte que mon programme trouve systématiquement le centre de l'élève, même lorsque les yeux bougent?

Est-il possible/meilleur/plus facile pour moi de dire à mon programme où se trouve l'élève au début? J'ai examiné d'autres méthodes de suivi de la vision, mais je ne peux pas former d'algorithme général. Si quelqu'un pouvait aider à en former un, ce serait très apprécié! https://arxiv.org/ftp/arxiv/papers/1202/1202/152.6517.pdf

import numpy as np
import cv2

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

#number signifies camera
cap = cv2.VideoCapture(0)

while 1:
    ret, img = cap.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    #faces = face_cascade.detectMultiScale(gray, 1.3, 5)
    eyes = eye_cascade.detectMultiScale(gray)
    for (ex,ey,ew,eh) in eyes:
        cv2.rectangle(img,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
        roi_gray2 = gray[ey:ey+eh, ex:ex+ew]
        roi_color2 = img[ey:ey+eh, ex:ex+ew]
        circles = cv2.HoughCircles(roi_gray2,cv2.HOUGH_GRADIENT,1,20,param1=50,param2=30,minRadius=0,maxRadius=0)
        try:
            for i in circles[0,:]:
                # draw the outer circle
                cv2.circle(roi_color2,(i[0],i[1]),i[2],(255,255,255),2)
                print("drawing circle")
                # draw the center of the circle
                cv2.circle(roi_color2,(i[0],i[1]),2,(255,255,255),3)
        except Exception as e:
            print e
    cv2.imshow('img',img)
    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break

cap.release()
cv2.destroyAllWindows()
6
user3502541

Je peux voir deux alternatives, à partir de travaux que j'ai déjà réalisés:

  1. Entraînez un détecteur Haar à détecter le globe oculaire, en utilisant des images d’entraînement avec le centre de la pupille au centre et la largeur du globe oculaire. Je l'ai trouvé mieux que d'utiliser des cercles de Hough ou juste le détecteur de yeux original d'OpenCV (celui utilisé dans votre code).

  2. Utilisez les points de repère du visage de Dlib pour estimer la région des yeux. Utilisez ensuite le contraste provoqué par les régions blanches et sombres du globe oculaire, ainsi que les contours, pour estimer le centre de la pupille. Cela a produit de bien meilleurs résultats.

7
Totoro

Il suffit de remplacer la ligne où vous avez créé HoughCircles par ceci:

circles = cv2.HoughCircles(roi_gray2,cv2.HOUGH_GRADIENT,1,200,param1=200,param2=1,minRadius=0,maxRadius=0)

Je viens de changer quelques paramètres et cela me donne plus de précision.

Informations détaillées sur les paramètres ici .