Analyse d'une image

Signaler
-
Messages postés
41
Date d'inscription
samedi 27 juillet 2019
Statut
Membre
Dernière intervention
16 octobre 2020
-
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


Configuration: Windows / Chrome 86.0.4240.75

13 réponses

Messages postés
477
Date d'inscription
lundi 23 mars 2020
Statut
Membre
Dernière intervention
28 octobre 2020
66
Bonjour Terence,


Si j'ai bien compris:

_ Tu débutes en programmation ?

_ Le prof vous a donné des images d'un jeu de cartes ?

_ Il vous demande vraiment de faire de la reconnaissance d'image ?


Pour débuter, il me semble qu'il y a des exercices plus faciles !

C'est vraiment ça ?
Bonjour Phil,

Oui c’est ça. Après dans ma classe certains sont déjà avancé en programmation, ce qui n’est pas mon cas. C’est pour ça qu’il a dit qu’il ne mettait que les cartes de 1 à 10.

Il nous a bien fourni un jeu de carte en image oui.

D’après lui c’est très simple et basique comme genre de code
Messages postés
477
Date d'inscription
lundi 23 mars 2020
Statut
Membre
Dernière intervention
28 octobre 2020
66
Je serais curieux de voir ce que ca donne ...

Pour moi, reconnaissance d'image = IA avec réseau de neurones et tout ...
Messages postés
419
Date d'inscription
vendredi 25 septembre 2015
Statut
Membre
Dernière intervention
20 octobre 2020
200
Bonjour,
Je vous avoue que je suis tout aussi étonné que Phil_1857 qu'on vous demande de faire de la reconnaissance d'image alors que vous débutez en programmation. Il s'agit à priori d'une tache d'intelligence artificielle donc c'est un sujet assez complexe.

Après le problème est peut-être plus simple que ce qu'il n'y parait, tout dépend des images qui vous ont été fournis. S'il s'agit de photos, alors je ne pourrais pas vous aider et je vous conseille de chercher des exercices plus facile pour commencer.
Si ce sont des images qui ont été généré numériquement, c'est à dire où tous les trèfles par exemple sont exactement les mêmes au pixel prêt et placés exactement au même endroit au pixel prêt, et si on ne vous demande pas que l'algorithme fonctionne pour des images inconnues, alors votre approche peut fonctionner.

Pour le symbole, vous pouvez chercher quelques pixels qui vous permettent à partir de la couleur de ces seuls pixels, de trouver la couleur (pique, carreur, coeur trèfle) de la carte.

Pour déterminer le numéro de la carte, votre solution peut peut-être fonctionner, mais j'imagine que ça dépend de comment sont les images exactement. Si le numéro affiché est de la même couleur que les symboles, alors la surface du chiffre va être comptabilisée et pourra fausser les résultats. Mais encore une fois, ça dépends des images qui vous ont été données, rien de vous empêche d'essayer.

Sinon, une idée que j'ai, qui est plus compliqué, mais qui pourrait fonctionner dans le cas où votre première méthode ne fonctionnerait pas : vous pouvez faire comme pour l'analyse du symbole. Vous prennez quelques pixels qui vous permettent, à eux seuls, de déterminer le numéro de la carte. Si je prends un exemple avec uniquement des 1 et des 2, vous pouvez regarder le pixel au centre de la carte et les 2 pixels qui sont aux centre des symboles lorsque qu'il y en a 2, et en fonction des quels sont blancs, rouges, ou noirs, vous devriez pouvoir determiner s'il s'agit d'un 1 ou un 2.
Il faut généraliser ça avec les 10 numéros.

Bon, je ne sais pas ce que vous appellez débutant exactement.
Je ne trouve pas que ce soit un algorithme très simple quand même, mais étant donné que ça correspond plus ou moins à ce que vous avez proposé, je me dis que vous avez peut-être le niveau pour le réaliser. Ça reste quand même infiniment plus simple que de la "vrai" reconnaissance d'image.
Messages postés
41
Date d'inscription
samedi 27 juillet 2019
Statut
Membre
Dernière intervention
16 octobre 2020

Bonjour,

Merci pour vos réponses.

Alors pour être plus clair, nous avons ce genre d'image .

Et à partir de là il faut réaliser un code qui permettrait d'identifier la carte.

Mon niveau en programmation est de 0. Je connais un peu les boucles etc mais niveau algorithmique. Lorsqu'il s'agit de traduire dans un langage j'ai beaucoup de mal. Je ne suis pas développeur mais malheureusement dans les études informatique on n'y échappe pas.

