Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
722 connectés 

  FORUM HardWare.fr
  Programmation
  Divers

  Automatiser détection faciale et numérotation d’une photo de groupe

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Automatiser détection faciale et numérotation d’une photo de groupe

n°2262311
Nessie3
Posté le 11-07-2015 à 14:53:16  profilanswer
 

Bonjour à tous,
J'ai un lot important de photos de groupes.  
Je souhaite numéroter automatiquement les personnes présentes sur la photos.  
En pièce jointe la photo avant / après.  
Quelqu'un saurait-il le faire ?
Peut-on automatiser la tâche avec un script dans Photoshop ou un autre logiciel ?
Le problème c'est de détecter le visage et de placer à proximité un numéro.
Merci d'avance
 
http://hpics.li/024c7af

mood
Publicité
Posté le 11-07-2015 à 14:53:16  profilanswer
 

n°2262312
honrisse
Posté le 11-07-2015 à 17:00:21  profilanswer
 

Nessie3 a écrit :

Bonjour à tous,
J'ai un lot important de photos de groupes.  
Je souhaite numéroter automatiquement les personnes présentes sur la photos.  
En pièce jointe la photo avant / après.  
Quelqu'un saurait-il le faire ?
Peut-on automatiser la tâche avec un script dans Photoshop ou un autre logiciel ?
Le problème c'est de détecter le visage et de placer à proximité un numéro.
Merci d'avance
 
http://hpics.li/024c7af


 
Bonjour,
 
