00001 /// \file 00002 /// Définition de la classe Histogram 00003 00004 #include "Histogram.hpp" 00005 /////////////////////////////////////////////////////////////////////////////// 00006 /// HistogramClass 00007 /////////////////////////////////////////////////////////////////////////////// 00008 HistogramClass::HistogramClass(Color _color): 00009 color(_color), 00010 total(0) { 00011 } 00012 string HistogramClass::toString()const{ 00013 ostringstream o; 00014 o << color.toString() << " #" << data.size() << " #TOTAL " << total; 00015 return o.str(); 00016 } 00017 void HistogramClass::addPixel(Pixel pixel){ 00018 data.push_back(pixel); 00019 } 00020 int HistogramClass::getSize()const{ 00021 return data.size(); 00022 } 00023 void HistogramClass::setTotal(int _total){ 00024 total = _total; 00025 } 00026 int HistogramClass::getTotal()const{ 00027 return total; 00028 } 00029 Pixel HistogramClass::getElementAt(const int i)const{ 00030 return data[i]; 00031 } 00032 /////////////////////////////////////////////////////////////////////////////// 00033 /// Histogram 00034 /// 00035 /// Met en correspondance une couleur et sa classe 00036 /////////////////////////////////////////////////////////////////////////////// 00037 void Histogram::addPixel(Pixel pixel){ 00038 // MAJ nombre de pixel 00039 pixelNumber++; 00040 Color color = pixel.getColor(); 00041 // Cherche si la classe de cette couleur existe, sinon on la crée 00042 map_iter it = data.find(color); 00043 if(it != data.end()){ 00044 it->second.addPixel(pixel); 00045 } else { 00046 HistogramClass cl(color); 00047 cl.addPixel(pixel); 00048 data.insert(make_pair(color, cl)); 00049 } 00050 } 00051 string Histogram::toString()const{ 00052 const_map_iter b = data.begin(); 00053 const_map_iter e = data.end(); 00054 ostringstream o; 00055 while(b != e){ 00056 o << "Class " << b->first.toString() << " " << b->second.toString() << endl; 00057 b++; 00058 } 00059 return o.str(); 00060 } 00061 /// . 00062 /// Calcul de l'histogramme cumulé. On parcourt chaque classe en mettant 00063 /// à jour le total de la suivante 00064 void Histogram::makeCumul(){ 00065 map_iter b = data.begin(); 00066 map_iter e = data.end(); 00067 int total = 0; 00068 while(b != e){ 00069 total += b->second.getSize(); 00070 b->second.setTotal(total); 00071 b++; 00072 } 00073 } 00074 /// . 00075 /// Sépare l'ensemble des couleurs en un nombre classe. Le but de cette 00076 /// méthode est de fournir de bonnes valeurs de départ à l'algorithme des 00077 /// KMean 00078 void Histogram::makeClass(int classNumber){ 00079 // Calcul de la "largeur" d'une classe 00080 float delta = (float)pixelNumber / (float)classNumber; 00081 for(int i = 0; i < classNumber; i++){ 00082 float j = i; 00083 // Indice de début et fin 00084 int start = (int)(j * delta); 00085 int end = (int)(start + delta - 1); 00086 // On prent la première couleur de la classe 00087 Color c1 = getElementAt(start).getColor(); 00088 Color c2 = getElementAt(end).getColor(); 00089 Color res; 00090 /* 00091 Variant faire la moyenne des couleurs extremes 00092 if(COLOR_GRAY == c1.getType()){ 00093 float gray = (c1.getGray() + c2.getGray()) / 2; 00094 res = Color(gray); 00095 }else if(COLOR_COLOR == c1.getType()){ 00096 float h = (c1.getHue() + c2.getHue()) / 2; 00097 float s = (c1.getSaturation() + c2.getSaturation()) / 2; 00098 float v = (c1.getValue() + c2.getValue()) / 2; 00099 res = Color(h, s, v, false); 00100 } 00101 Autre variante faire la moyenne de toutes les couleurs 00102 for(int j = start + 1; j < end; j++){ 00103 Color c1 = getElementAt(j).getColor(); 00104 c = c + c1; 00105 } 00106 c = c / delta; 00107 */ 00108 res = c1; 00109 classColor.push_back(res); 00110 } 00111 } 00112 /// . 00113 /// Parcourt chaque classe jusqu'à arriver au rang demandé 00114 Pixel Histogram::getElementAt(const int i)const{ 00115 const_map_iter b = data.begin(); 00116 const_map_iter e = data.end(); 00117 00118 int total = 0; 00119 00120 while(b != e){ 00121 total += b->second.getSize(); 00122 if(total > i){ 00123 total -= b->second.getSize(); 00124 break; 00125 } 00126 b++; 00127 } 00128 int ndx = i - total; 00129 Pixel ret = b->second.getElementAt(ndx); 00130 return ret; 00131 } 00132 Color Histogram::getColor(int i)const{ 00133 return classColor[i]; 00134 }