Messages postés
477
Date d'inscription
lundi 23 mars 2020
Statut
Membre
Dernière intervention
28 octobre 2020
66
Bonjour T-rence,

Déjà, si il n'y a que les cartes de 1 à 10, cela simplifie le problème: il ne peut y avoir que 2 couleurs sur une carte, le blanc du fond et le rouge ou le noir des figures

Donc si les chiffres que tu affiches représentent les 3 composantes Rouge, Vert, Bleu de la couleur du pixel, tu peux chercher si il y a au moins 1 pixel rouge ou 1 noir, en dehors du blanc

Par contre, pour le type de figure, (trèfle, cœur,...), et le chiffre, c'est un peu moins simple ...

Pour le chiffre, on peut peut être compter la quantité de pixels noirs ou rouges, vu que sur le 10 de carreau, par exemple, il y a une surface de rouge plus grande que sur l'as

Moi je ferai d'abord un petit programme de test pour analyser les cartes une par une et donc récupérer le nombre de pixels de couleur de chacune, ce qui donnerait une liste de 10 entiers par figure qui servirait ensuite dans le programme définitif pour connaitre le chiffre d'une carte donnée
exemple : liste_trefle = [3250,4520,6585,8674, .....]

Exemple: tu a déterminé que c'est une carte rouge, et tu a le nb total de pixels rouges, donc tu cherches dans liste_carreau et dans liste_coeur un nb de pixels qui correspond

Si le nb est le 5eme de la liste liste_carreau, c'est donc un 5 de carreau
Messages postés
41
Date d'inscription
samedi 27 juillet 2019
Statut
Membre
Dernière intervention
16 octobre 2020

Bonjour Phil,

Merci pour ta réponse.

Oui voilà c'est à peu près le style d'idées que j'avais. Maintenant c'est surtout pour retranscrire en langage python qui va être compliqué.

Est-ce que tu aurais des pistes vis-à-vis du code ? J'ai beau cherché sur le net mais je ne trouve pas vraiment de documentation qui ressemblerais à ce genre de choses.

J'ai une assez bonne logique dans l'analyse mais dès qu'il s'agit d'être technique c'est un peu plus compliqué pour moi.

Merci en tout cas de ton aide
Messages postés
477
Date d'inscription
lundi 23 mars 2020
Statut
Membre
Dernière intervention
28 octobre 2020
66
for x in range(carte.width):
    for y in range(carte.height):
        print(pixel[x,y])


Avec ça, on analyse toute la surface

Ensuite, à toi de dire ce que représentent les chiffres qui s'affichent, personnellement, je ne connais ni
numpy ni matplotlib, ni PIL ...
Messages postés
41
Date d'inscription
samedi 27 juillet 2019
Statut
Membre
Dernière intervention
16 octobre 2020

Les chiffres qui s'affichent (255 255 255 par exemple) représente les couleurs à un pixel donné. 255 255 255 étant le blanc et 0 0 0 le noir.

Ok donc si je comprend ton code, on a deux boucles et chacune analyse un pixel sur la longueur et la largeur.

A partir de ce moment là est- ce que l'on peut faire une "comparaison" ou une déduction qui serait:
Si au moins un pixel de la carte est rouge alors la carte est soit du carreau soit du coeur
Si non c'est soit du trèfle soit du pique ?

Je sais pas si tu vois ce que je veux dire
Messages postés
477
Date d'inscription
lundi 23 mars 2020
Statut
Membre
Dernière intervention
28 octobre 2020
66
"Ok donc si je comprend ton code, on a deux boucles et chacune analyse un pixel sur la longueur et la largeur."

on a 2 boucles pour extraire un pixel de coordonnées x,y, donc on parcourt toute la surface, dans ton exemple, tu ne parcours que la ligne en y 50

C'est quoi le 4eme chiffre qui s'affiche:

il n'y a pas que 255,255,255, mais un 4eme chiffre au bout ...

Enfin, si les 3 1ers chiffres sont la couleur, alors au lieu du print, on peut écrire:
noir = 0
rouge = 0
for x in range(carte.width):
    for y in range(carte.height):
        if(pixel[x,y][0:3] == (0,0,0)):
            noir += 1
        elif(pixel[x,y][0:3] == (255,0,0)):
            rouge += 1

En fin de boucle rouge = nb de pixels rouges et noir = nb de pixels noirs
Messages postés
41
Date d'inscription
samedi 27 juillet 2019
Statut
Membre
Dernière intervention
16 octobre 2020
>
Messages postés
477
Date d'inscription
lundi 23 mars 2020
Statut
Membre
Dernière intervention
28 octobre 2020

