IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

OpenCV Discussion :

Filtre sur image d'un œil


Sujet :

OpenCV

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    422
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 422
    Par défaut Filtre sur image d'un œil
    Bonjour,

    Je dois detecter l'etat d'un oeil à savoir si celui-ci est fermé ou pas.

    Pour le moment, j'ai déja testé plusieurs algorithmes que j'ai implémenté (sans utiliser openCV) pour tenter de detecter cela mais le résultat n'est pas très frutctueux :/

    J'ai utilisé la transformé de Hough (avec Sobel au préalable) pour détecter l'iris mais le soucis est qu'il me trouve toujours un cercle même quand l'oeil est fermé. De plus, je ne connais pas forcément le rayon de l'iris mais juste une estimation, donc pas évident ...

    Pour info, je ne cherche pas forcément à détecter et entourer l'iris mais seulement si l'oeil est ouvert ou fermé.

    De coup j'ai aussi testé le filtre Canny mais là encore, le résultat est souvent aléatoire et dépend de la qualité de l'image et de sa luminosité.

    Ce qu'il me faudrait, c'est un filtre de thresohld efficace comme sur cette video :


    Il arrive à laisser que le blanc de l'iris lorsque l'oeil est ouvert et sinon l'image est noire lorsque l'oeil est fermé Je ne sais pas trop quel filtre utilisé pour cela

    Si vous avez une idée je suis vraiment preneur

    Merci d'avance

  2. #2
    Membre éclairé Avatar de GabrielD
    Homme Profil pro
    ingénieur de recherche
    Inscrit en
    Août 2009
    Messages
    52
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur de recherche

    Informations forums :
    Inscription : Août 2009
    Messages : 52
    Par défaut
    as tu essayé de chercher une zone blanche correspondant à l'oeil?
    tu peux par exemple chercher un cercle avec une composante tres foncée à l’intérieur et très clair à l'extérieur. (en jouant avec les espaces de couleurs pour trouver celui qui convient le mieu)
    Sinon jette une coup d'oeil ici:
    http://opencv.itseez.com/opencv_tutorials.pdf (p.291)

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    422
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 422
    Par défaut
    Gabriel, désolé pour le retard de réponse et merci pour ton aide.

    as tu essayé de chercher une zone blanche correspondant à l'oeil?
    tu peux par exemple chercher un cercle avec une composante tres foncée à l’intérieur et très clair à l'extérieur. (en jouant avec les espaces de couleurs pour trouver celui qui convient le mieu)
    Non pas vraiment, j'ai essayé d'appliquer cet algorithme mais là encore, ce n'est pas très concluant.

    Peut-tu m'indiquer comment rechercher un cercle qui aurait les caractéristiques que tu décrit, car ça me semble pas mal comme solution (si elle est applicable...) ?

  4. #4
    Membre éclairé Avatar de GabrielD
    Homme Profil pro
    ingénieur de recherche
    Inscrit en
    Août 2009
    Messages
    52
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur de recherche

    Informations forums :
    Inscription : Août 2009
    Messages : 52
    Par défaut
    Les cercles se détectent avec houghcircle() par exemple. Ensuite à toi de faire des routines qui analyses les pixels extérieurs et intérieurs des cercles.

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    422
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 422
    Par défaut
    Alors j'ai essayé HoughCircle de opencv mais il ne me renvoie aucun cercle !

    Je pré-process l'image en niveau de gris puis en filtre median.

    Ensuite je lui envoi cela (attention, j'utilise opencv4android, donc c'est du java) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Imgproc.HoughCircles(imgSource, imgCirclesOut, Imgproc.CV_HOUGH_GRADIENT, 1, 10, 150, 75, (int)rayon-10, (int)rayon+10);
    Mon inspiration vient de ce post

    Mais imgCirclesOut ne renvoi jamais rien...

    Mes paramètres sont peut-être mauvais

    Une idée ?

  6. #6
    Membre éclairé Avatar de GabrielD
    Homme Profil pro
    ingénieur de recherche
    Inscrit en
    Août 2009
    Messages
    52
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur de recherche

    Informations forums :
    Inscription : Août 2009
    Messages : 52
    Par défaut
    Binarise ton image d'abord.
    utilise la fonction threshold

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    422
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 422
    Par défaut
    Voici ce que j'ai fait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
    bmpSource = ImageUtils.JPEGtoRGB888(bmpSource );
     
    Mat imgSource = new Mat(), imgCirclesOut = new Mat();
     
    Utils.bitmapToMat(bmpSource , imgSource); 
     
    //grey opencv
    Imgproc.cvtColor(imgSource, imgSource, Imgproc.COLOR_BGR2GRAY);
     
    Imgproc.GaussianBlur( imgSource, imgSource, new Size(9, 9), 2, 2 );
    Imgproc.HoughCircles( imgSource, imgCirclesOut, Imgproc.CV_HOUGH_GRADIENT, 1, imgSource.rows()/8, 200, 100, 0, 0 );
     
    float circle[] = new float[3];
    Log.w("circles", imgCirclesOut.cols()+""); // Renvoi tjrs 0 !!!!!!
     
    for (int i = 0; i < imgCirclesOut.cols(); i++)
    {
    	imgCirclesOut.get(0, i, circle);
    	org.opencv.core.Point center = new org.opencv.core.Point();
    	center.x = circle[0];
    	center.y = circle[1];
    	Core.circle(imgSource, center, (int) circle[2], new Scalar(255, 255, 0,	255), 4);
    }
     
    Bitmap bmp = Bitmap.createBitmap(bmpSource.getWidth(), bmpSource.getHeight(), Bitmap.Config.ARGB_8888);
     
    Utils.matToBitmap(imgSource, bmp);
    Je me suis inspiré de ceci pourtant (docs officielle).

    Malgré cela, imgCirclesOut.cols() est toujours égale à 0...

  8. #8
    Membre éclairé Avatar de GabrielD
    Homme Profil pro
    ingénieur de recherche
    Inscrit en
    Août 2009
    Messages
    52
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur de recherche

    Informations forums :
    Inscription : Août 2009
    Messages : 52
    Par défaut
    En réalité je n'ai jamais implémenté de houghcircle mais as-tu testé ton code sur des images plus simple (un cercle par exemple?)

  9. #9
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    422
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 422
    Par défaut
    Alors oui en fait tu as raison, j'ai réussit a détecter le contour d'un cercle de couleur unie sur fond blanc ... Cool !

    Mais du fait que mon image est plus compliquée (un œil humain), je crois que ça ne passe pas ...

    Il faudrait que j'utilise des filtres probablement auparavant, ou même ajuster les paramètres de Canny de cette méthode HoughCircle().

    Mais du fait que je ne m'y connais pas vraiment en traitement d'image, vos conseils avisés en la matières me serait d'une grande aide

  10. #10
    Membre éclairé Avatar de GabrielD
    Homme Profil pro
    ingénieur de recherche
    Inscrit en
    Août 2009
    Messages
    52
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur de recherche

    Informations forums :
    Inscription : Août 2009
    Messages : 52
    Par défaut
    Essaie de jouer un peu:
    integre des trackbar pour tous les paramètres et modifie les à la volé en affichant les résultats.
    C'est très utiles pour comprendre et même régler tes paramètres

  11. #11
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    422
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 422
    Par défaut
    Ok merci de ton aide, je vais voir tout ça

  12. #12
    Membre confirmé
    Inscrit en
    Février 2011
    Messages
    32
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 32
    Par défaut
    Quelque chose qui peut être pas mal et que j'ai déjà utilisé : cvMatchTemplate().
    Tu utilises une image d'iris comme Template, et tu passes sur l'image pour le repérer. S'il n'y en a pas, l'oeil est fermé (ou hors de la caméra). Le mieux, c'est de pouvoir récupérer l'iris de l'utilisateur comme template, mais tu peux aussi créer ton template d'avance.

  13. #13
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    422
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 422
    Par défaut
    Bonjour Pseudopode et merci pour ton aide

    Je suis entrain de regarder du coté de MatchTemplate() et ça à l'air effectivement séduisant comme solution

    Voici l'appel à ma fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Imgproc.matchTemplate(mFace, mEye, mResult, Imgproc.TM_SQDIFF);
    Core.MinMaxLocResult mmres =  Core.minMaxLoc(mResult);
    (Ma source d'inspiration ici (cf dernière réponse de Roman)).

    Bref, j'ai comprit que "mmres" me renvoyait 2 points : minLoc et maxLoc mais je n'ai pas bien saisit à quoi correspondent-ils ? De plus, j'ai l'impression que même si ça ne doit pas matcher, il renvoit quand même ces 2 points ...

    J'aurai une 2e question, à savoir si il fallait utiliser un filtre avant le match, si oui lequels (niveau de gris, filtre median, ... ?), et si il fallait filtrer aussi bien la source que la template ou l'une des 2 seulement ?

    Encore merci pour ton aide !

  14. #14
    Membre confirmé
    Inscrit en
    Février 2011
    Messages
    32
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 32
    Par défaut
    Tu n'as pas de filtrage en particulier à faire sur aucune des deux images, pour que le filtrage fonctionne (dans tous les cas, si tu fais un filtrage sur une des 2 images, mais pas sur l'autre, tu vas empêcher la détection de se faire).
    Un soucis que tu peux rencontrer, c'est si tu prends un template de l'oeil de l'utilisateur à une heure donnée, (par exemple tôt le matin), et que tu cherches à faire un matching plus tard dans la journée, tu peux avoir un changement de luminosité très important. Parfois suffisant pour faire complètement planter la recherche, alors que tu sais que l'oeil est là.

    C'est pour ça que je faisais une détection de l'oeil grossière avec les filtres fournis par OpenCV (les mêmes qui servent à détecter la tête). Une fois l'oeil détecté, je prenais le centre de la ROI détecté, et j'y découpais un carré d'un vingtaine ou une trentainre de pixels de côté. Cela me servait de template.

    Je ne me souviens plus bien des détails du MatchTemplate, mais si je me rappelle bien, c'est une autocorrelation, tu obtiens donc le point de corrélation minimale, et le point de corrélation maximale (à confirmer).
    Je me souviens par contre qu'il y a un paramètre qui te permet de paramétrer la recherche de corrélation (normalisée, non-normalisée, etc...)
    Comme le calcul de corrélation se fait sur toute l'image et te renvoit un "score" pour chaque pixel, tu dois établir un seuil à partir duquel tu vois un matching. Tu dois faire une série de tests pour savoir à partir de quel seuil cela a un sens dans ton expé.
    L'idéal, c'est d'avoir un template où tu ne gardes que l'iris. En effet, la déformation de celui ne sera que géométrique (quand l'oeil va bouger dans le plan), par contre si tu prends le bord des paupières, la déformation sera plus complexe (les muscles vont déformer le tour de l'oeil).

  15. #15
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    422
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 422
    Par défaut
    Merci Pseudopode pour ton aide précieuse ! Je viens aux nouvelles

    Alors ça avance mais je rencontre effectivement certaines difficultés ...

    Citation Envoyé par Pseudopode Voir le message
    Tu n'as pas de filtrage en particulier à faire sur aucune des deux images, pour que le filtrage fonctionne (dans tous les cas, si tu fais un filtrage sur une des 2 images, mais pas sur l'autre, tu vas empêcher la détection de se faire).
    Tout à fait ! Du coup, je ne met qu'un niveau de gris dans les 2 pour uniformiser et cela suffit je penses

    Citation Envoyé par Pseudopode Voir le message
    Un soucis que tu peux rencontrer, c'est si tu prends un template de l'oeil de l'utilisateur à une heure donnée, (par exemple tôt le matin), et que tu cherches à faire un matching plus tard dans la journée, tu peux avoir un changement de luminosité très important. Parfois suffisant pour faire complètement planter la recherche, alors que tu sais que l'oeil est là.
    C'est justement la difficulté que je rencontre ... Si je prends mon oeil dans une luminosité ambiante claire et que je teste cela sur une luminosité sombre, ça ne fonctionne plus

    Citation Envoyé par Pseudopode Voir le message
    C'est pour ça que je faisais une détection de l'oeil grossière avec les filtres fournis par OpenCV (les mêmes qui servent à détecter la tête). Une fois l'oeil détecté, je prenais le centre de la ROI détecté, et j'y découpais un carré d'un vingtaine ou une trentainre de pixels de côté. Cela me servait de template.
    Ok, mais personne ne te dis que lorsque tu effectue un changement de template référant de l'oeil, celui-ci représente un oeil ouvert ou fermé et du coup, tu ne sais plus si ce que tu match est un oeil ouvert ou fermé...

    Citation Envoyé par Pseudopode Voir le message
    L'idéal, c'est d'avoir un template où tu ne gardes que l'iris. En effet, la déformation de celui ne sera que géométrique (quand l'oeil va bouger dans le plan), par contre si tu prends le bord des paupières, la déformation sera plus complexe (les muscles vont déformer le tour de l'oeil).
    Tu as raison mais je pense que pour mon cas, c'est encore plus simple de partir d'un template oeil fermé, car il ya moins de chance de se tromper (tant que ça ne match pas ==> oeil ouvert), qu'en penses-tu ?

  16. #16
    Membre confirmé
    Inscrit en
    Février 2011
    Messages
    32
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 32
    Par défaut
    Pour s'assurer que la détection fonctionne malgré les différences de luminosité, il faut faire une normalisation de tes images (celle de départ, le template), comme celles contre lesquelles tu testes.
    Pour cela, tu peux déjà faire une balance des blancs sur toutes les images. Tu dois avoir moyen d'étaler le spectre des couleurs de l'image (l'histogramme de couleur), pour qu'il couvre l'intégralité des valeurs disponibles (il y a les fonctions qu'il faut dans OpenCV pour accéder à cet histogramme).
    Ceci fait, tu peux ensuite changer de mode de représentation des couleurs pour s'abstraire des différences d'éclairage.
    Le HSV est pas mal pour ça.
    Tu prends donc ton image en RGB, tu l'égalises, comme expliqué au-dessus, tu la passes en HSV (ou HSL, c'est pareil pour notre cas), et ensuite de cette image HSV, tu fais un Grayscale. Dans ce cas précis, je te conseille d'écrire toi-même ta boucle de passage couleurs_HSL -> Grayscale, car la fonction RGB vers gris d'OpenCV est optimisée pour la perception des couleurs de l'oeil humain (ce n'est donc pas une bête moyenne des 3 canaux, mais une moyenne pondérée, ce qui casserait complètement dans le cas d'un passage HSV vers gris).
    Tu peux, pour cette conversion, faire un passage sur tes 3 canaux H, S et L, et faire la moyenne dans une nouvelle IplImage à un seul canal, qui serait ton image "HSV en niveau de gris".

    Les cascades de Haar dispnibles avec OpenCV pour détecter l'oeil correspondent à un oeil ouvert. Donc si tu veux construire automatiquement un template automatiquement, ça sera forcément un template d'oeil ouvert.

    Si tu sais que tu disposes d'une image d'oeil fermé, alors tu peux construire un template d'oeil fermé, ça sera effectivement simple.

    Tu peux également détecter l'action de clignement de l'oeil à l'aide d'un calcul de flot optique à l'intérieur de la zone détectée correspondante à la tête, puisque sur une personne normalement constituée, c'est le seul mouvement qui s'effectue sur le visage. Pour ce faire, tu dois évidemment normaliser tes images encore une fois.

    Tu peux, au final, faire aussi une soustraction entre deux images de visage (centrées et normalisées). Si une des images a l'oeil ouvert, et l'autre l'oeil fermé, tu n'es censé voir apparaître qu'un seul gros "blob", qui correspond à la différence entre les deux, pixel-par-pixel.

    Par contre, ces deux dernières méthodes, bien que rapides, sont moins robustes.

  17. #17
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    422
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 422
    Par défaut
    Merci pseudopode pour ton dévouement

    Alors, je suis entrain d'essayer de mettre en place pour le moment, la première solution que tu cites.

    Donc:
    1 - j'ai ajouté en paramètre de la camera le mode 'auto' pour la balance des blancs
    2 - j'ai réussi à trouver l'équivalent du passage RGB (en code java, version opencv4android)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Imgproc.cvtColor(mEyeRGB, mEyeHSV, Imgproc.COLOR_RGB2HSV_FULL, 0);
    (Bien qu'il y ait plusieurs autres options pour le 3e paramètres comme Imgproc.COLOR_RGB2HSV qui me mettent le doute ...)

    Bref, ok.

    Par contre, je n'ai pas bien saisi comment : en partant de mEyeHSV, je dois lui appliquer un grayscale ?

    Il faut pour cela, récupérer chaque canal HSV de mEyeHSV (ça c'est ok pour moi, grâce à ce post de Andrey Pavlenko :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Imgproc.cvtColor(mRgba, mhsv, Imgproc.COLOR_RGB2HSV_FULL, 0);
    List<Mat> lhsv = new ArrayList<Mat>(3);
    Core.split(mhsv, lhsv);
    Mat mh = lhsv.get(0); //==> H
      //Mat ms = lhsv.get(1); //==> S
      //Mat mv = lhsv.get(2); //==> V
    )

    Et ensuite, ma question est de savoir comment en faire la moyenne et créer une image greyscal à un seul canal ?


    Sinon, je suis aussi très intéressé par ta 3e solution qui est la soustraction d'image et j'aimerai aussi m'y penché ( après l'essai de la première solution... ) ...

    Merci encore de ton aide

  18. #18
    Membre confirmé
    Inscrit en
    Février 2011
    Messages
    32
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 32
    Par défaut
    Imgproc.COLOR_RGB2HSV m'a l'air bien suffisant .

    Une image Grayscale, c'est tout simplement une image à un seul canal, quel que soit la provenance de ce canal (ainsi, après avoir fait un RGB -> HSV, tu peux faire un cvSplit() et ne garder qu'une seul des 3 images ainsi obtenue - la luminance, si je me souviens bien sera celle qui porte le plus d'infos).

    Pour la soustraction de deux images à 1 seul canal, il y a des fonctions déjà prévues dans OpenCV pour ça.

    Bon courage .

Discussions similaires

  1. Filtre sur image trop importante
    Par lucazzo dans le forum Macros et VBA Excel
    Réponses: 12
    Dernier message: 21/06/2008, 15h23
  2. appliquer des filtres sur image
    Par MANU_2 dans le forum Débuter
    Réponses: 1
    Dernier message: 10/01/2008, 12h02
  3. Filtres sur image
    Par ironzorg dans le forum SDL
    Réponses: 12
    Dernier message: 08/07/2007, 15h36
  4. filtre alpha sur image
    Par nicerico dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 18/05/2007, 22h35
  5. Filtre sur image compatible I.E
    Par sacados1 dans le forum Mise en page CSS
    Réponses: 3
    Dernier message: 13/03/2007, 13h57

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo