00001
00002
00003
#include "segment.hpp"
00004
00005
int main(
int argc,
char* argv[]) {
00006
if(argc == 2){
00007 string s = string(argv[1]);
00008
if(s ==
"-help"){
00009 segmentHelp();
00010
return 0;
00011 }
00012 }
00013 map<string, vector<string> > args;
00014
try{
00015 segmentOption(argc, argv, args);
00016 }
catch(runtime_error e){
00017 cout <<
"ERREUR : " << e.what() << endl;
00018 cout <<
"segment -help pour les instructions" << endl;
00019
return -1;
00020 }
00021
try{
00022 map<string, vector<string> >::iterator e = args.end();
00023 vector<string> file = args[
"output"];
00024 string name = args[
"input"][0] + args[
"input"][1];
00025 ofstream output((args[
"output"][0] +
".txt").c_str());
00026
PNG image(name);
00027 image.
read();
00028
00029 output <<
"Fichier : " << name << endl;
00030 output << image.
toString() << endl;
00031
00032 {
00033
int size = 5;
00034
float mu = 0.0;
00035
float sigma = 0.8;
00036
if(args.find(
"filtre") != e){
00037 vector<string> vals = args[
"filtre"];
00038 size = atoi(vals[0].c_str());
00039 mu = atof(vals[1].c_str());
00040 sigma = atof(vals[2].c_str());
00041 }
00042
if(args[
"msfiltre"].size() == 0){
00043
Filter_Gaussian filter(size, mu, sigma);
00044 image = filter.
apply(image);
00045 }
00046 }
00047
Node graph =
Node::CreateGraph(
"GRAPH");
00048 {
00049
if(args[
"kmean"].size() != 0){
00050
00051 vector<string> vals = args[
"kmean"];
00052
int k = atoi(vals[0].c_str());
00053
00054
KMean kmean(image, k);
00055 kmean.
doKMean();
00056
00057
00058 graph = kmean.
makeNode();
00059
00060 output <<
"KMean " << vals[0] << graph.
getNodeSize() <<
" composants, ";
00061 output << graph.
getEdgeSize() <<
" arrêtes" << endl;
00062
00063 graph.
drawPNG(file[0] +
"_kmean_segment" + file[1], 1);
00064 graph.
drawPNG(file[0] +
"_kmean_couleur" + file[1], 0);
00065 }
else if(args[
"msfiltre"].size() != 0){
00066
00067 vector<string> vals = args[
"msfiltre"];
00068
int size = atoi(vals[0].c_str());
00069
float radius = atof(vals[1].c_str());
00070
MeanShift m(size, radius, image);
00071 m.
doFilter();
00072 graph = m.
makeNode();
00073 output <<
"MeanShift filtre " << vals[0] <<
" " << vals[1] <<
" " << graph.
getNodeSize() <<
" composants, ";
00074 output << graph.
getEdgeSize() <<
" arrêtes" << endl;
00075 graph.
drawPNG(file[0] +
"_msfiltre" + file[1], 0);
00076 }
else {
00077
00078 graph =
Node::CreateGridGraph(image);
00079 output <<
"Grid graphe : " << graph.
getNodeSize() <<
" sommets, ";
00080 output << graph.
getEdgeSize() <<
" arrêtes" << endl;
00081 }
00082 }
00083 {
00084 vector<float> params;
00085
if(args[
"segment"].size() != 0){
00086 vector<string> vals = args[
"segment"];
00087
for(
int i = 0; i < vals.size(); i++){
00088
float k = atof(vals[i].c_str());
00089 params.push_back(k);
00090 }
00091
for(
int i = 0; i < params.size(); i++){
00092
Segment segment(graph, params[i]);
00093 graph = segment.
makeDisjointSet();
00094 ostringstream o;
00095 o << file[0] <<
"_segment_level_" << i;
00096 graph.
drawPNG(o.str() + file[1], 1);
00097
00098 o <<
"_color";
00099 graph.
drawPNG(o.str() + file[1], 0);
00100 o <<
"_border";
00101 graph.
drawBorderPNG(o.str() + file[1], 1);
00102 output <<
"Segment " << params[i] <<
" " << graph.
getNodeSize() <<
" composants, ";
00103 output << graph.
getEdgeSize() <<
" arrêtes" << endl;
00104 }
00105 }
else if(args[
"mint"].size() != 0){
00106 vector<string> vals = args[
"mint"];
00107
for(
int i = 0; i < vals.size(); i++){
00108
float tau = atof(vals[i].c_str());
00109 params.push_back(tau);
00110 }
00111
for(
int i = 0; i < params.size(); i++){
00112
MInt mint(graph, params[i]);
00113 graph = mint.
makeDisjointSet();
00114 ostringstream o;
00115 o << file[0] <<
"_mint_" << i;
00116 graph.
drawPNG(o.str() + file[1], 1);
00117 o <<
"_color";
00118 graph.
drawPNG(o.str() + file[1], 0);
00119 o <<
"_border";
00120 graph.
drawBorderPNG(o.str() + file[1], 1);
00121
00122 output <<
"MInt " << params[i] <<
" " << graph.
getNodeSize() <<
" composants, ";
00123 output << graph.
getEdgeSize() <<
" arrêtes" << endl;
00124 }
00125 }
else if(args[
"msfusion"].size() != 0){
00126 vector<string> vals = args[
"msfusion"];
00127
int size = atoi(vals[0].c_str());
00128
float radius = atof(vals[1].c_str());
00129
00130
MeanShiftFusion f(graph, radius);
00131 graph = f.
makeDisjointSet();
00132
00133 ostringstream o;
00134 o << file[0] <<
"_msfusion";
00135 graph.
drawPNG((o.str() +
"_segment") + file[1], 1);
00136 graph.
drawPNG(o.str() +
"_couleur" + file[1], 0);
00137 o <<
"_border";
00138 graph.
drawBorderPNG(o.str() + file[1], 1);
00139
00140
00141 output <<
"MeanShift fusion " << vals[0] <<
" " << vals[1]<<
" " << graph.
getNodeSize() <<
" composants, ";
00142 output << graph.
getEdgeSize() <<
" arrêtes" << endl;
00143
00144
00145 }
00146 }
00147 {
00148
if(args[
"prune"].size() != 0){
00149 vector<string> vals = args[
"prune"];
00150
int size = atoi(vals[0].c_str());
00151
00152
Prune p(graph, size);
00153 graph = p.
makeDisjointSet();
00154
00155 ostringstream o;
00156 o << file[0] <<
"_prune";
00157 graph.
drawPNG((o.str() +
"_segment") + file[1], 1);
00158 graph.
drawPNG(o.str() +
"_couleur" + file[1], 0);
00159 graph.
drawBorderPNG(o.str() +
"_border" + file[1], 1);
00160
00161
00162 output <<
"Prune " << graph.
getNodeSize() <<
" composants, ";
00163 output << graph.
getEdgeSize() <<
" arrêtes" << endl;
00164
00165
00166 }
00167 }
00168 output.close();
00169 }
catch(runtime_error e){
00170 cout <<
"ERREUR D'EXECUTION: " << e.what() << endl;
00171 }
00172
return 0;
00173
00174 }
00175
00176
void segmentHelp(){
00177 cout <<
"Usage : segment [options...] NomFichier [options...]" << endl;
00178 cout << endl;
00179 cout <<
"Options :" << endl;
00180 cout <<
"\t-smooth:size,mu,sigma\t" <<
"size : taille du masque (défaut 5)" << endl;
00181 cout <<
"\t\t\t\t" <<
"mu : (défaut 0.0)" << endl;
00182 cout <<
"\t\t\t\t" <<
"sigma : (défaut 0.8)" << endl;
00183 cout <<
"\t-kmean:k\t\t" <<
"k : nombre de centre du K-Mean (voir remarque)" << endl;
00184 cout <<
"\t-segment:tau1,tau2,...\t" <<
"tau 1 : constante de segmentation étape 1" << endl;
00185 cout <<
"\t\t\t\t" <<
"tau 2 : constante de segmentation étape 2" << endl;
00186 cout <<
"\t\t\t\t" <<
"..." << endl;
00187 cout <<
"\t\t\t\t" <<
"Défaut : 1 étape de segmentation avec la constante 100." << endl;
00188 cout << endl;
00189 cout <<
"Remarque :" << endl;
00190 cout <<
"\tSi on ne donne pas l'option 'kmean', on commence l'étape de " << endl;
00191 cout <<
"\tsegmentation 1 avec un grid graphe." << endl;
00192 cout << endl;
00193 cout <<
"Sortie :" << endl;
00194 cout <<
"\tLe programme produit des fichiers png en fonction des options." << endl;
00195 cout <<
"\tLe nom de chaque fichier produit correspond à une option choisie." << endl;
00196 cout << endl;
00197 cout <<
"Exemple :" << endl;
00198 cout <<
"\tsegment result/street10.png -kmean:8" << endl;
00199 cout <<
"\tproduit les fichiers suivants:" << endl;
00200 cout <<
"\tstreet10_kmean_composant.png\tcomposants trouver après le kmean" << endl;
00201 cout <<
"\tstreet10_segment_0.png\t\tcomposants trouver après 1 étape de segmentation" << endl;
00202 cout << endl;
00203 cout <<
"\tsegment result/street10.png -segment:50,100" << endl;
00204 cout <<
"\tconstruit un grid graph et produit les fichiers suivants:" << endl;
00205 cout <<
"\tstreet10_segment_0.png\t\tcomposants trouver après la 1ère segmentation" << endl;
00206 cout <<
"\tstreet10_segment_1.png\t\tcomposants trouver après la 2ème segmentation" << endl;
00207
00208
00209
00210 }
00211
void segmentOption(
int argc,
char* argv[], map<string, vector<string> > & args){
00212
00213 vector<string> options;
00214 options.push_back(
"filtre");
00215 options.push_back(
"kmean");
00216 options.push_back(
"msfiltre");
00217 options.push_back(
"segment");
00218 options.push_back(
"mint");
00219 options.push_back(
"msfusion");
00220 options.push_back(
"input");
00221 options.push_back(
"output");
00222 options.push_back(
"prune");
00223
00224
00225
00226
if(argc == 1){
00227
throw std::runtime_error(
"Pas d'arguments.");
00228 }
00229
00230
00231
bool segmentFound =
false;
00232
bool algoFound =
false;
00233
for(
int i = 1; i < argc; i++){
00234 string option(argv[i]);
00235 vector<string> vals;
00236
int i = option.find(
'-');
00237
if(i == -1){
00238
throw std::runtime_error(
"Mauvaise option " + option);
00239 }
00240 i = option.find(
':');
00241
if(i == -1){
00242
throw std::runtime_error(
"Mauvaise option " + option);
00243 }
00244 string name(option.substr(1, i - 1));
00245
if((name ==
"mint" || name ==
"segment" || name ==
"msfusion") && segmentFound){
00246
throw std::runtime_error(
"Les options de segmentation sont incompatibles!");
00247 }
00248
if((name ==
"mint" || name ==
"segment" || name ==
"msfusion") && !segmentFound){
00249 segmentFound =
true;
00250 }
00251
if((name ==
"kmean" || name ==
"msfiltre") && algoFound){
00252
throw std::runtime_error(
"Les options de segmentation sont incompatibles!");
00253 }
00254
if((name ==
"kmean" || name ==
"msfiltre") && !segmentFound){
00255 algoFound =
true;
00256 }
00257
00258
00259
bool ok =
false;
00260
for(
int j = 0; j < options.size(); j++){
00261
if(options[j] == name){
00262 ok =
true;
00263
break;
00264 }
00265 }
00266
if(!ok){
00267
throw std::runtime_error(
"L'option " + name +
" n'existe pas!");
00268 }
00269
00270 string value(option.substr(i + 1, option.size() - 1));
00271
00272
int start = 0;
00273 i = 0;
00274
while(start < value.size()){
00275
while(i < value.size() && value[i]!=
','){
00276 i++;
00277 }
00278 string aVal(value.substr(start, i - start));
00279 vals.push_back(aVal);
00280 i++;
00281 start = i;
00282 }
00283
if(name ==
"filtre" && vals.size() != 3){
00284
throw std::runtime_error(
"L'option filtre prend 3 arguments");
00285 }
else if(name ==
"kmean" && vals.size() != 1){
00286
throw std::runtime_error(
"L'option kmean prend 1 argument");
00287 }
else if(name ==
"input" && vals.size() != 1){
00288
throw std::runtime_error(
"L'option input prend 1 argument");
00289 }
else if(name ==
"output" && vals.size() != 1){
00290
throw std::runtime_error(
"L'option output prend 1 argument");
00291 }
else if(name ==
"msfiltre" && vals.size() != 2){
00292
throw std::runtime_error(
"L'option msfiltre prend 2 arguments");
00293 }
else if(name ==
"msfusion" && vals.size() != 2){
00294
throw std::runtime_error(
"L'option msfusion prend 1 argument");
00295 }
else if(name ==
"prune" && vals.size() != 1){
00296
throw std::runtime_error(
"L'option prune prend 1 argument");
00297 }
00298 args[name] = vals;
00299 }
00300
00301
00302
00303
00304
00305
if(args[
"input"].size() == 0){
00306
throw std::runtime_error(
"Pas de fichier d'entrée.");
00307 }
else {
00308 string fileName = args[
"input"][0];
00309
int pos = fileName.find(
".png");
00310
if(pos != -1){
00311 string s = fileName.substr(0, pos);
00312 args[
"input"][0] = s;
00313 s = fileName.substr(pos, fileName.size()-1);
00314 args[
"input"].push_back(s);
00315 }
else {
00316 args[
"input"].push_back(
"");
00317 }
00318 }
00319
if(args[
"output"].size() == 0){
00320 args[
"output"] = args[
"input"];
00321 }
00322 string fileName = args[
"output"][0];
00323
int pos = fileName.find(
".png");
00324
if(pos != -1){
00325 string s = fileName.substr(0, pos);
00326 args[
"output"][0] = s;
00327 s = fileName.substr(pos, fileName.size()-1);
00328 args[
"output"].push_back(s);
00329 }
else {
00330 args[
"output"].push_back(
"");
00331 }
00332 }
00333