Page principale | Hiérarchie des classes | Liste des classes | Liste des fichiers | Membres de classe | Membres de fichier

PixelMap.cpp

Aller à la documentation de ce fichier.
00001 /// \file 00002 /// Implémentation de la classe PixelMap 00003 #include "PixelMap.hpp" 00004 /////////////////////////////////////////////////////////////////////////////// 00005 /// Labelise un tableau de pixel 00006 /////////////////////////////////////////////////////////////////////////////// 00007 PixelMap::PixelMap(int _width, int _height): 00008 width(_width), 00009 height(_height){ 00010 data.resize(width * height); 00011 parent.resize(width * height); 00012 border.resize(width * height); 00013 } 00014 string PixelMap::toString(){ 00015 string ret; 00016 for(int i = 0; i < data.size(); i++){ 00017 ret += data[i].toString() + "\n"; 00018 } 00019 return ret; 00020 } 00021 void PixelMap::addPixel(Pixel pixel){ 00022 data[pixel.getX() + pixel.getY() * width] = pixel; 00023 } 00024 void PixelMap::addPixel(Pixel pixel, int label){ 00025 data[pixel.getX() + pixel.getY() * width] = pixel; 00026 parent[pixel.getX() + pixel.getY() * width] = label; 00027 } 00028 ///. 00029 /// Produit un graphe à partir d'un tableau de pixel 00030 /// On crée le graphe en effectuant une recherche en largeur 00031 Node PixelMap::makeComponent(){ 00032 Trace trace("makeComponent", channelPixelMap); 00033 trace.print("Création des composants"); 00034 // Valeur de retour 00035 Node ret = Node::CreateGraph("ROOT"); 00036 // Labels initialisés à -1 00037 parent.clear(); 00038 for(int i = 0; i < data.size(); i++){ 00039 parent.push_back(-1); 00040 } 00041 // Les composants 00042 vector<Node> component; 00043 // Compteur 00044 int count = 0; 00045 // On parcourt les pixels 00046 for(int i = 0; i < data.size(); i++){ 00047 // Si un pixel a déjà un label on continue 00048 if(parent[i] != -1){ 00049 continue; 00050 } 00051 // Label du pixel et création d'un cluster 00052 parent[i] = count; 00053 ostringstream o; 00054 o << "COMPONENT " << count; 00055 Node comp = Node::CreateGraph(o.str()); 00056 // Association du pixel au cluster 00057 comp.setPixel(data[i]); 00058 // Liste auxiliaire 00059 list<Pixel> aux; 00060 // On ajoute le point à la liste à parcourir 00061 aux.push_back(data[i]); 00062 // On crée une feuille pour le pixel 00063 Node leaf = Node::CreateLeaf(); 00064 leaf.setPixel(data[i]); 00065 // On l'ajoute au cluster 00066 comp.addNode(leaf); 00067 // On parcourt les voisins 00068 // Pour chaque voisin à explorer on regarde si sa couleure 00069 // est identique au point courant 00070 while(!aux.empty()){ 00071 // On récupère le point 00072 Pixel current = aux.front(); 00073 // Et on l'élimine de la liste 00074 aux.pop_front(); 00075 // Position dans l'image 00076 int rank = (current.getX() + width * current.getY()); 00077 // en haut 00078 if((rank / width) != 0){ 00079 Pixel p = data[rank - width]; 00080 if((parent[rank - width] == -1) && p.getColor() == current.getColor()){ 00081 parent[rank - width] = count; 00082 aux.push_back(p); 00083 Node leaf = Node::CreateLeaf(); 00084 leaf.setPixel(p); 00085 comp.addNode(leaf); 00086 } 00087 } 00088 // a gauche 00089 if((rank % width) != 0){ 00090 Pixel p = data[rank - 1]; 00091 if((parent[rank - 1] == -1) && p.getColor() == current.getColor()){ 00092 parent[rank - 1] = count; 00093 aux.push_back(p); 00094 Node leaf = Node::CreateLeaf(); 00095 leaf.setPixel(p); 00096 comp.addNode(leaf); 00097 } 00098 } 00099 // a droite 00100 if((rank % width) != width -1){ 00101 Pixel p = data[rank + 1]; 00102 if((parent[rank + 1] == -1) && p.getColor() == current.getColor()){ 00103 parent[rank + 1] = count; 00104 aux.push_back(p); 00105 Node leaf = Node::CreateLeaf(); 00106 leaf.setPixel(p); 00107 comp.addNode(leaf); 00108 } 00109 } 00110 // en bas 00111 if((rank / width) != height -1){ 00112 Pixel p = data[rank + width]; 00113 if((parent[rank + width] == -1) && p.getColor() == current.getColor()){ 00114 parent[rank + width] = count; 00115 aux.push_back(p); 00116 Node leaf = Node::CreateLeaf(); 00117 leaf.setPixel(p); 00118 comp.addNode(leaf); 00119 } 00120 } 00121 } 00122 // composant ajouter au graphe 00123 ret.addNode(comp); 00124 component.push_back(comp); 00125 count++; 00126 } 00127 // On a les composants, maintenant on cherche les arrêtes 00128 // d'adjacence entre composant. Lorsqu'on ajoute une arrête 00129 // on MAJ des données diverses et en particulier les coordonnées 00130 // de départ et d'arrivée de l'arrête. 00131 trace.print("Création des arrêtes"); 00132 typedef pair<int, int> aPair; 00133 map< aPair , Edge> table; 00134 typedef map< aPair , Edge>::iterator table_iter; 00135 // on cherche les noeuds frontières 00136 for(int i = 0; i < (height - 1); i++){ 00137 for(int j = 0; j < (width - 1); j++){ 00138 // noeud (j, i) 00139 Pixel p1 = data[i * width + j]; 00140 int parent1 = parent[i * width + j]; 00141 // noeud (j + 1, i) 00142 Pixel p2 = data[i * width + j + 1]; 00143 int parent2 = parent[i * width + j + 1]; 00144 // noeud (j, i + 1) 00145 Pixel p3 = data[(i + 1) * width + j]; 00146 int parent3 = parent[(i + 1) * width + j]; 00147 // noeud (j + 1, i + 1) 00148 Pixel p4 = data[(i + 1) * width + j + 1]; 00149 int parent4 = parent[(i + 1) * width + j + 1]; 00150 if(parent1 != parent2){ 00151 // On regarde si l'arrête entre cluster est déjà présente 00152 aPair pair1 = make_pair(parent1, parent2); 00153 aPair pair2 = make_pair(parent2, parent1); 00154 table_iter b1 = table.find(pair1); 00155 table_iter b2 = table.find(pair2); 00156 table_iter e = table.end(); 00157 if((table.size() == 0) || ((b1 == e) && (b2 == e)) ){ 00158 // On l'insère 00159 float weight = p1.getColor().distance(p2.getColor()); 00160 Edge e(component[parent1], component[parent2], weight); 00161 int x0 = p1.getX(); 00162 int y0 = p1.getY(); 00163 int x1 = p2.getX(); 00164 int y1 = p2.getY(); 00165 e.setCoord(x0, y0, x1, y1); 00166 ret.addEdge(e); 00167 table.insert(make_pair(pair1, e)); 00168 } 00169 } 00170 if(parent1 != parent3){ 00171 // On regarde si l'arrête entre cluster est déjà présente 00172 aPair pair1 = make_pair(parent1, parent3); 00173 aPair pair2 = make_pair(parent3, parent1); 00174 table_iter b1 = table.find(pair1); 00175 table_iter b2 = table.find(pair2); 00176 table_iter e = table.end(); 00177 if((table.size() == 0) || ((b1 == e) && (b2 == e)) ){ 00178 // On l'insère 00179 float weight = p1.getColor().distance(p3.getColor()); 00180 Edge e(component[parent1], component[parent3], weight); 00181 int x0 = p1.getX(); 00182 int y0 = p1.getY(); 00183 int x1 = p3.getX(); 00184 int y1 = p3.getY(); 00185 e.setCoord(x0, y0, x1, y1); 00186 ret.addEdge(e); 00187 table.insert(make_pair(pair1, e)); 00188 } 00189 } 00190 if(parent1 != parent4){ 00191 // On regarde si l'arrête entre cluster est déjà présente 00192 aPair pair1 = make_pair(parent1, parent4); 00193 aPair pair2 = make_pair(parent4, parent1); 00194 table_iter b1 = table.find(pair1); 00195 table_iter b2 = table.find(pair2); 00196 table_iter e = table.end(); 00197 if((table.size() == 0) || ((b1 == e) && (b2 == e)) ){ 00198 // On l'insère 00199 float weight = p1.getColor().distance(p4.getColor()); 00200 Edge e(component[parent1], component[parent4], weight); 00201 int x0 = p1.getX(); 00202 int y0 = p1.getY(); 00203 int x1 = p4.getX(); 00204 int y1 = p4.getY(); 00205 e.setCoord(x0, y0, x1, y1); 00206 ret.addEdge(e); 00207 table.insert(make_pair(pair1, e)); 00208 } 00209 } 00210 if(j > 0){ 00211 // On regarde si l'arrête entre cluster est déjà présente 00212 // noeud (j - 1 1, i + 1) 00213 Pixel p5 = data[(i + 1) * width + j - 1]; 00214 int parent5 = parent[(i + 1) * width + j - 1]; 00215 if(parent1 != parent5){ 00216 // On l'insère 00217 aPair pair1 = make_pair(parent1, parent5); 00218 aPair pair2 = make_pair(parent5, parent1); 00219 table_iter b1 = table.find(pair1); 00220 table_iter b2 = table.find(pair2); 00221 table_iter e = table.end(); 00222 if((table.size() == 0) || ((b1 == e) && (b2 == e)) ){ 00223 float weight = p1.getColor().distance(p5.getColor()); 00224 Edge e(component[parent1], component[parent5], weight); 00225 int x0 = p1.getX(); 00226 int y0 = p1.getY(); 00227 int x1 = p5.getX(); 00228 int y1 = p5.getY(); 00229 e.setCoord(x0, y0, x1, y1); 00230 ret.addEdge(e); 00231 table.insert(make_pair(pair1, e)); 00232 } 00233 } 00234 } 00235 } 00236 } 00237 { 00238 ostringstream o; 00239 o << "Nombre de composants " << ret.getNodeSize() << endl; 00240 trace.print(o.str()); 00241 } 00242 { 00243 ostringstream o; 00244 o << "Nombre d'arrêtes " << ret.getEdgeSize() << endl; 00245 trace.print(o.str()); 00246 } 00247 return ret; 00248 } 00249 void PixelMap::findBorder(){ 00250 Trace("findBorder", channelPixelMap); 00251 vector<bool> visited; 00252 for(int i = 0; i < data.size(); i++){ 00253 visited.push_back(false); 00254 } 00255 border.clear(); 00256 for(int i = 0; i < (height - 1); i++){ 00257 for(int j = 0; j < (width - 1); j++){ 00258 if(visited[i * width + j]){ 00259 continue; 00260 } 00261 visited[i * width + j] = true; 00262 // noeud (j, i) 00263 int parent1 = parent[i * width + j]; 00264 // noeud (j + 1, i) 00265 int parent2 = parent[i * width + j + 1]; 00266 // noeud (j, i + 1) 00267 int parent3 = parent[(i + 1) * width + j]; 00268 // noeud (j + 1, i + 1) 00269 int parent4 = parent[(i + 1) * width + j + 1]; 00270 if(parent1 != parent2){ 00271 border[i * width + j + 1] = true; 00272 visited[i * width + j + 1] = true; 00273 } 00274 if(parent1 != parent3){ 00275 border[(i + 1) * width + j] = true; 00276 visited[(i + 1) * width + j] = true; 00277 } 00278 if(parent1 != parent4){ 00279 border[(i + 1) * width + j + 1] = true; 00280 visited[(i + 1) * width + j + 1] = true; 00281 } 00282 if(j > 0){ 00283 int parent5 = parent[(i + 1) * width + j - 1]; 00284 if(parent1 != parent5){ 00285 border[(i + 1) * width + j - 1] = true; 00286 visited[(i + 1) * width + j - 1] = true; 00287 } 00288 } 00289 } 00290 } 00291 } 00292 void PixelMap::drawBorderPNG(string fileName){ 00293 Trace("drawBorder", channelPixelMap); 00294 findBorder(); 00295 PNG output(width, height, PNG_GRAY, fileName); 00296 Color color; 00297 Color black(0); 00298 Color gray(225); 00299 for(int i = 0; i < data.size(); i++){ 00300 Pixel pix = data[i]; 00301 if(border[i]){ 00302 color = black; 00303 } else { 00304 color = gray; 00305 } 00306 output.setColor(pix.getX(), pix.getY(), color); 00307 } 00308 output.write(); 00309 00310 } 00311 00312 void PixelMap::parentToFile(string fileName)const{ 00313 ofstream o(fileName.c_str()); 00314 for(int i = 0; i < parent.size(); i++){ 00315 o << parent[i] << endl; 00316 } 00317 o.close(); 00318 } 00319

Généré le Sun Jun 27 15:59:32 2004 pour segment par doxygen 1.3.7