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

C# Discussion :

Suppression de couleur d'une image


Sujet :

C#

  1. #1
    Nouveau membre du Club
    Inscrit en
    Novembre 2009
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 59
    Points : 27
    Points
    27
    Par défaut Suppression de couleur d'une image
    Bonjour tout le monde, mon problème est simple à comprendre mais pas simple à résoudre...

    Je travaille avec un ocr (tesseract) puis pour avoir de meilleur résultat je veux supprimer la couleur de fond de mes bulletins de versement, j'ai le code hexa,rgb,etc des couleurs qu'il faut que je supprime mais je ne sais pas comment interagir avec ça ...

    Ou de simplement garder une seule couleur (noire) ...

    Est-ce que quelqu'un aurait une soluce à me passer.. ??

    Yep LilMemt.

  2. #2
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2011
    Messages
    141
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2011
    Messages : 141
    Points : 201
    Points
    201
    Par défaut
    Quand tu parles de ne garder que du noir, est-ce qu'une conversion en noir et blanc te suffirait ?

  3. #3
    Nouveau membre du Club
    Inscrit en
    Novembre 2009
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 59
    Points : 27
    Points
    27
    Par défaut
    Salut, regarde mon autre post,

    http://www.developpez.net/forums/d12...emgucv-csharp/

    avec la dernière image je n'ai aucun soucis, les autres oui...et pas mal même... donc je me dis que si j'arrive à supprimer le "rose" et ensuite à appliquer un masque pour utiliser que les parties qui m'intéresse j'aurais beaucoup moins de soucis avec l'OCR, vu que dans mon projet je dois faire via une webcam...

  4. #4
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Bonjour.

    Non seulement je doute fort que remplacer un fond quasiment blanc par du blanc change beaucoup la donne mais en plus en faisant cette opération tu vas dégrader la qualité de ton image ce qui peut rendre plus difficile la reconnaissance de caractères. Sauf si ton OCR est optimisé pour du bitonal, auquel cas tu devrais transformer ton image de façon appropriée. Est-ce le cas ?

    Qui plus est tu pars aujourd'hui sur des masques. Mais as-tu une idée de comment tu appliqueras ces masques sur des feuilles déformées par une perspective et qui ne sont pas tenues à angle droit ?

    Enfin tu utilises Tesseract OCR. Celui-ci est-il adapté à ton problème (reconnaissance de nombres uniquement, imprimés et non écrits à la main) ? Je ne connais pas suffisamment les solutions OCR pour t'en recommander une mais chacune à ses spécificités, il n'y en n'a pas une meilleure en tout. J'imagine qu'un système que tu pourrais entraîner toi-même pour la fonte spécifique utilisée ici, et qui sache s'adapter aux perspectives, et capable de te retourner un score de fiabilité, serait plus indiqué. D'autant que dans l’analyse de chiffres on ne peut pas vérifier si le mot est cohérent et fait sens par rapport au reste de la phrase. Qui plus est tu n'as pas besoin de te restreindre aux OCR pour dotnet : au pire tu n'auras qu'à ajouter cinq imports de fonction et ce ne sera pas la mort.

  5. #5
    Nouveau membre du Club
    Inscrit en
    Novembre 2009
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 59
    Points : 27
    Points
    27
    Par défaut
    Salut DonQuiche,

    Le fond est un rose, couleur peau.

    Alors Tesseract-OCR marche bien sur une image fixe, donc que j'ai loadé. J'arrive à récupérer le n°compte,n° de référence,montant, et le numéro préimprimé, grâce auxquels je fais un algorithme de sécurité pour être sûre que tout est correct.

    Sur une image, modifié avec gimp, où je n'ai que ces numéros affichés,mais à leur emplacement de base, je n'ai aucun soucis.

    Tesseract est un ocr alphanumérique.

    Puis pour le problème de perspective, je proposerai à l'utilisateur de poser le bvr sur une surface plate et bien éclairé, sinon ça ne va pas bien récupérer les données. Justement si les données sont mal récupérées, grâce à mon algorithme je peux avertir l'utilisateur de recommencer le scan.

    Mais c'est justement au niveau du flux d'image que je bloque et aussi niveau détection des webcam automatisé ainsi que de récupérer leurs meilleures résolutions..

    voila toutes les infos que tu voulais, j'espère que tu pourras m'aider et Merci encore !

  6. #6
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Tesseract est surtout un OCR créé pour du texte imprimé ou cunéiforme : c'est à dire avec des mots, des phrases, et plusieurs milliers de signes. Il parcourt le texte, apprend au fur et à mesure à reconnaître la police ou l'écriture en déduisant que "j2 n0nle l3 ckev4l" n'est pas correct et qu'il doit plutôt s'agir de "je monte le cheval". Autrement dit, il n'est pas du tout prévu pour ton cas. Alors, certes, il peut arriver à tirer son épingle du jeu si tu lui présentes un document scanné en haute résolution, avec une fonte assez régulière, bien droit, uniformément éclairé, pour te présenter un résultat à 90% correct que tu parviens à corriger en remplaçant manuellement les "k" par des "4" et compagnie.

    Mais ça reste de la bidouille pour un résultat contraignant pour l'utilisateur et je voudrais savoir si tu as fait des tests avec des images prises depuis des webcams plus ou moins bonnes, en situations réelles, sous divers éclairages, quitte à transformer l'image sous Gimp avec des filtres qu'on peut reproduire, avant de t'aventurer plus loin. Si ça fonctionne, ok, ça vaut le coup qu'on discute du reste. Sinon, inutile d'aller plus loin, ça veut tout simplement dire que Tesseract ne fera pas l'affaire et il faut reprendre les choses depuis le départ.

    Désolé si je suis décourageant mais mieux vaut regarder la réalité en face : tu as l'air d'avoir pris le premier OCR venu, de ne pas t'être renseigné dessus (meilleur en bitonal ou non ? As-tu recompilé avec les flags qui te convenaient ?), de ne pas avoir testé sa capacité à faire le travail, etc. Et dans ce cas ce sera la catastrophe au dernier moment avec 90% du boulot à jeter et refaire. Si c'est le cas je préfère risquer d'avoir été le mec désagréable au cas où je pourrais être celui qui t'aura empêché de te tirer une balle dans le pied.

  7. #7
    Nouveau membre du Club
    Inscrit en
    Novembre 2009
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 59
    Points : 27
    Points
    27
    Par défaut
    Alors pourquoi Tesseract ? tout simplement parce que le prof m'a "conseillé" d'utiliser EmguCV qui intègre Tesseract, EmguCV est une dérivée d'OpenCV pour C#...

    Ensuite j'ai essayé avec des images de webcam mais ça bug pas mal dû à la luminosité de la salle..

    Demain je ramène une lampe de bureau afin d'avoir une meilleure résolution pour avoir moins de bug...

    Parce que moi je dois seulement récupérer des nombres ainsi que un caractère "+" et deux ">" ...

    Merci encore de ton soutien et de ton aide, et non tu ne me décourage pas !

  8. #8
    Nouveau membre du Club
    Inscrit en
    Novembre 2009
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 59
    Points : 27
    Points
    27
    Par défaut
    alors j'ai réussi à avancer un peu dans mon projet, je n'ai plus besoin de remplacer les K par des 4 etc... j'avais fait une erreur au niveau du moteur OCR... ça marche directement beaucoup mieux, mais ce n'est pas encore assez précis...

  9. #9
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    J'ai été me renseigner un peu sur Tesseract. En trente minutes (le sujet était assez intéressant), je suis parvenu à apprendre que :
    * Les images présentées à Tesseract doivent être bitonales (filtre passe-haut nécessaire) et droites (détection de la déformation, sans doute via une détection des bords, pour ensuite appliquer un deskewing). Si l'image est prise depuis une webcam on cherchera sans doute à l'agrandir au préalable pour éviter la perte de trop d'informations. EgmuCV propose des outils pour certaines de ces opérations et un exemple intéressant dont la qualité est toutefois insuffisante pour de la production ("this system is not robust and recognition accuracy might be low").
    * Il est possible d'entraîner Tesseract dans sa dernière version pour reconnaître une fonte spécifique. L'API exposée par EgmuCV semble trop limitée pour ça, il faudrait peut-être créer son propre wrapper. Dix ou vingt formulaires semblent suffir.
    * Tesseract dispose de plus d'une centaine d'options. Un bon livre s'impose !
    * Le logiciel doit être capable d'évaluer s'il a réussi ou non pour solliciter éventuellement l'utilisateur. Tesseract offre notamment des scores de pertinence de la reconnaissance.

  10. #10
    Nouveau membre du Club
    Inscrit en
    Novembre 2009
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 59
    Points : 27
    Points
    27
    Par défaut
    tout d'abord merci de prendre de ton temps libre pour moi, c'est vraiment sympa !

    -Pour l'OCR en fait j'ai une police spéciale, propre aux bulletins de versements, mais je ne sais pas comment l'utiliser avec l'API tesseract d'Emgu ... Puis qu'est-ce qu'un "wrapper" ??

    - Pour le score de pertinence de la reconnaissance, je n'étais pas au courant que ça existait ... Peux-tu m'indiquer dans quelle méthode ça se trouve ?

    Merci encore DonQuiche !

  11. #11
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Bonjour.

    Pour entraîner Tesseract, leur wiki offre un guide dédié à la version 3. EmguCV utilise la version 3.0. L'idée est de spécialiser Tesseract pour ta police et les quelques caractères qui t'intéressent, ce qui facilitera son boulot.

    Par "wrapper" je voulais dire une biblio qui fournit une API dotnet autour de la biblio native via p/invoke. C'est ce que fait déjà Emgu sauf qu'ils n'ont apparemment importé qu'une partie de la biblio. Il semble qu'il existe un wrapper complet. En revanche il sera plus fastidieux de faire collaborer Tesseract et Emgu, à voir donc si les fonctionnalités supplémentaires sont bien nécessaires. Encore une fois on en revient au fait qu'il faut bien connaître Tesseract si l'on veut obtenir de lui les meilleurs résultats sous des éclairages faiblards avec des webcams moisies et des feuilles pas droites.

    Enfin Tesseract offre deux façons d'obtenir les résultats : l'une retourne le texte entier, l'autre une séquence de blocs appelés "charactors" qui donnent pour chacun le texte du bloc, son rectangle et sa pertinence. Via Emgu cela passe par Tesseract.GetCharactors() (voir doc Emgu). Cela te dispense aussi d'appliquer des masques comme tu le faisais : il te suffira à la place d'examiner le rectangle de chaque bloc de résultats. Quant aux textes couleur saumon qui n'ont pas la même police que ceux qui t'intéressent, ils seront de toute façon éliminés avant cela par le filtrage de l'image.

  12. #12
    Nouveau membre du Club
    Inscrit en
    Novembre 2009
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 59
    Points : 27
    Points
    27
    Par défaut
    Voilà mon bout de code pour l'OCR, en fait il faut juste que je trouve comment utiliser la police fournie... Donc j'utilise GetCharactors().

    Puis Tesseract supprime automatiquement les parties non-texte de la frame. Donc ce qui m'évite de devoir couper l'image etc, mais le problème c'est que même de cette manière il me récupère les noms,adresses etc.. ce dont je n'ai pas besoin, et j'aimerais trouver une soluce sans devoir filtrer toutes les données, simplement en prenant les parties en bas à droite en gros... mais je ne vois vraiment pas comment faire..

    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
     public void Recognizer()
          {
              Bgr drawColor = new Bgr(Color.Blue);
              try
              {
                  using (GrayFrame)
                  {
                       _ocr.Recognize(BackImage);
                      Tesseract.Charactor[] charactors = _ocr.GetCharactors();
                      foreach (Tesseract.Charactor c in charactors)
                      {
                          BackImage.Draw(c.Region, drawColor, 1);
                      }
                      String text = _ocr.GetText();
     
                      label1.Text = text;
                      //Coupe les données reçues
                      string[] lines = Regex.Split(text, "\n");                             //coupe par ligne et met un retour à la ligne
     
                      strRef = lines[0];
                      string strRef1 = strRef.Replace(" ", "");            //Variable Reference pour le test de sécurité
     
                      strCompte = lines[1];      //Variable Compte pour le test de sécurité
                      string strCompte1 = strCompte.Replace("-", "");
     
                      strMontant = lines[2];   //Variable Montant pour le test de sécurité
                      string strMontant1 = strMontant.Replace(".", "");
                      strMontant1 = strMontant1.Replace(" ", "");
     
                      strNum = lines[3];
                      string strTest = "n° ref:" + strRef + "\nCompte: " + strCompte + "\nMontant : " + strMontant + "\nNumero : " + strNum;
                      //Sécurité pour saisie de donnée :
                      string[] strSplit = Regex.Split(strNum, ">");           //coupe la ligne du numéro préimprimé avec le char >
                      //MessageBox.Show(strSplit[0] + " ----" + strSplit[1]); 
                      string[] strSplit2 = Regex.Split(strSplit[1], @"\+ ");  //Découpe la ligne avec le caractère +     
                      string strTestMontant = strSplit[0];
                      string strTestRef = strSplit2[0];
     
                      string strTestCompte = strSplit2[1];
                      double dblTestRef = double.Parse(strTestRef);
                      double dblRef = double.Parse(strRef1);
                      double dblTestMontant = double.Parse(strTestMontant);
                      double dblMontant = double.Parse(strMontant1);
     
                      if (dblTestRef == dblRef)
                      {
                          //ocrTextBox.Text += "\r\nLe numéro de référence est correct.\r\n";
                          if (dblTestMontant == dblMontant)
                          {
                              Form1 frm = new Form1();
                              frm.Show();
                              Bitmap icone = new Bitmap("C:\\Emgu\\emgucv-windows-x86 2.3.0.1416\\Emgu.CV.Example\\CameraCapture\\check.ico");
                              IntPtr iIcone = icone.GetHicon();
                              notifyIcon1.Icon = Icon.FromHandle(iIcone);
                          }
                      }
                      else
                      {
     
                         // MessageBox.Show("Erreur dans le num de référence");
                      }
                        label1.Text = text;
                  }
              }
              catch (Exception ex)
              {
              }
          }

  13. #13
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    L'idée en fait est de ne plus appeler GetText(). Chaque charactor expose son morceau de texte. Donc tu dois faire un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Pour chaque charactor c
    {
        Si EssayeLaReference(c.Text)
        Sinon EssayeLeMontant(c.Text)
    }
    Par exemple, EssayeLaRéférence vérifiera qu'il s'agit bien d'un texte type XX XXXXX XXXXX etc... Si oui il stocke la valeur. C'est une méthode bourrine, qui fait tout reposer sur Tesseract mais qui pourrait t'éviter d'avoir à identifier la feuille au milieu de l'image de la webcam, d'avoir à détordre, etc...

    Si ça ne fonctionne pas on passera à l'analyse des régions, en se basant sur leurs centres, après avoir extrait la feuille du reste de l'image et l'avoir remise d'aplomb.

  14. #14
    Nouveau membre du Club
    Inscrit en
    Novembre 2009
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 59
    Points : 27
    Points
    27
    Par défaut
    Donc si j'ai bien compris tu me dis faire un truc genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
                      foreach (Tesseract.Charactor c in charactors)
                      {
                          if(Reference == " XX XXXX XX...")
                          {
     
                          }
                          else
                          {
                                 if(Montant== "****.**")
                                  ....
                          }
                      }
    c'est ça ??

  15. #15
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Oui, c'est l'idée, si ce n'est que tu aurais plutôt des "if (Regex.Match(c.Text, motifRéférence))"

  16. #16
    Nouveau membre du Club
    Inscrit en
    Novembre 2009
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 59
    Points : 27
    Points
    27
    Par défaut
    Je viens de penser que cette méthode est un peu trop barbare, parce que la longueur des suites de chiffres change sur chaque bulletin de versement en fait ... donc il faudrait que je trouve une solution pour "couper" l'image... Mais je ne sais vraiment pas comment m'y prendre...

  17. #17
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Mais non, c'est ta solution qui est compliquée : tu continues à raisonner à partir de ton image scannée alors que tes utilisateurs te fourniront des images prises depuis une webcam, donc jamais suffisamment droite ni centrée.

    Pour l'instant la question est de savoir si tu peux éviter d'avoir à extraire la feuille de l'ensemble de l'image. Car, crois-moi, ce serait beaucoup plus compliqué que de vérifier si un numéro est conforme au format que tu attends ou non.

    Par ailleurs, je serais toi, j'arrêterais totalement de travailler depuis une image scannée car cela va te mener à de fausses conclusions. La solution consistant à dire "l'utilisateur n'aura qu'à bien centrer, mettre à plat et adapter son éclairage" est un leurre.

  18. #18
    Nouveau membre du Club
    Inscrit en
    Novembre 2009
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 59
    Points : 27
    Points
    27
    Par défaut
    Justement je me disais pareil, maintenant je suis passé à faire pareil mais avec le flux vidéo, puis j'ai imprimé la feuille avec les numéros sur fond blanc, ça marche pas mal comme ça, mais justement je ne vois pas trop comment agir avec le BVR au complet ...

    Merci encore de ton aide !

  19. #19
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Une approche naïve consiste à scanner tous les pixels de l'image, faire la somme de R, V et B, et définir un seuil au-delà duquel tout est blanc et, en-dessous, noir. Sous quel format récupères-tu les données (buffer, handle GDI, image WPF/WinForms, etc) de la webcam ?

  20. #20
    Nouveau membre du Club
    Inscrit en
    Novembre 2009
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 59
    Points : 27
    Points
    27
    Par défaut
    je récupère le flux vidéo en Image<Bgr,Byte> , c'est une image au format EmguCV

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [C#] Comment supprimer/remplacer une couleur d'une image ?
    Par rannounna dans le forum Windows Forms
    Réponses: 1
    Dernier message: 09/05/2006, 12h37
  2. Réponses: 2
    Dernier message: 04/04/2006, 17h03
  3. [Cross-Browser] Couleur d'une image PNG
    Par [BkM-) dans le forum Balisage (X)HTML et validation W3C
    Réponses: 3
    Dernier message: 17/11/2005, 21h00
  4. [Image]Nombre de couleur d'une image
    Par daxuza dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 05/09/2005, 08h14
  5. [Graphique] Comment compter les couleurs d'une image ?
    Par yoghisan dans le forum API, COM et SDKs
    Réponses: 27
    Dernier message: 16/02/2005, 18h17

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