Bonjour Phil,

Je rencontre un petit soucis: Quand j'exécute la première partie du code, j'ai aucuns soucis, tout se passe bien:



Par contre quand j'exécute la seconde, ça ne fonctionne pas. Dans mon exemple c'est censé être une carte noire et il m'affiche systématiquement que c'est une carte rouge et il n'affiche rien d'autre alors qu'il devrait m'afficher le numéro et le style de carte. J'ai essayé d'enlever la première partie pour voir si le problème ne venait pas de là (peut-être dû à une répétition mais non). Et j'ai aussi essayer de mettre les listes en haut avec "rouge=0" et "noir=0" mais ça me fait toujours la même chose. Aurais tu une idée de ce que cela peut-être.



Merci encore pour ton aide
Messages postés
477
Date d'inscription
lundi 23 mars 2020
Statut
Membre
Dernière intervention
28 octobre 2020
66 >
Messages postés
41
Date d'inscription
samedi 27 juillet 2019
Statut
Membre
Dernière intervention
16 octobre 2020

ce serait plus clair si tu postait ton code avec les balises de code comme je l'ai fait dans mes exemples
de plus, on peut copier/coller et tester, alors qu'avec une image ....

https://codes-sources.commentcamarche.net/faq/11288-les-balises-de-code

dis-donc, je m'aperçois que le bout de code que j'avais posté pou la 2eme partie n'apparait plus ici,
certains de mes messages ont disparu ...

Déjà, on voit que tu ne sépares pas apprentissage et exploitation
le rouge c'est (255,0,0), pas (223,0,0)

pixels_coeur = [.....]
pixels_carreau = [.....]
pixels_pique = [.....]
pixels_trefle = [.....]

#Afficher une carte au hasard
carte = image.open .....
imshow(np.asarray(carte))

#Tester
noir = 0
rouge = 0
for x in range(carte.width):
    for y in range(carte.height):
        if(pixel[x,y][0:4] == (0,0,0)):
            noir += 1
        elif(pixel[x,y][0:3] == (255,0,0)):
            rouge += 1

if(rouge != 0):
    for k in range(10):
        if(pixels_coeur[k] == rouge):
            print('''C'est un {} de coeur'''.format(k+1))
    for k in range(10):
        if(pixels_carreau[k] == rouge):
            print('''C'est un {} de carreau'''.format(k+1))
elif(noir != 0):
    for k in range(10):
        if(pixels_pique[k] == noir):
            print('''C'est un {} de pique'''.format(k+1))
    for k in range(10):
        if(pixels_trefle[k] == noir):
            print('''C'est un {} de trefle'''.format(k+1))
Messages postés
41
Date d'inscription
samedi 27 juillet 2019
Statut
Membre
Dernière intervention
16 octobre 2020
>
Messages postés
477
Date d'inscription
lundi 23 mars 2020
Statut
Membre
Dernière intervention
28 octobre 2020

Je te mets le code directement dans le message. Désolé.

Donc la "première partie":

noir = 0
rouge = 0
for x in range(carte.width):
    for y in range(carte.height):
        if(pixel[x,y][0:3] == (0,0,0)):
            noir += 1
        elif(pixel[x,y][0:3] == (223,0,0)):
            rouge += 1
            
print ("Nombre de pixels noir:",noir)
print ("Nombre de pixels rouge:",rouge)


if noir > rouge:
    print ("C'est une carte noire")
else: 
    print ("C'est une carte rouge")    


Jusqu'ici j'ai bien le résultat escompté.

Par contre pour la seconde partie (où j'ai tout remis dedans pour essayer de "généraliser" ça ne fonctionne pas et ça me met que "la carte est rouge" même quand elle ne l'est pas.

noir = 0
rouge = 0

for x in range(carte.width):
    for y in range(carte.height):
        if(pixel[x,y][0:3] == [0,0,0]):
            noir += 1
        elif(pixel[x,y][0:3] == [223,0,0]):
            rouge += 1
if noir > rouge:
    print ("C'est une carte noire")
else:
    print ("C'est une carte rouge")

pixels_trefle = [11813,33953,45145,56462,67862,79444,89749,101966,113220,125936]
pixels_coeur = [9991,30718,41075,51672,62366,73140,82741,94211,104671,116284]
pixels_pique = [56404,30920,41041,51315,61854,72336,81703,92956,103151,114792]
pixels_carreau = [7523,22970,30774,38750,46852,54990,61979,70871,78705,87648]
    
if(rouge != 0):
 for k in range(len(pixels_coeur)):
  if(pixels_coeur[k] == rouge):
   print('''C'est un {} de coeur'''.format(k))

 for k in range(len(pixels_carreau)):
  if(pixels_carreau[k] == rouge):
   print('''C'est un {} de carreau'''.format(k))

if(noir != 0):
 for k in range(len(pixels_pique)):
  if(pixels_pique[k] == noir):
   print('''C'est un {} de pique'''.format(k))

 for k in range(len(pixels_trefle)):
  if(pixels_trefle[k] == noir):
   print('''C'est un {} de trèfle'''.format(k))



Par contre je n'ai pas très bien compris la phase d'apprentissage et exploitation.

Et il me semble que pour le rouge de ce que j'ai pu analyser dans les cartes du jeu que j'ai c'est 223 je vais revérifier
Messages postés
477
Date d'inscription
lundi 23 mars 2020
Statut
Membre
Dernière intervention
28 octobre 2020
66 >
Messages postés
41
Date d'inscription
samedi 27 juillet 2019
Statut
Membre
Dernière intervention
16 octobre 2020

dans ton code carte est toujours rouge car tu exploite le résultat de la 1ere partie: rouge est différent de 0
donc rouge tout le temps !


phase d'apprentissage: c'est celle qui permet de déterminer les 4 listes

on ne le fait qu'une fois pour toutes en passant toutes les cartes

phase d'exploitation : une fois qu'on a les 4 listes, on affiche une carte au hasard et on la teste, et ça, on le fait autant de fois que l'on veut, pas besoin de refaire la 1ere phase

regarde le code que je t'ai posté, en plus tu verra une correction d'erreur :

print('''C'est un {} de coeur'''.format(k+1))


au lieu de :

print('''C'est un {} de coeur'''.format(k))


car les indices de liste vont de 0 à 9 et pas de 1 à 10

if noir > rouge:


pas terrible, c'est rouge =0 ou un nombre, ou noir = 0 ou un nombre
Messages postés
41
Date d'inscription
samedi 27 juillet 2019
Statut
Membre
Dernière intervention
16 octobre 2020
>
Messages postés
477
Date d'inscription
lundi 23 mars 2020
Statut
Membre
Dernière intervention
28 octobre 2020

Ca m'a l'air de fonctionner. La place des listes à un emplacement précis à avoir dans le code je ne pensais pas.

En tout cas je te remercie beaucoup pour ton aide. Je vais proposer ça au prof. En tout cas tu m'as bien aidé et je commence un peu à comprendre. Le problème c'est vraiment le code à proprement parler qui me pose problème. Merci encore à toi d'avoir pris de ton temps pour m'aider
Messages postés
1
Date d'inscription
jeudi 15 octobre 2020
Statut
Membre
Dernière intervention
15 octobre 2020

Fait un tableau avec les % de couleur de chaque carte en premier :
pctCouleurCarte = [0]*10

Tu devras remplir le tableau dans ton code quand tu auras récupérer le % de couleur de chaque carte
Du coup avant d'avoir rempli les 10 valeurs, ton programme pourra juste te donner le % de couleur et pas trouver la carte

Rajoute avant ta boucle :
nbPixels = carte.width * carte.height

Après la boucle :
pctCouleur = (blanc / nbPixels) * 100

Quand ton tableau pctCouleurCarte est rempli :
for i in range (0,10) :
if pctCouleurCarte[i] == pctCouleur
print "La carte est la Carte " + i
Messages postés
41
Date d'inscription
samedi 27 juillet 2019
Statut
Membre
Dernière intervention
16 octobre 2020

Yes donc là je pense que grâce au code de Phil, je peux avoir l'info sur la couleur ce qui élimine une première étape du problème.

Et grâce au tableau de pourcentage je peux avoir le numéro de la carte.

Il me manquerait alors seulement la forme. Et là je pense qu'il faudrait superposer des pixels à partir d'une couleur. Quand on sait que c'est du rouge on superpose un même pixel sur une carte de carreau et de coeur et c'est ce qui nous donnerait la forme.
Messages postés
477
Date d'inscription
lundi 23 mars 2020
Statut
Membre
Dernière intervention
28 octobre 2020
66
avec ma méthode, pas besoin de pourcentage, et il ne manque pas la forme

on obtient directement : 10 de trèfle, par exemple

(voir ma réponse de 15h43)