Si le but est de détecter (pas de reconnaissance faciale, où l'on attribuerait un même numéro à la même personne) tous les visages sur une photo et placer à côté un numéro, si l'on sait programmer en C++, il y a la librairie OpenCV qui permet de le faire.
Il doit peut-être exister des programmes ou des scripts qui font ça, par exemple Picasa permet de tagger les visages.

n°2262313
Nessie3
Posté le 11-07-2015 à 17:09:48  profilanswer
 

honrisse a écrit :


 
Bonjour,
 
Si le but est de détecter (pas de reconnaissance faciale, où l'on attribuerait un même numéro à la même personne) tous les visages sur une photo et placer à côté un numéro, si l'on sait programmer en C++, il y a la librairie OpenCV qui permet de le faire.
Il doit peut-être exister des programmes ou des scripts qui font ça, par exemple Picasa permet de tagger les visages.


 
 
 
Le but est effectivement de détecter tous les visages sur une photo et de placer à coté de chaque visage un numéro différent sans aller plus loin (pas de reconnaissance faciale).
Visage n°1 --------> chiffre 1
...
Visage n°36 -------> chiffre 36
Picasa j'ai essayé mais je n'y suis pas arrivé.
Y aurait-il un informaticien prêt à développer le programme ?
Je suis prêt à le payer.

Message cité 2 fois
Message édité par Nessie3 le 11-07-2015 à 17:11:10
n°2262315
honrisse
Posté le 11-07-2015 à 20:59:16  profilanswer
 

Nessie3 a écrit :


 
 
 
Le but est effectivement de détecter tous les visages sur une photo et de placer à coté de chaque visage un numéro différent sans aller plus loin (pas de reconnaissance faciale).
Visage n°1 --------> chiffre 1
...
Visage n°36 -------> chiffre 36
Picasa j'ai essayé mais je n'y suis pas arrivé.
Y aurait-il un informaticien prêt à développer le programme ?
Je suis prêt à le payer.


 
 
La détection de visages d'OpenCV n'est pas parfaite:
http://reho.st/medium/self/35890e5227f6abc3844bd133659b5cc6898d5041.jpg
 
L'ordre des numéros n'est pas parfait non plus (sur cette photo c'est bon), et il peut y avoir des fausses détections pour les visages.
 
Voici le programme qui permet de le faire en ligne de commande. Et il faut aussi savoir programmer en C++ pour pouvoir compiler le source avec OpenCV.
Il y a des tutoriels sur le site d'OpenCV qui expliquent comment utiliser la librarie OpenCV.
 
Pour l'utiliser:

Code :
  1. -cascade <pour le chemin vers le fichier d'apprentissage pour la détection de visages>
  2. -image_list <chemin vers le fichier texte contenant les images à traiter, une ligne par chemin pour les images>
  3. -display <pour afficher le résultat en cours de traitement, appuyer sur une touche pour continuer quand la fenêtre est sélectionner>


 
Cela reste une preuve de faisabilité. Pour être vraiment utile, il faudrait rajouter toute l'interface autour du programme. Le programme détecte et labellise 95% des visages d'une photo, mais il faudrait une interface qui permettrait de supprimer les fausses détections, ajouter/éditer les numéros, etc.
 
Le code source:

Code :
  1. /**
  2.     This program is free software: you can redistribute it and/or modify
  3.     it under the terms of the GNU General Public License as published by
  4.     the Free Software Foundation, either version 3 of the License, or
  5.     any later version.
  6.     This program is distributed in the hope that it will be useful,
  7.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.     GNU General Public License for more details.
  10.     You should have received a copy of the GNU General Public License
  11.     along with this program.  If not, see <http://www.gnu.org/licenses/>
  12. **/
  13. #include <iostream>
  14. #include <algorithm>
  15. #include <fstream>
  16. #include <opencv2/opencv.hpp>
  17. #define DEBUG 0
  18. /**
  19. @author: Catree
  20. @date: 2015/07/11
  21. **/
  22. typedef struct face_info_t {
  23.   cv::Point face_center;
  24.   cv::Size face_size;
  25.   cv::Point label_center;
  26.   cv::Size img_size;
  27.   face_info_t() : face_center(), face_size(), label_center(), img_size()
  28.   {
  29.   }
  30.   face_info_t(const cv::Point &center, const cv::Size &size, const cv::Point &lbl_center, const cv::Size _img_size)
  31.   : face_center(center), face_size(size), label_center(lbl_center), img_size(_img_size)
  32.   {
  33.   }
  34.   bool operator<(const face_info_t& face_info) const
  35.   {
  36.   int top1 = (int) (face_center.y - face_size.height*0.5);
  37.   int bottom1 = (int) (face_center.y + face_size.height*0.5);
  38.   int top2 = (int) (face_info.face_center.y - face_info.face_size.height*0.5);
  39.   int bottom2 = (int) (face_info.face_center.y + face_info.face_size.height*0.5);
  40.   if( (top1 >= top2 && top1 <= bottom2) || (bottom1 >= top2 && bottom1 <= bottom2) ||
  41.    (top2 >= top1 && top2 <= bottom1) || (bottom2 >= top1 && bottom2 <= bottom1) )
  42.   {
  43.    return (face_center.x < face_info.face_center.x);
  44.   }
  45.   return (face_center.y < face_info.face_center.y);
  46.   }
  47. } face_info_t;
  48. std::vector<face_info_t> remove_same_faces(const std::vector<face_info_t> &vectorOfFaces)
  49. {
  50. std::vector<face_info_t> vectorOfUniqueFaces;
  51. std::vector<size_t> vectorOfDuplicateIndexes;
  52. for(size_t i = 0; i < vectorOfFaces.size(); i++)
  53. {
  54.  int top = (int) (vectorOfFaces[i].face_center.x - vectorOfFaces[i].face_size.width*0.5);
  55.  int left = (int) (vectorOfFaces[i].face_center.y - vectorOfFaces[i].face_size.height*0.5);
  56.  cv::Rect r1(top, left, vectorOfFaces[i].face_size.width, vectorOfFaces[i].face_size.height);
  57.  bool duplicate = false;
  58.  for(size_t j = i+1; j < vectorOfFaces.size(); j++)
  59.  {
  60.   if(std::find(vectorOfDuplicateIndexes.begin(), vectorOfDuplicateIndexes.end(), j) == vectorOfDuplicateIndexes.end())
  61.   {
  62.    top = (int) (vectorOfFaces[j].face_center.x - vectorOfFaces[j].face_size.width*0.5);
  63.    left = (int) (vectorOfFaces[j].face_center.y - vectorOfFaces[j].face_size.height*0.5);
  64.    cv::Rect r2(top, left, vectorOfFaces[i].face_size.width, vectorOfFaces[i].face_size.height);
  65.    cv::Rect r_intersection = r1 & r2;
  66.    if(r_intersection.width > 0 && r_intersection.height > 0)
  67.    {
  68.     duplicate = true;
  69.     vectorOfDuplicateIndexes.push_back(j);
  70.    }
  71.   }
  72.  }
  73.  if(!duplicate)
  74.  {
  75.   vectorOfUniqueFaces.push_back(vectorOfFaces[i]);
  76.  }
  77. }
  78. return vectorOfUniqueFaces;
  79. }
  80. void display_number(cv::Mat &img, const int number, const cv::Point &center, const cv::Size &label_box_size=cv::Size(30,30),
  81. const cv::Scalar label_box_bcg_color=cv::Scalar(255,255,255))
  82. {
  83. cv::Mat label_box(label_box_size, CV_8UC3);
  84. label_box.setTo(label_box_bcg_color);
  85. std::stringstream ss;
  86. ss << number;
  87. double factor = label_box_size.width / 30.0;
  88. if(number < 10)
  89. {
  90.  cv::putText(label_box, ss.str(), cv::Point(label_box.cols/2-6*factor, label_box.rows/2+5*factor), cv::FONT_HERSHEY_PLAIN, factor, cv::Scalar(0,0,0), 2);
  91. }
  92. else
  93. {
  94.  cv::putText(label_box, ss.str(), cv::Point(label_box.cols/2-10*factor, label_box.rows/2+5*factor), cv::FONT_HERSHEY_PLAIN, factor, cv::Scalar(0,0,0), 2);
  95. }
  96. label_box.copyTo(img(cv::Rect(center.x, center.y, label_box.cols, label_box.rows)));
  97. }
  98. void detect_faces_and_display_labels(cv::Mat &img, cv::CascadeClassifier &face_cascade, const bool display_result=false)
  99. {
  100.     std::vector<cv::Rect> faces;
  101.     face_cascade.detectMultiScale(img, faces);
  102. int size = std::min(img.rows, img.cols) / 24;
  103. cv::Size label_box_size(size, size);
  104. std::vector<face_info_t> vectorOfFaces(faces.size());
  105.     for (size_t i = 0; i < faces.size(); i++)
  106.     {
  107.         cv::Point center((int) (faces[i].x + faces[i].width*0.5), (int) (faces[i].y + faces[i].height*0.5));
  108. #if DEBUG
  109.         ellipse(img, center, cv::Size(faces[i].width*0.5, faces[i].height*0.5), 0, 0, 360, cv::Scalar(255, 0, 255), 2);
  110. #endif
  111.  cv::Point label_box(center.x - size/2, center.y + faces[i].height - size/2);
  112.  vectorOfFaces[i] = face_info_t(center, faces[i].size(), label_box, img.size());
  113.     }
  114. std::sort (vectorOfFaces.begin(), vectorOfFaces.end());
  115. vectorOfFaces = remove_same_faces(vectorOfFaces);
  116. int label = 1;
  117. for(std::vector<face_info_t>::const_iterator it = vectorOfFaces.begin(); it != vectorOfFaces.end(); ++it, label++)
  118. {
  119.  display_number(img, label, it->label_center, label_box_size);
  120. }
  121. if(display_result)
  122. {
  123.  cv::imshow("Image with tags", img);
  124.  std::cout << "Press a key to continue..." << std::endl;
  125.  cv::waitKey(0);
  126. }
  127. }
  128. cv::Mat read_image(const std::string &filepath)
  129. {
  130. cv::Mat img = cv::imread(filepath);
  131. return img;
  132. }
  133. void help()
  134. {
  135. std::cout << "Option: -h <print this help>" << std::endl;
  136. std::cout << "Option: -cascade <filepath for the cascade classifier learning file>" << std::endl;
  137. std::cout << "Option: -image_list <filepath for the text file containing the images to process>" << std::endl;
  138. std::cout << "Option: -display <display the result for each image>" << std::endl;
  139. }
  140. int main(int argc, char*argv[])
  141. {
  142. std::string casacade_filepath = "haarcascade_frontalface_alt2.xml";
  143. std::string image_list_filepath = "image_list.txt";
  144. bool display_result = false;
  145. for(int i = 1; i < argc; i++)
  146. {
  147.  if(std::string(argv[i]) == "-h" )
  148.  {
  149.   help();
  150.  }
  151.  else if(std::string(argv[i]) == "-cascade" )
  152.  {
  153.   if(i+1 < argc)
  154.   {
  155.    casacade_filepath = argv[i+1];
  156.   }
  157.  }
  158.  else if(std::string(argv[i]) == "-image_list" )
  159.  {
  160.   if(i+1 < argc)
  161.   {
  162.    image_list_filepath = argv[i+1];
  163.   }
  164.  }
  165.  else if(std::string(argv[i]) == "-display" )
  166.  {
  167.   display_result = true;
  168.  }
  169. }
  170. std::ifstream file(image_list_filepath.c_str());
  171. if(!file.is_open())
  172. {
  173.  std::cerr << "Problem with the filepath for the learning file !" << std::endl;
  174.  return -1;
  175. }
  176. std::string line;
  177. std::vector<std::string> vectorOfImageFilepaths;
  178. while(getline(file, line))
  179.     {
  180.  vectorOfImageFilepaths.push_back(line);
  181.     }
  182. cv::CascadeClassifier face_cascade;
  183. if(!face_cascade.load(casacade_filepath))
  184. {
  185.  std::cerr << "Problem with the filepath for cascade classifier learning file !" << std::endl;
  186.  return -1;
  187. }
  188. for(std::vector<std::string>::const_iterator it = vectorOfImageFilepaths.begin(); it != vectorOfImageFilepaths.end(); ++it)
  189. {
  190.  cv::Mat img = read_image(*it);
  191.  if(!img.empty())
  192.  {
  193.   std::string filenama_tagged = (*it) + "_tagged.jpg";
  194.   detect_faces_and_display_labels(img, face_cascade, display_result);
  195.   std::cout << "Save image: " << filenama_tagged << std::endl;
  196.   cv::imwrite(filenama_tagged, img);
  197.  }
  198.  else
  199.  {
  200.   std::cerr << "The image " << line << " cannot be read !" << std::endl;
  201.  }
  202. }
  203.     return 0;
  204. }


Message édité par honrisse le 11-07-2015 à 22:39:19
n°2262318
Nessie3
Posté le 11-07-2015 à 22:56:58  profilanswer
 

Super !
Ce n'est pas important si les numéros ne sont pas dans l'ordre et s'il y a de temps à autre de fausse détection.
Après il faudrait tester sur une cinquantaine de photos pour en déduire si la qualité de la détection est suffisante.
Pour moi j'ai des photos dans dossier source sur le disque dur et il faut mettre l'image numérotée dans un autre dossier, je n'ai pas besoin d'avoir une interface élaborée.
Je n'ai aucune connaissance en programmation.
Cela t'intéresse-t-il de finaliser ce projet ?
On se met d'accord sur un prix ?

n°2262331
bardiel
Debian powa !
Posté le 12-07-2015 à 17:58:08  profilanswer
 

Nessie3 a écrit :

Je n'ai aucune connaissance en programmation.
Cela t'intéresse-t-il de finaliser ce projet ?
On se met d'accord sur un prix ?


Citation :

On ne fait pas le boulot à votre place.
 
o  Les demandes du style "vous pouvez faire un programme faisant [...] pour moi ?" sont assez mal vues et ne sont pas dans l'esprit de la catégorie. Le but de la catégorie étant de vous aider dans vos problèmes de programmation, toute demande de travail tout fait sera modérée.
o  Les offres d'emploi et recrutements doivent être postées sur Emploi & Études, même si elles concernent des jobs de programmation.


---------------
Grippe ? Coronavirus ? Portez votre masque correctement ! :D
n°2262332
Nessie3
Posté le 12-07-2015 à 18:03:39  profilanswer
 

bardiel a écrit :


Citation :

On ne fait pas le boulot à votre place.
 
o  Les demandes du style "vous pouvez faire un programme faisant [...] pour moi ?" sont assez mal vues et ne sont pas dans l'esprit de la catégorie. Le but de la catégorie étant de vous aider dans vos problèmes de programmation, toute demande de travail tout fait sera modérée.
o  Les offres d'emploi et recrutements doivent être postées sur Emploi & Études, même si elles concernent des jobs de programmation.



 
 
 
Je ne propose pas une offre d'emploi !
Voilà je suis confronté à un problème et j'essaie de le résoudre.

n°2262339
Modération
Posté le 12-07-2015 à 23:25:26  answer
 

Nessie3 a écrit :

Y aurait-il un informaticien prêt à développer le programme ?
Je suis prêt à le payer.

Les offres d'emploi, ce n'est pas dans cette section!
 


Aller à :
  FORUM HardWare.fr
  Programmation
  Divers

  Automatiser détection faciale et numérotation d’une photo de groupe

 

Sujets relatifs
[résolu] Affichage de photo avec IF sur base[BATCH] Pb numérotation de fichiers
Reproduire ligne avec plusieurs Cases d'option/Zone de groupe ET Macro[Selenium IDE] Comment automatiser les tests ?
Aide:extraire un groupe de données depuis un groupe de fichiersphoto ne veux pas se mettre dans ma page
Automatiser StackedBar vb.netImpression automatiser avec différents type de fichiers
changer la couleur d'un cadre de photo dans flashautomatiser la synchronisation de 2 base de donnée mysql et oracle
Plus de sujets relatifs à : Automatiser détection faciale et numérotation d’une photo de groupe


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR