Annonce

>>> Bienvenue sur codelab! >>> Première visite ? >>> quelques mots sur codelab //// partage de liens //// une carte des membres//// (apéros) codelab


#1 2015-12-09 22:53:14 Segmentation

tintin02100
membre
Date d'inscription: 2015-12-09
Messages: 14

Segmentation



Bonjour,

J'ai une image png qui contient plusieurs formes de couleurs différentes.

http://image.noelshack.com/minis/2015/50/1449697869-sans-titre.png

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;

http://image.noelshack.com/minis/2015/50/1449697868-sans-titre1.png

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

http://image.noelshack.com/minis/2015/50/1449697869-sans-titre2.png

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 wink

Dernière modification par tintin02100 (2015-12-09 22:54:30)

Hors ligne

 

#2 2015-12-10 17:51:24 Re : Segmentation

Mushussu
membre
Lieu: Orléans
Date d'inscription: 2012-05-24
Messages: 792

Re: Segmentation



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

 

#3 2015-12-10 17:58:04 Re : Segmentation

tintin02100
membre
Date d'inscription: 2015-12-09
Messages: 14

Re: Segmentation



Bonjour Mushussu,

Merci pour les liens smile
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 hmm

Hors ligne

 

#4 2015-12-10 23:54:42 Re : Segmentation

Mushussu
membre
Lieu: Orléans
Date d'inscription: 2012-05-24
Messages: 792

Re: Segmentation



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

 

#5 2015-12-11 09:17:24 Re : Segmentation

tintin02100
membre
Date d'inscription: 2015-12-09
Messages: 14

Re: Segmentation



*-* Tu es fabuleux @Mushussu.
Ton code est juste magnifique !!!
Un grand merci à toi big_smile

Hors ligne

 

#6 2015-12-11 10:06:52 Re : Segmentation

Mushussu
membre
Lieu: Orléans
Date d'inscription: 2012-05-24
Messages: 792

Re: Segmentation



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

 

#7 2015-12-11 13:55:47 Re : Segmentation

tintin02100
membre
Date d'inscription: 2015-12-09
Messages: 14

Re: Segmentation



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 smile

Dernière modification par tintin02100 (2015-12-11 14:15:38)

Hors ligne

 

#8 2015-12-11 16:38:34 Re : Segmentation

tintin02100
membre
Date d'inscription: 2015-12-09
Messages: 14

Re: Segmentation



Comment modifierais tu ta fonction séparation mais pour des objets de n'importe quelle couleur?

Hors ligne

 

#9 2015-12-13 11:01:37 Re : Segmentation

Mushussu
membre
Lieu: Orléans
Date d'inscription: 2012-05-24
Messages: 792

Re: Segmentation



Voilà, j'ai tout empaqueter dans une classe.
Avec la souris tu peux sélectionner la couleur dans l'image principale.

Hors ligne

 

#10 2015-12-13 23:20:17 Re : Segmentation

tintin02100
membre
Date d'inscription: 2015-12-09
Messages: 14

Re: Segmentation



Waouw tu as sacrement bien réduit le code. Un grand merci big_smile

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.

smile

Hors ligne

 

#11 2015-12-14 09:29:13 Re : Segmentation

tintin02100
membre
Date d'inscription: 2015-12-09
Messages: 14

Re: Segmentation



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

 

#12 2015-12-14 10:34:19 Re : Segmentation

Mushussu
membre
Lieu: Orléans
Date d'inscription: 2012-05-24
Messages: 792

Re: Segmentation



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

 

#13 2015-12-14 10:43:27 Re : Segmentation

tintin02100
membre
Date d'inscription: 2015-12-09
Messages: 14

Re: Segmentation



Ci-joint le sujet smile

Hors ligne

 

#14 2015-12-14 11:23:06 Re : Segmentation

Mushussu
membre
Lieu: Orléans
Date d'inscription: 2012-05-24
Messages: 792

Re: Segmentation



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

 

#15 2015-12-14 11:50:38 Re : Segmentation

tintin02100
membre
Date d'inscription: 2015-12-09
Messages: 14

Re: Segmentation



Ca me parle pas du tour :p

Hors ligne

 

fil rss de cette discussion : rss

Pied de page des forums

Powered by FluxBB

codelab, graphisme & code : emoc / 2008-2019