» codelab : http://codelab.fr/accueil » Forum : Codes & Travaux : http://codelab.fr/codes-et-travaux » Segmentation : http://codelab.fr/6018 Ceci est la version imprimable d'un sujet du forum, pour retourner à la version complète : Segmentation |
tintin02100 — 2015-12-09 22:53:14 |
Bonjour, 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;
|
Mushussu — 2015-12-10 17:51:24 |
Bonjour, |
tintin02100 — 2015-12-10 17:58:04 |
Bonjour Mushussu, |
Mushussu — 2015-12-10 23:54:42 |
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; } |
tintin02100 — 2015-12-11 09:17:24 |
*-* Tu es fabuleux @Mushussu. |
Mushussu — 2015-12-11 10:06:52 |
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. |
tintin02100 — 2015-12-11 13:55:47 |
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? |
tintin02100 — 2015-12-11 16:38:34 |
Comment modifierais tu ta fonction séparation mais pour des objets de n'importe quelle couleur? |
Mushussu — 2015-12-13 11:01:37 |
Voilà, j'ai tout empaqueter dans une classe. |
tintin02100 — 2015-12-13 23:20:17 |
Waouw tu as sacrement bien réduit le code. Un grand merci :D |
tintin02100 — 2015-12-14 09:29:13 |
Ca m'énerve XD 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? 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; } |
Mushussu — 2015-12-14 10:34:19 |
Tu n'es pas obligé de passer par la décomposition en RGB. Le type color est un entier : 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. |
tintin02100 — 2015-12-14 10:43:27 |
Ci-joint le sujet :) |
Mushussu — 2015-12-14 11:23:06 |
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. |
tintin02100 — 2015-12-14 11:50:38 |
Ca me parle pas du tour :p |
Olivier — 2015-12-14 12:04:16 |
Mushussu te décris juste un moyen de repérer le fond de l'image, compte tenu du fait que les couleurs des objets ne sont, elles, pas parfaitement uniformes. |
tintin02100 — 2015-12-14 12:24:07 |
Oui je dois passer par niveau de gris :) |
tintin02100 — 2015-12-14 14:44:50 |
J'ai réussi à stocker les pixels avec ta fonction. Et à récupérer certaines images. Il ne me les récupères pas toutes. An OutOfMemoryError means that your code is either using up too much memory because of a bug (e.g. creating an array that's too large, or unintentionally loading thousands of images), or that your sketch may need more memory to run. If your sketch uses a lot of memory (for instance if it loads a lot of data files) you can increase the memory available to your sketch using the Preferences window. |
Olivier — 2015-12-14 23:18:39 |
Est-ce que tu as essayé de faire ce que le message te suggère ?
|
Mushussu — 2015-12-15 00:23:47 |
C'est une fuite en avant Olivier, c'est comme un bol de noix de cajou dans une réunion de la fête des 0 et des 1. Tu auras beau en rajouter il sera toujours vide. PImage detectionFond(PImage img) { PImage travail = img.get(); color fond = img.pixels[0]; // boolean test = true; for (int i = 0; i < img.width; i++) { if (img.pixels[i] != fond) { test = false; } } if (!test) { println("Pas de couleur de fond"); return null; } println(red(fond) + " " + green(fond) + " " + blue(fond)); // Elaboration de la copie de travail for (int i = 0; i < img.pixels.length; i++) { if (img.pixels[i] == fond) { travail.pixels[i] = color(255); } else { travail.pixels[i] = color(0); } } return travail; } Ensuite tu peux appliquer la moulinette. Pour finir j'ai fait la méthode pour sauvegarder les images. |
Olivier — 2015-12-15 00:38:08 |
True. :P |
Mushussu — 2015-12-15 00:48:35 |
Entres-tu dans les paramètres de cette équation ? |
tintin02100 — 2015-12-15 06:38:14 |
Bonjour les gars, |
Mushussu — 2015-12-15 08:17:43 |
Je balaye l'image, les lignes les unes après les autres. Le premier point que je rencontre me donne le y du point de départ du rectangle ensuite je regarde le point le plus à gauche (min) et le point le plus à droite(max) pour le x et la largeur. à chaque fois que je vois un point noir je dit que c'est le dernier, comme cela quand je n'en vois plus la coordonnée y est stockée ce qui me donne la hauteur du rectangle.
A toi de voir l'algorithme le plus robuste. |
tintin02100 — 2015-12-15 09:03:33 |
Ton algo est bien plus robuste xD |
Mushussu — 2015-12-15 09:53:25 |
La méthode décomposition n'a plus lieu d'être puisque l'image de travail à été réalisée avec la méthode decompositionFond(). |
Olivier — 2015-12-15 12:22:07 |
Oui. Merci.
Je ne vois absolument pas pourquoi tu poses cette question. :D |