[PYTHON] J'ai essayé de détecter l'iris à partir de l'image de la caméra

introduction

Nous avons résumé les présentations du 56th Computer Vision Study Group @ Kanto tenue le samedi 19 janvier 2020. Vous pouvez voir les documents de la journée sur ici.

Le code source est disponible sur le Github suivant. https://github.com/33taro/gaze_cv

À propos de la procédure de détection de l'iris

La détection irisée est un thème que j'étudiais quand j'étais à l'université, alors j'ai pensé que ce serait facile de le faire avec l'OpenCV avancé. La procédure est la suivante.

  1. Détection du visage humain et des points de repère faciaux à partir d'images de caméra
  2. Découpez le contour des yeux du repère sur le visage
  3. Binarisez le contour des yeux et extrayez la zone de l'iris
  4. Détection irisée de la région de l'iris extraite

虹彩検出手順.png

Détecter le visage et les repères faciaux d'une personne à partir d'images de caméra

J'ai essayé de détecter l'iris (partie des yeux au beurre noir) en utilisant la détection de repère du visage présentée dans Another article avant. Veuillez vous y référer pour plus de détails.

Découpez le contour des yeux du repère sur le visage

Comme présenté dans l'article ci-dessus, le repère du visage est [ici](https://ibug.doc.ic.ac.uk/ Nous utilisons le modèle entraîné dans resources / facial-point-annotations /). Par conséquent, l'œil droit est «n ° 37-42» et l'œil gauche est «n ° 43-48».

目領域.png

Ceci est décrit dans "eye_region_manager.py" dans le répertoire "tracking_system" dans le code source actuel.

eye_region_manager.py


    def detect_eye_region(self, face_landmark):
        """
Obtenez les coordonnées de la zone des yeux à partir du repère
        :param face_landmark:
        """
        #Découpe de l'œil droit
        self._right_eye_region = {'top_x': face_landmark[36][0], 'bottom_x': face_landmark[39][0],
                                  'top_y': face_landmark[37][1]
                                  if face_landmark[37][1] < face_landmark[38][1] else face_landmark[38][1],
                                  'bottom_y': face_landmark[41][1]
                                  if face_landmark[41][1] > face_landmark[40][1] else face_landmark[40][1]}

        #Découpe de l'œil gauche
        self._left_eye_region = {'top_x': face_landmark[42][0], 'bottom_x': face_landmark[45][0],
                                 'top_y': face_landmark[43][1]
                                 if face_landmark[43][1] < face_landmark[45][1] else face_landmark[45][1],
                                 'bottom_y': face_landmark[47][1]
                                 if face_landmark[47][1] > face_landmark[46][1] else face_landmark[46][1]}

Binariser le contour des yeux et extraire la zone de l'iris

