Bonjour,
J'ai une image png qui contient plusieurs formes de couleurs différentes.
Je dois dans un premier temps ne garder que les formes de couleurs noirs et créer un fichier image pour chaque forme.
Je parse donc l'image et ne garde que les pixels de couleurs noirs avec cet algorithme :
public PImage DetectionFormesNoir(PImage img){ PImage buf = createImage( img.width, img.height, RGB ); buf.loadPixels(); for(int x = 0; x < img.width; x++) { for(int y = 0; y < img.height; y++) { int loc = x + (y * img.width); color c = img.pixels[loc]; float r = red(c); float v = green(c); float b = blue(c); if(r == 0 && v == 0 && b == 0 ) { color col = color(r, v, b); buf.pixels[loc] = col; } else{ buf.pixels[loc] = color(255, 255, 255); } } } buf.updatePixels(); return buf;
Puis applique au résultat le filtre de sodel afin de récupérer les contours des différentes formes noirs.
Fonction Sodel : http://www.mon-club-elec.fr/pmwiki_mon_ … treSobel2D
En soit cela fonctionne très bien. Mais je ne vois pas de là comment récupérer chaque forme et les enregistrer séparément. Auriez-vous une idée?
Merci d'avance,
Valentin
PS : Je n'ai pas le droit d'utiliser OpenCV ou autre librairie
Dernière modification par tintin02100 (2015-12-09 22:54:30)
Hors ligne
Bonjour,
Beau problème, j'avais un peu débroussaillé la vision par ordinateur il y a quelques temps, mais sans rien imlémenter.
Il faut faire une détection des coins après avoir fait les contours. Il y a ce lien :
http://www.developpez.net/forums/d32513 … is-imagej/
Sinon, un autre réalisé avec MathLab :
http://robotics.eecs.berkeley.edu/~sast … index.html
Je te souhaite plein de courage.
Hors ligne
Bonjour Mushussu,
Merci pour les liens
Je vais y regarder.
Ce qui est dommage c'est que j'aimerai ne pas toucher au code actuel car sobel récupère déjà les contours... Il faut juste réussir à charger chaque objet dans une image différente
Hors ligne
Je n'avais pas bien lu ta demande. Pour récupérer les différentes formes dans des images, je n'ai pas eu besoin de Sobel. Dès que je trouve un point noir, je scrute son environnement pour en trouver d'autres. Je regarde le tas de pixel adjacents. Voici le code :
PImage origine, test; ArrayList<PImage> liste; // Tableau de PImage qui contiendra les formes independantes void setup() { size(1500, 500); origine = loadImage("IMG_1999.PNG"); test = detectionFormesNoires(origine); liste = new ArrayList<PImage>(); int i = 0; while (!imageBlanche(test)) { PImage forme = separation(test); liste.add(forme); //forme.save("forme" + i + ".png"); i++; } println("Extraction de " + i + " formes"); } void draw() { image(origine, 0, 0); image(test, 500, 0); image(liste.get(0), 1000, 0); } boolean imageBlanche(PImage img) { boolean test = true; for (int i = 0; i < img.width * img.height; i++) { if (img.pixels[i] == color(0)) { test = false; } } return test; } PImage separation(PImage img) { PImage retour = createImage(img.width, img.height, RGB); for (int i = 0; i < img.width * img.height; i++) { retour.pixels[i] = color(255); } img.loadPixels(); boolean vierge = true; int debut = 0; int tt = 0; for (int i = 0; i < img.width; i++) { for (int j = 0; j < img.height; j++) { int loc = j + (i * img.width); tt++; if (img.pixels[loc] == color(0)) { vierge = false; debut = loc; break; } } if (!vierge) { break; } } IntList liste = new IntList(); IntList nouveau = new IntList(); IntList nouveauP = new IntList(); liste.append(debut); nouveau.append(debut); do { nouveauP.clear(); // Pour chaque nouveau pixel, recherche dans les 4 directions s'il y en a un nouveau noir for (int i : nouveau) { if (img.pixels[i - img.width] == color(0)) { nouveauP.append(i - img.width); img.pixels[i - img.width] = color(255); } if (img.pixels[i + img.width] == color(0)) { nouveauP.append(i + img.width); img.pixels[i + img.width] = color(255); } if (img.pixels[i - 1] == color(0)) { nouveauP.append(i - 1); img.pixels[i - 1] = color(255); } if (img.pixels[i + 1] == color(0)) { nouveauP.append(i + 1); img.pixels[i + 1] = color(255); } } nouveau.clear(); for (int i : nouveauP) { liste.append(i); nouveau.append(i); } } while (nouveauP.size() != 0); // Arrete si aucun pixel noir n'est trouve for (int i : liste) { retour.pixels[i] = color(0, 0, 0); } retour.updatePixels(); return retour; } public PImage detectionFormesNoires(PImage img) { PImage buf = createImage( img.width, img.height, RGB ); buf.loadPixels(); for (int x = 0; x < img.width; x++) { for (int y = 0; y < img.height; y++) { int loc = x + (y * img.width); color c = img.pixels[loc]; float r = red(c); float v = green(c); float b = blue(c); if (r <= 10 && v <= 10 && b <= 10 ) { buf.pixels[loc] = color(0); } else { buf.pixels[loc] = color(255, 255, 255); } } } buf.updatePixels(); return buf; }
Hors ligne
*-* Tu es fabuleux @Mushussu.
Ton code est juste magnifique !!!
Un grand merci à toi
Hors ligne
N'exagérons rien, il y a plein d'optimisation à réaliser. Ne pas repartir de zéro pour trouver un nouveau point noir. Change le test de l'image blanche.
Je m'y collerais ce week-end si j'ai le temps.
Feras-tu une détection de coin pour trouver les formes rectangulaires ?
Hors ligne
Le système détecte tous les objets qu'ils soient rond ou carré ou en étoile alors pourquoi détecter les contours? C'est peut être moins gourmand?
Il me manquait que ta partie pour finir le programme. Je dois juste le modifier pour qu'il puisse dans un deuxième cas enregistrer tous les objets dans des fichiers différents aussi
Dernière modification par tintin02100 (2015-12-11 14:15:38)
Hors ligne
Comment modifierais tu ta fonction séparation mais pour des objets de n'importe quelle couleur?
Hors ligne
Voilà, j'ai tout empaqueter dans une classe.
Avec la souris tu peux sélectionner la couleur dans l'image principale.
Hors ligne
Waouw tu as sacrement bien réduit le code. Un grand merci
Je vais essayer d'implanter une fonction pour qu'il recherche toutes les couleurs affichées sur l'écran et les enregistres direct. Comme dit sur le sujet.
Hors ligne
Ca m'énerve XD
J'essaye d'automatiser la recherche des couleurs présent sur l'image.
Je veux stocker les couleurs dans un tableau.
color[] colorArray = new color[1000]; public void DetectionCouleurs(PImage img){ for(int x = 0; x < img.width; x++) { for(int y = 0; y < img.height; y++) { int loc = x + (y * img.width); color c = img.pixels[loc]; float r = red(c); float g = green(c); float b = blue(c); if(r != 255 && g != 255 && b != 255 ){ for(int i = 0; i < colorArray.length; i++){ color c_old = colorArray[i]; float r_old = red(c_old); float g_old = green(c_old); float b_old = blue(c_old); if(c != c_old){ colorArray[i] = color(r, g, b); } } } } }
Cependant il enregistre quand même toutes les couleurs en double malgré toutes les if... Saurais tu d'ou vient mon erreur? Comment toi ferais tu?
Le but du jeu étant qu'en suite je parse le tableau et enregistre les images automatiquement pour chaque couleur
void setup() { origine = loadImage("0.png"); size(1600, 500); liste = new ArrayList<PImage>(); t = new Traitement(10); // Initialise avec une tolerance pour les couleurs DetectionCouleurs(origine); for(int i = 0; i < colorArray.length; i++){ color c = colorArray[i]; float r = red(c); float g = green(c); float b = blue(c); println(red(c) + " : " + green(c) + " : " + blue(c)); liste = t.process(origine, color(0, 0, 0)); } frameRate(1); compteur = 0; }
Hors ligne
Tu n'es pas obligé de passer par la décomposition en RGB. Le type color est un entier :
https://processing.org/reference/color_datatype.html
Il "suffit" de comparer les deux entiers.
Il est possible de faire ainsi :
IntList listeCouleur = new IntList(); for (int i = 0; i < origine.pixels.length; i++) { boolean correspondance = false; for (int element : listeCouleur) { if (origine.pixels[i] == element) { correspondance = true; break; } } if (!correspondance) { listeCouleur.append(origine.pixels[i]); } }
Le problème, c'est que l'on obtient plus de 2000 couleurs. Parce que les couleurs rouges ne sont pas franches. Il y a de micro-variations et le bords sont un peu flous.
Il serait préférable de passer l'image à travers la moulinette d'un filtre de seuil.
Ce n'est peut-être pas la bonne approche du problème. Peux-tu donner l'énoncé de l'exercice ?
Hors ligne
Ci-joint le sujet
Hors ligne
C'est bien cela, l'approche n'est pas la bonne. Puisque c'est un fond uniforme, il faut distinguer les couleurs qui ne sont pas semblables au fond.
De plus, il faudra recadrer les images pour qu'elles soient au plus proche de la forme.
Il faut poser un postulat pour le fond. On peut dire que si la couleur des points de la première ligne est uniforme alors cette couleur est la couleur du fond. Sinon, on teste la dernière ligne, première colonne, dernière colonne.
Une fois le couleur du fond définie, on transforme dans une image tampon le fond en blanc et tout ce qui n'est le fond en noir, pour avoir ce que l'on connait.
Hors ligne
Ca me parle pas du tour :p
Hors ligne