Analyse d'une image
Bonjour,
J'ai mon premier programme à réaliser en python pour mes études, le soucis c'est que je suis vraiment nul, très nul en programmation.
Donc j'aurais aimé savoir s'il est possible d'avoir un coup de main ici.
Je vous explique le sujet, déjà on passe par jupyter notebook que j'ai installer via anaconda il me semble. Le prof nous a transmis un jeu de carte via un dossier mais le souci premièrement c'est que dès que je change la valeur de la carte (D'un 10 de trèfle je veux afficher un 10 de coeur) et ben ça ne fonctionne pas. Surement un soucis de réglages mais je ne comprends pas quoi.
Du coup, le sujet c'est qu'à partir d'une analyse de l'image, on doit savoir reconnaître qu'elle carte est affiché à l'écran. Le jeu de carte que l'on doit étudier est un jeu de carte basique sauf que l'on prend que les cartes de 1 à 10, on exclu les figures.
A partir de là, il faut être capable d'identifier:
La couleur: noire ou rouge
La forme: coeur, carreau, trèfle ou pique
Le numéro: donc de 1 à à10.
Donc selon moi il faudrait réaliser une analyse de l'image pixel par pixel avec la bibliothèque matpotlib de ce que j'ai pu trouvé sur internet.
Mon "algorithme" commencerait par quelque chose comme ça (je me répète, mais le développement j'y arrive absolument pas):
Pour "pixel" allant de 1 à "nombre de pixel total" faire:
n° pixel <- Valeur rgb (ce qui nous donnerait la liste de tous les pixels avec la couleur, donc la
couleur serait déjà trouvé)
Ensuite je pense qu'il faudrait comparer le nombre de pixels blanc par rapport au nombre de pixels noir ou rouge. Car plus il y a de la couleur sur la carte, plus le chiffre sur la carte est élevé. Mais là je n'ai aucunes approche de comment je pourrait faire. Avec cette partie on pourrait en déduire le chiffre.
Et pour la forme il faudrait, selon moi, analyser un pixel spécifique je m'explique. Sur chaque carte il y a le symbole qui est placé au même endroit sur la carte (dans les 4 coins). Donc grossièrement si on analyse une carte rouge, les pixels du coeur seront différents des pixels du carreau.
Selon vous est ce une première bonne approche ?
Je ne souhaite pas quelqu'un qui fasse le programme pour moi évidemment, mais de l'aide et une piste sur laquelle je peux m'appuyer.
J'espère avoir été clair, et je vous remercie d'avoir pris le temps de lire et de m'aider si c'est possible.
Bonne journée à vous
J'ai mon premier programme à réaliser en python pour mes études, le soucis c'est que je suis vraiment nul, très nul en programmation.
Donc j'aurais aimé savoir s'il est possible d'avoir un coup de main ici.
Je vous explique le sujet, déjà on passe par jupyter notebook que j'ai installer via anaconda il me semble. Le prof nous a transmis un jeu de carte via un dossier mais le souci premièrement c'est que dès que je change la valeur de la carte (D'un 10 de trèfle je veux afficher un 10 de coeur) et ben ça ne fonctionne pas. Surement un soucis de réglages mais je ne comprends pas quoi.
Du coup, le sujet c'est qu'à partir d'une analyse de l'image, on doit savoir reconnaître qu'elle carte est affiché à l'écran. Le jeu de carte que l'on doit étudier est un jeu de carte basique sauf que l'on prend que les cartes de 1 à 10, on exclu les figures.
A partir de là, il faut être capable d'identifier:
La couleur: noire ou rouge
La forme: coeur, carreau, trèfle ou pique
Le numéro: donc de 1 à à10.
Donc selon moi il faudrait réaliser une analyse de l'image pixel par pixel avec la bibliothèque matpotlib de ce que j'ai pu trouvé sur internet.
Mon "algorithme" commencerait par quelque chose comme ça (je me répète, mais le développement j'y arrive absolument pas):
Pour "pixel" allant de 1 à "nombre de pixel total" faire:
n° pixel <- Valeur rgb (ce qui nous donnerait la liste de tous les pixels avec la couleur, donc la
couleur serait déjà trouvé)
Ensuite je pense qu'il faudrait comparer le nombre de pixels blanc par rapport au nombre de pixels noir ou rouge. Car plus il y a de la couleur sur la carte, plus le chiffre sur la carte est élevé. Mais là je n'ai aucunes approche de comment je pourrait faire. Avec cette partie on pourrait en déduire le chiffre.
Et pour la forme il faudrait, selon moi, analyser un pixel spécifique je m'explique. Sur chaque carte il y a le symbole qui est placé au même endroit sur la carte (dans les 4 coins). Donc grossièrement si on analyse une carte rouge, les pixels du coeur seront différents des pixels du carreau.
Selon vous est ce une première bonne approche ?
Je ne souhaite pas quelqu'un qui fasse le programme pour moi évidemment, mais de l'aide et une piste sur laquelle je peux m'appuyer.
J'espère avoir été clair, et je vous remercie d'avoir pris le temps de lire et de m'aider si c'est possible.
Bonne journée à vous
Configuration: Windows / Chrome 86.0.4240.75
49 réponses
Résumé de la discussion
Un étudiant souhaite développer une détection de cartes à jouer 1 à 10 à partir d'images pour identifier couleur, symbole et chiffre, en Python via Jupyter. Plusieurs propositions divergent entre une approche par analyse d'images au niveau des pixels et l'usage de réseaux de neurones, avec des outils Python comme PIL, NumPy ou OpenCV. En cas de difficultés, les échanges évoquent des erreurs de code liées à l'accès aux pixels et à PIL, des contraintes de rotation et de zoom, et des conseils pour tester pas à pas sur Jupyter. D'autres sections évoquent l'utilisation de réseaux de neurones et de cadres comme TensorFlow ou PyTorch pour apprendre à reconnaître les motifs des cartes malgré les variations.
-
Bonjour t-rence,
Je pense que tu peux marquer cet appel comme résolu ........ -
ContributeurBonjour T-rence,
Merci pour ce retour. J'imaginais bien que vous aviez du mal à compléter ce programme, qui n'est effectivement pas d'un niveau débutant.
Je connaissais le principe du réseau de neurones, qui sert entre autres choses dans le domaine de l'Intelligence Artificielle, dont notamment l'identification d'un individu dans une foule ou la détection des comportements déviants (les chinois sont très avancés dans ces spécialités) entre autres choses nécessitant un apprentissage par mix algorithmes-analyse de données.
Pour ma part, j'ai parmi mes nombreux projets, celui d'une ruche connectée où la reconnaissance de formes serait utilisée pour le comptage des abeilles et la détection de leurs migrations hors de la ruche (carte raspberry pi). Je n'ai pas le niveau pour écrire ce genre de programme in extenso mais plusieurs existent déjà, qui utilisent des bibliothèques de python (il me semble qu'il y en a une chez Google).
Je constate que votre professeur a apprécié vos efforts pour résoudre l'exercice, ce qui vous aura fait progresser, ce qui est le but de toute pédagogie. Comme le disait Coubertin, "l'important...")
Je vous souhaite bonne continuation dans vos études et le reste.
Georges -
Bonjour t-rence,
Les réseaux de neurones, je connais, j'ai déjà fait un programme qui, après une phase
d'apprentissage, reconnait ou bien des lettres, ou bien des chiffres sur une grille de 5x5 pixels ... -
Bonjour à tous,
Désolé pour le délai de réponse, j'ai eu quelques soucis perso qui fait que j'ai baissé pas mal les bras.
Je tiens à m'excuser auprès des personnes qui ont pris du temps pour me répondre et pour m'aider.
Je vous remercie grandement de l'aide que vous avez pu m'apporter. J'ai un peu evolué grâce à vous meme si mon niveau en code reste presque null.
Pour info j'ai toujours pas la solution de ce problème, mais le prof m'avait parlé qu'avec un réseau de neuronnes c'était totalement faisable mais il l'a dit lui même que pour nous c'était quasi impossible. Il a surtout souligné les démarches de recherches qui ont été effectué par chacun.
Je sais pas si vous vous y connaissez en réseau de neuronnes mais sachez qu'avec ce genre de système cela est faisable.
Si jamais vous avez des questions sur le sujet je pourrais faire l'intermédiaire pour y répondre.
Encore une fois, merci à vous pour votre aide. -
ContributeurAu fait Phil, nous n'avons pas de nouvelles de Phil et surtout de son programme.
"Mort aux pluches" comme on disait de notre temps ou passé à C pluche pluche et nous ayant laissé avec son ex-problème? -
Contributeurje prend l'angle ou il y a le minimum de pixels, ainsi que l'angle ou il y a le maximum de pixels oui, et tu les notes pour vérifier quand tu l'auras fait pour les 10 cartes qu'il n'y a pas de recoupement (il ne devrait pas y en avoir puisque la somme de pixels à l'air différente d'une carte à l'autre)
il faudrait faire ça pour tous les angles puisque comme vu dans l'exemple ou je cite les différences de pixels.
Ne le fais pas pour le moment. Fais le pour 4 ou 5 valeurs d'angles, come je le décrivais. Le calcul des 360 angles se fera dans un second temps par une boucle (de 0 à 359)
On ne s'occupe pas de vérifier la proportionnalité? Seule l'intervalle sera pris en compte.
Je tente une illustration:
as
mini=10000
maxi-12000
2
mini=25000
maxi=28000
3
mini=28000
maxi=32000
etc.
Mon "système" ne peut fonctionner que si les valeurs de ces couples ne se recoupent jamais, sinon, il y a "bataille" entre deux cartes.
On a donc 10 couples de valeurs, qui serviront à créer un dictionnaire, sorte de liste constituée de couple de deux éléments liés l'un à l'autre. On parle d'immutabilité en python, c'est à dire sur l'on ne peut pas changer les valeurs.
Ca donnera quelque chose comme cela (je suis quasiment en mode algorithmique là, je n'ai pas vérifié la syntaxe.
Je crée donc un dictionnaire mini_maxi pour les 10 cartes
dico_minmax={"mini1": 10000, "maxi1": 12000,"mini2": 25000, "maxi2": 28000,"mini3": 28000, "maxi3": 32000,....}
Chaque couple dans le dictionnaire ext un indice de 0 à 9 donc.
Une fonction if sera utilisée our comparer la carte entée, quelque soit son orientation, puisqu'elle devrait se situer dans l'intervalle d'un des 10 couples.
Par exemple, si la valeur de la carte entrée est de 26000 pour un angle de 30°, c'est le 2, si c'est 27500, c"est aussi le 2.
Si c'est 310000, c'est le 3.
En fait, on ne se préoccupe plus de l'angle, qui a été traité en amont, ou plus exactement contourné puisqu'on a enregistré dans une liste les 360 valeurs que peut prendre une carte et qu'on n'en a extrait le min et le maxi grâce aux fonctions min() et max()
La dernière partie consistera à tester par un if à quel couple correspond la a valeur-pixels de la carte entrée. Pour cela , on teste tour à tour chaque couple du dictionnaire jusqu'à atteindre l'intervalle correspondant à la valeur recherchée.
A l'attention de Phil, si cela n'est pas possible par le dictionnaire, c'est sans doute envisageable sur une liste et peut-être plus simple puisqu'il suffira de s'arrêter quand on atteindra la valeur recherchée:
ma_liste_valeurs(10000,12000;25000,28000,32000) et le if ressemblera à quelque chose comme:
for carte_entrée in range ma_liste_valeurs:
if carte_entrée<indice_liste:
carte_sortie=valeur(indice_liste) soit la carte 3 pour l'indice 2
Je suis à la retraite et dispose de temps mais le concours de Phil sera indispensable pour la dernière partie car je ne suis qu'un junior en python (mais pas en âge) et si ma piste est correcte, il aura sans doute des idées d'amélioration.
A bientôt. -
Ah oui donc si je comprend bien en gros je prend l'angle ou il y a le minimum de pixels, ainsi que l'angle ou il y a le maximum de pixels ce qui constitue le couple.
Ainsi si la valeur se situe dans ce couple il s'agit alors de telle carte.
Mais il faudrait faire ça pour tous les angles puisque comme vu dans l'exemple ou je cite les différences de pixels. Cela varie en fonction de chaque angle et n'est pas proportionnel (dans le sens où un angle de 10° peut avoir plus de pixels qu'un angle de 30° mais moins que celui de 20°).
Je sais pas si vous voyez ce que je veux dire ?
En tout cas s'il faut faire ça, je le ferais surement demain parce que je vous avouerais que je me suis donné la migraine.
Merci encore pour votre aide en tout cas -
Hello Georges97,
Pas de problème
Donner une plage de tolérance au lieu de valeurs exactes, ca parait pas mal ...-
ContributeurBonjour Phil, et merci pour ton retour,
En me relisant, je dois préciser à l'attention de T-Rence que quand je dis: juste un couple, constitué des deux extrêmes, la valeur la plus basse et la plus haute j'entends qu'au lieu de relever 10 valeurs comme au début de votre travail, on prend la valeur min et la valeur maxi pour constituer ce couple, on n'aura donc que deux valeurs par couple pour chaque carte, certes multiplié par 360, mais de façon automatique (boucle) pour finalement donner deux valeurs pour une carte correspondant au mini/maxi du relevé de pixels.
Ce sont ces seules deux valeurs qui seront introduites pour chaque carte, constituant un dictionnaire de 10 lines. A partir de ce dictionnaire, on évaluera à quel indice (coule) correspond la nouvelle carte par comparaison avec son mini/maxi.
-
-
ContributeurNon, justement, pas une liste par angle, juste un couple, constitué des deux extrêmes, la valeur la plus basse et la plus haute, correspondant à l'angle 0° du départ et de l'angle 359°. Mais mon raisonnement est sans doute faux sur la valeur du maximum de pixels, qui pourrait se trouver par exemple pour un angle de 80°.
Ce que tu pourrais faire, c'est relever les valeurs pour 0, 90, 180, 270 et 359°, soit 5 valeurs dont tu retiens le mini et le maxi, que tu utiliseras plus tard dans le dictionnaire (couple mini/maxi) dont je parlais.
Si pour chacune des 10 cartes, ces mini/maxis ne se recoupent pas, en testant l'appartenance du relevé de la carte tirée à un degré de rotation aléatoire, on pourra en déduire si elle entre dans les limites d'un couple puisque tous les couples sont différents.
Tu pourras après compléter en ajoutant l'ensemble des angles au lieu des 5 du premier test.
Par ailleurs, je ne sais pas comment tu relève les valeurs des pixels (c'est le post n°38, n-est-ce pas?), mais une simple boucle doit permettre d'établir la liste constituant le relevé des 360 positions d'angle.
Peut-être veux tu attendre la validation de Phil_1857 avant d'avancer trop loin dans ce qui pourrait ne pas convenir (je pense au dictionnaire), mais je pense que le test sur les 5 valeurs peut être tenté sans trop y consacrer de temps.
A te lire -
Bonjour Georges,
Merci pour ta contribution.
Si je comprend bien ton raisonnement, il faudrait donc construire une liste par angle qui comprend chaque limite de pixel pour chaque carte ?
Par exemple pour un angle de 10°: Réaliser par exemple pour l'as un ensemble style: [11 000 - 11 500] et ainsi de suite pour chaque carte ?
Ce qui signifie donc réaliser pleins de liste pour chaque angle ?
Pour ce qui est du zoom je n'arrive vraiment pas à zoomer.
J'ai alors demandé à mes collègues où ils en sont dans le projet et pour la plupart ils sont dans la même situation. Ils n'arrivent pas à zoomer.
Un collègue vient de me parler de crop pour la partie zoom. Je vais essayer d'approfondir de ce côté là voir ce qui est possible. -
ContributeurBonjour T-Rence, bonjour Phil_1857,
J'ai suivi ce fil dans le but de me perfectionner en python. Quand on voit les choses de l'extérieur, plutôt que d'avoir les contraintes "scolaires" de T-rence, on essaie de trouver, par jeu, une solution.
Voila ma proposition, plutôt que de réaliser un tableau ou plutôt une liste qui corresponde à chaque degré d'angle ou à chaque niveau de zoom, pourquoi ne pas générer une liste qui corresponde aux limites de chaque carte.
Je m'explique:
Si par exemple, en rotation les valeurs vont de disons 11000 à 15000 pour l'as et que pour le6 elle vont de 79444 à 82000, il "suffirait" d'établir la liste de base correspondant à un angle de 0°, une seconde liste correspondant à la position extrême de 359° (n vérifiant que cette liste inclue bien les valeurs extrêmes des angles intermédiaires.
Ensuite, en établissant un dictionnaire (fonction python, à l'attention de T-Rence bien sûr)) correspondant à chaque couple valeur inférieure/valeur supérieure, on serait sûr de retourner la bonne carte quelque soit l'angle (ou le zoom) présenté.
@ Phil_1857, il se peut que mon idée soit farfelue ou irréalisable mais considère la comme une simple réflexion par rapport au travail que vous avez tous deux réalisé.
Cordialement -
Je vais essayer de réaliser un zoom sur la photo. Je n'avais pas réussi en début de semaine. Je retente et dès que j'ai les valeurs de zoom je te dis ça
-
"comme je suis pas un dev et que j'ai jamais codé ... "
Ok, mais avant de coder en Python (ou autre langage), il faut déjà trouver l'idée sur le papier,
l'algorithme qui permettra de tester une carte
J'ai repris ta liste pixels trèfle[] et j'ai cherché une constante entre les 10 valeurs
puisque par rapport à l'as, il y a 2 fois plus de figurines 'trèfle' sur le 2, 3fois plus sur le 3, etc ...
Mais ca ne marche pas car sur une carte il n'y a pas les trèfles, il y a aussi le chiffre de la valeur,
avec au dessous la figurine en plus petit, et même, sur l'as, la figurine est parfois différente et décorée
tu peux tester le zoom pour voir si c'est mieux, il y aura peut-être une proportionnalité avec le facteur de zoom -
Je pense qu'il doit l'avoir oui. En faite c'est plus "découverte de la recherche" et suite à ça on va devoir écrire un article et le présenter etc. Le soucis c'est que le programme compte dans la "note" et comme je suis pas un dev et que j'ai jamais codé bah je galère un peu. Les autres je ne sais pas vraiment comment ils font vu que tout se fait à distance et que je ne connais personne c'est compliqué.
Tu penses que le zoom serait plus simple à traiter ? Au pire je sacrifie la rotation pour le zoom. -
Bonjour T-Rence,
Effectivement, on ne peut pas en tirer de loi, c'est un peu disparate
Il va falloir trouver autre chose, mais quoi ...
Est-ce que ton prof à la solution, au moins ?
Et les autres, ils font comment ? -
Bonjour Phil,
J'ai alors pour la carte 10 de pique, ce qui est connu: 114 792 pixels noir
Pour une rotation de 10° j'ai: 115 127 pixels noir soit 335 pixels de différence
Pour une rotation de 20° j'ai: 115 119 pixels noir soit 327 pixels de différence
Pour une rotation de 30° j'ai: 115 101 pixels noir soit 309 pixels de différence
Pour une rotation de 40° j'ai: 115 114 pixels noir soit 322 pixels de différence
Pour une rotation de 50° j'ai: 115 153 pixels noir soit 361 pixels de différence
Pour une rotation de 60° j'ai: 115 100 pixels noir soit 308 pixels de différence
Pour une rotation de 70° j'ai: 115 115 pixels noir soit 323 pixels de différence
Pour une rotation de 80° j'ai: 115 126 pixels noir soit 334 pixels de différence
Pour une rotation de 90° j'ai: 114 792 pixels noir soit 0 pixels de différence
J'en conclus pour cette carte qu'il n'y a pas de variable fixe pour le degré de variation et le nombre de pixels de différence.
J'ai donc testé sur une seconde carte pour voir si pour chaque rotation la différence de pixels est la même pour chaque degré de rotation.
J'ai pris le 9 de pique, ce qui est connu: 103 151 pixels noir:
Pour une rotation de 10° j'ai: 103 479 pixels noir soit 328 pixels de différence
Pour une rotation de 20° j'ai: 103 484 pixels noir soit 333 pixels de différence
A partir de là on voit déjà que les valeurs ne sont pas identiques vis-à-vis de la carte précédente. -
Je proposais donc de faire un bout de code pour analyser la relation angle / perte de pixels
La boucle qui varie de 1 à 91 (puisque le dernier chiffre est exclu de la liste, ca va donc de 1 à 90), non pas pour afficher les pixels, mais pour les compter, comme au début de ce projet
Ca donnerait une liste de ce genre (je mets des valeurs bidon, évidemment) :
angle nb de pixels delta par rapport au nb de pixels sans tourner la carte (on les a déjà dans tes 4 listes par figure) 1 15200 10 2 14850 20 etc ...
Et en examinant la liste complète, on verrait peut-être que l'on perd 10 pixels a chaque degré
comme ici: 1 degré: -10 pixels, 2 degrés: -20 pixels
donc perte = 10 pixels/degré
Et donc en test de reconnaissance réel:
Affichage carte
Rotation 30 degrés (par exemple), donc perte: 30 x 10 = 300 pixels
Comptage des pixels (noirs ou rouges)
Ajout de 300 pixels : on doit retomber sur un nombre de pixels présent dans l'une des 4 listes
du début (pixels_trefle, etc ...)
Fais le déjà pour une seule carte, c'est juste pour vérifier l'hypothèse -
Effectivement là le résultat est différent et ça fonctionne.
Je ne sais pas pourquoi ça ne marchais pas avant. Mon code n'avait pas l'air mauvais.
Donc à partir de là je n'est pas compris la suite de ton idée -
Ben évidement!
Rotation 0 degrés, la carte reste verticale !
Maintenant, tu essaye avec 20 au lieu de 0 pour voir .... -
Oui j'ai bien le même affichage. Mais il est identique s'il y a la ligne de code de rotation ou non. Je ne vois pas de différence.
Est ce qu'est c'est dû au "0.0"?
- 1
- 2
- 3
Suivant