La méthode P-tile a été utilisée pour binariser le contour des yeux. Il s'agit d'une méthode pour spécifier le pourcentage de la zone d'image que vous souhaitez binariser. En conséquence, l'iris pourrait être acquis quelle que soit la luminosité. (En règle générale, l'iris représente 40% du contour des yeux)

目領域の2値化.png

La méthode P-tile n'est pas implémentée dans OpenCV, je l'ai donc créée moi-même. Il est décrit dans "image_utility.py" dans le répertoire "utilitaire".

image_utility.py


# coding:utf-8

import cv2


def p_tile_threshold(img_gry, per):
    """
Traitement de binarisation par méthode de tuile P
    :param img_gry:Image en échelle de gris à binariser
    :param per:Pourcentage d'images à binariser
    :return img_thr:Image binarisée
    """

    #Obtenir l'histogramme
    img_hist = cv2.calcHist([img_gry], [0], None, [256], [0, 256])

    #Calculer le nombre de pixels à partir du rapport de l'image à binariser
    all_pic = img_gry.shape[0] * img_gry.shape[1]
    pic_per = all_pic * per

    #Calcul du seuil de binarisation par la méthode P-tile
    p_tile_thr = 0
    pic_sum = 0

    #Luminosité actuelle et somme de la luminosité(Ajouter par ordre décroissant de valeur)Calculs de
    for hist in img_hist:
        pic_sum += hist

        #Le traitement se termine lorsque la luminosité totale dépasse le rapport spécifié
        if pic_sum > pic_per:
            break

        p_tile_thr += 1

    #Processus de binarisation avec la valeur seuil obtenue par la méthode des carreaux P
    ret, img_thr = cv2.threshold(img_gry, p_tile_thr, 255, cv2.THRESH_BINARY)

    return img_thr

Détection irisée de la région de l'iris extraite

J'ai pu obtenir la zone de l'iris, mais je ne peux pas extraire uniquement l'iris proprement à cause des ombres des sourcils et des paupières. Par conséquent, la zone noire a été acquise par suivi des points de contour, ajoutée à chaque zone pour se rapprocher du cercle circonscrit, et le cercle avec le plus grand rayon a été utilisé comme iris.

虹彩の外接円近似.png

Une série de détection de binarisation-iris est décrite dans "eye_system_manager.py" dans le répertoire "tracking_system".

eye_system_manager.py


    @staticmethod
    def _detect_iris(eye_img):
        #Après échelle de gris, lissage avec filtre gaussien
        eye_img_gry = cv2.cvtColor(eye_img, cv2.COLOR_BGR2GRAY)
        eye_img_gau = cv2.GaussianBlur(eye_img_gry, (5, 5), 0)

        #Binarisation par méthode de tuile P
        eye_img_thr = p_tile_threshold(eye_img_gau, IRIS_PER)

        cv2.rectangle(eye_img_thr, (0, 0), (eye_img_thr.shape[1] - 1, eye_img_thr.shape[0] - 1), (255, 255, 255), 1)

        #Extraction de contour
        contours, hierarchy = cv2.findContours(eye_img_thr, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

        #Trouver l'iris du contour par le cercle circonscrit minimum
        iris = {'center': (0, 0), 'radius': 0}
        for i, cnt in enumerate(contours):
            (x, y), radius = cv2.minEnclosingCircle(cnt)
            center = (int(x), int(y))
            radius = int(radius)

            #Exclure des candidats iris si le rayon est trop grand
            if eye_img_thr.shape[0] < radius*0.8:
                # #Dessin de candidats iris
                # cv2.circle(eye_img, center, radius, (255, 0, 0))
                continue

            #Le cercle avec le plus grand rayon est reconnu comme un iris
            if iris['radius'] < radius:
                iris['center'] = center
                iris['radius'] = radius
                iris['num'] = i

        return iris

Résultat de détection irisé

demo.gif

Comme le montre la figure ci-dessus, les iris des yeux gauche et droit sont fermement acquis. Cependant, il y a encore des problèmes concernant le haut et le bas. Cependant, lorsqu'une personne regarde de haut en bas, elle bouge souvent son visage plutôt que de bouger son iris. (En fait, regarder de haut en bas avec juste vos yeux vous fatigue) Je me demande donc si je peux en quelque sorte détecter l'orientation du visage à partir des points de repère sur le visage.

Lien de référence

Suivi des points de contour

Cercle circonscrit minimum

Méthode de tuile P

Recommended Posts

J'ai essayé de détecter l'iris à partir de l'image de la caméra
J'ai essayé de couper une image fixe de la vidéo
J'ai essayé de corriger la forme trapézoïdale de l'image
J'ai essayé de compresser l'image en utilisant l'apprentissage automatique
J'ai essayé de déplacer le ballon
J'ai essayé d'estimer la section.
J'ai essayé de changer le script python de 2.7.11 à 3.6.0 sur Windows10
J'ai essayé d'obtenir diverses informations de l'API codeforces
J'ai essayé de trier les objets de l'image du plat de steak-④ Clustering
J'ai essayé de résumer la commande umask
J'ai essayé de reconnaître le mot de réveil
J'ai essayé de créer l'image de démarrage SD de LicheePi Nano
J'ai essayé de traiter l'image en "style croquis" avec OpenCV
J'ai essayé de résumer la modélisation graphique.
J'ai essayé d'estimer le rapport de circonférence π de manière probabiliste
J'ai essayé de toucher l'API COTOHA
J'ai essayé de traiter l'image dans un "style de dessin au crayon" avec OpenCV
J'ai essayé de jouer avec l'image avec Pillow
J'ai essayé de trier les objets de l'image du plat de steak-① Détection d'objets
J'ai essayé de trier les objets de l'image du plat de steak-② Tri des numéros de chevauchement
J'ai essayé de transformer l'image du visage en utilisant sparse_image_warp de TensorFlow Addons
J'ai essayé de déplacer l'image vers le dossier spécifié en faisant un clic droit et un clic gauche
J'ai essayé d'obtenir les résultats de Hachinai en utilisant le traitement d'image
J'ai essayé d'apprendre l'angle du péché et du cos avec le chainer
J'ai essayé de "lisser" l'image avec Python + OpenCV
J'ai essayé Web Scraping pour analyser les paroles.
J'ai essayé d'accéder à l'API Qiita depuis le début
J'ai essayé de "différencier" l'image avec Python + OpenCV
J'ai essayé d'optimiser le séchage du linge
J'ai essayé d'obtenir une image en grattant
J'ai essayé de sauvegarder les données avec discorde
J'ai essayé de détecter rapidement un mouvement avec OpenCV
J'ai essayé de "binariser" l'image avec Python + OpenCV
J'ai essayé de détecter un objet avec M2Det!
Qiita Job J'ai essayé d'analyser le travail
J'ai essayé d'utiliser le filtre d'image d'OpenCV
LeetCode j'ai essayé de résumer les plus simples
J'ai essayé de mettre en œuvre le problème du voyageur de commerce
J'ai essayé de vectoriser les paroles de Hinatazaka 46!
J'ai essayé de trier les objets de l'image du plat de steak --③ Image similaire Détection de carte de chaleur
J'ai essayé de déboguer.
J'ai essayé de trier les objets de l'image du plat de steak-⑤ Détection de point de fonction d'image similaire
J'ai essayé de résumer la relation entre les distributions de probabilité à partir de la distribution de Bernoulli
[Python] J'ai essayé de juger l'image du membre du groupe d'idols en utilisant Keras
[IBM Cloud] J'ai essayé d'accéder à la table Db2 on Cloud à partir de Cloud Funtions (python)
J'ai essayé d'extraire le dessin au trait de l'image avec Deep Learning
J'ai essayé de traiter et de transformer l'image et d'élargir les données pour l'apprentissage automatique
[Python] J'ai essayé d'obtenir le nom du type sous forme de chaîne de caractères à partir de la fonction type
J'ai essayé de passer le test G et la qualification E en m'entraînant à partir de 50
J'ai essayé d'automatiser le travail de masquage du visage de l'image de coordination pour l'usure
J'ai essayé d'entraîner la fonction péché avec chainer
J'ai essayé de représenter graphiquement les packages installés en Python
Je veux détecter des images de chats d'Instagram
J'ai essayé de résumer la forme de base de GPLVM
J'ai essayé de toucher un fichier CSV avec Python