CelesteTrain.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2008 by Tim Nugent                                      *
00003  *   timnugent@gmail.com                                                   *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
00017  ***************************************************************************/
00018 
00019 #include <iostream>
00020 #include "vigra/stdimage.hxx"
00021 #include "vigra/resizeimage.hxx"
00022 #include "vigra/impex.hxx"
00023 #include "vigra/colorconversions.hxx"
00024 #include <sys/types.h>
00025 #include <sys/stat.h>
00026 #include <stdlib.h>
00027 #include "Gabor.h"
00028 #include "Utilities.h"
00029 #include "CelesteGlobals.h"
00030 
00031 using namespace vigra; 
00032 using namespace std; 
00033 
00034 void usage (char* filename){
00035 
00036         cout << "Usage: " << filename << " <image file> <mask file>" << endl;
00037         cout << "or for a positive example: " << filename << " -p <image file>" << endl;
00038         cout << "or for a negative example: " << filename << " -n <image file>" << endl;
00039         cout << "(supported formats: " << vigra::impexListFormats() << ")" << endl;
00040 }
00041 
00042 int main(int argc, char ** argv){
00043 
00044         unsigned int a = 1;
00045         unsigned int pos = 0;
00046         unsigned int neg = 0;
00047         string image_file,mask_file;
00048         vigra::FRGBImage mask_in;
00049         vigra::FRGBImage::iterator mask_iter;
00050 
00051         // Deal with arguments
00052         if(argc < 3 || argc >= 4){
00053         
00054                 usage(argv[0]); exit(1);
00055         }
00056 
00057         while( a < argc ){
00058 
00059                 if( argv[a][0] == '-'){
00060     
00061                         a++;
00062                         switch(argv[a-1][1]){
00063 
00064                                 // Put some more argument options in here later
00065                                 case 'h' : {usage(argv[0]); exit(1);}
00066                                 case 'p' : {pos = 1;
00067                                                 cerr << "Ignoring mask. Image is a positive example." << endl;
00068                                                 image_file = argv[argc-1];
00069                                                 break;
00070                                             }
00071                                 case 'n' : {neg = 1;
00072                                                 cerr << "Ignoring mask. Image is a negative example." << endl;
00073                                                 image_file = argv[argc-1];
00074                                                 break;
00075                                                 }
00076                                 default  : {usage(argv[0]); exit(1);}
00077                         }
00078 
00079                 }
00080 
00081                 a++;
00082         }
00083 
00084         if (pos == 0 && neg == 0){
00085 
00086                 image_file = argv[argc-2];
00087                 mask_file = argv[argc-1];
00088                 
00089                 //cout << "Image is " << argv[argc-2] << endl;
00090                 //cout << "Mask is " << argv[argc-1] << endl;
00091                                 
00092         }
00093     
00094         try{
00095 
00096                 cerr << "Opening image file: " << image_file << endl;
00097 
00098                 // Read image given as first argument
00099                 // File type is determined automatically
00100                 vigra::ImageImportInfo info(image_file.c_str());
00101 
00102                 // Create RGB images of appropriate size        
00103                 vigra::FRGBImage in(info.width(), info.height());
00104 
00105                 // Import the image
00106                 importImage(info, destImage(in));
00107 
00108                 // Deal with mask unless -p || -n flags are on
00109                 if (pos == 0 && neg == 0){
00110                 
00111                         cerr << "Opening mask file:  " << mask_file << endl;
00112 
00113                         // Read mask given as second argument
00114                         vigra::ImageImportInfo mask_info(mask_file.c_str());
00115                 
00116                         // Check dimensions are the same
00117                         if (info.width() != mask_info.width() || info.height() != mask_info.height()){
00118 
00119                                 cerr << "Error - image and mask files are different dimension:" << endl;
00120                                 cerr << "Image:\t" << info.width() << " x " << info.height() << endl;
00121                                 cerr << "Mask:\t" << mask_info.width() << " x " << mask_info.height() << endl << endl;
00122                                 return 1;
00123 
00124                         }
00125                 
00126                         // Create RGB images of appropriate size        
00127                         vigra::FRGBImage tmp_mask_in(info.width(), info.height());
00128                         // Import the mask
00129                         importImage(mask_info, destImage(tmp_mask_in));
00130                         mask_in = tmp_mask_in;
00131                 
00132                 }
00133                 
00134 
00135                 // Max dimension
00136                 const int resize_dimension = 800;
00137                 
00138                 // Re-size to 800 max dimension
00139                 if (info.width() >= resize_dimension || info.height() >= resize_dimension){
00140 
00141                         // Method (0 - pixel repetition, 1 - linear, 2 - spline
00142                         // Pixel repetition seems to be the fastest
00143                         int method = 0;
00144                         double sizefactor;
00145         
00146                         if (info.width() >= info.height()){
00147                                 sizefactor = (double)resize_dimension/info.width();
00148                         }else{
00149                                 sizefactor = (double)resize_dimension/info.height();
00150                         }
00151         
00152                         // calculate new image size
00153                         int nw = (int)(sizefactor*info.width());
00154                         int nh = (int)(sizefactor*info.height());
00155  
00156                         cerr << "Image dimensions:\t" << info.width() << " x " << info.height() << endl;
00157                         cerr << "Scaling by:\t\t" << sizefactor << endl;
00158                         cerr << "New dimensions:\t\t" << nw << " x " << nh << endl;
00159         
00160                         // create a RGB image of appropriate size               
00161                         vigra::FRGBImage out(nw, nh);
00162                                     
00163                         switch(method){
00164               
00165                                 case 0:
00166                                 // resize the image, using a bi-cubic spline algorithms
00167                                 resizeImageNoInterpolation(srcImageRange(in),destImageRange(out));
00168                                 break;
00169                 
00170                                 case 1:
00171                                 // resize the image, using a bi-cubic spline algorithms
00172                                 resizeImageLinearInterpolation(srcImageRange(in),destImageRange(out));
00173                                 break;
00174                 
00175                                 default:
00176                                 // resize the image, using a bi-cubic spline algorithms
00177                                 resizeImageSplineInterpolation(srcImageRange(in),destImageRange(out));
00178                         }
00179 
00180                         in = out;
00181 
00182                         // Deal with mask unless -p || -n flags are on
00183                         if (pos == 0 && neg == 0){
00184 
00185                                 vigra::FRGBImage mask_out(nw, nh);
00186 
00187                                 switch(method){
00188               
00189                                         case 0:
00190                                         // resize the image, using a bi-cubic spline algorithms
00191                                         resizeImageNoInterpolation(srcImageRange(mask_in),destImageRange(mask_out));
00192                                         break;
00193                 
00194                                         case 1:
00195                                         // resize the image, using a bi-cubic spline algorithms
00196                                         resizeImageLinearInterpolation(srcImageRange(mask_in),destImageRange(mask_out));
00197                                         break;
00198                 
00199                                         default:
00200                                         // resize the image, using a bi-cubic spline algorithms
00201                                         resizeImageSplineInterpolation(srcImageRange(mask_in),destImageRange(mask_out));
00202                                         
00203                                 }
00204                                 
00205                                 mask_in = mask_out;
00206                         }
00207 
00208                 }else{
00209                         cerr << "Image dimensions:\t" << info.width() << " x " << info.height() << endl;
00210                 }
00211 
00212                 cerr << "Total pixels:\t\t" << in.width()*in.height() << endl;
00213         
00214                 // Convert to LUV colour space
00215                 cerr << "Converting to LUV colourspace..." << endl;             
00216                 
00217                 FRGBImage luv(in.width(),in.height());
00218                 transformImage(srcImageRange(in), destImage(luv), RGBPrime2LuvFunctor<double>() );
00219                 
00220                 // Create grid of fiducial points
00221                 cerr << "Generating fiducial points..." << endl;
00222 
00223                 for (int i = gRadius; i < in.height() - gRadius; i += spacing ){
00224                         for (int j = gRadius; j < in.width() - gRadius; j += spacing ){
00225                                 gNumLocs++;
00226                         }
00227                 }
00228 
00229                 // Create the storage matrix
00230                 gLocations = CreateMatrix( (int)0, gNumLocs, 2);
00231                 gNumLocs = 0;
00232                 for (int i = gRadius; i < in.height() - gRadius; i += spacing ){
00233                         for (int j = gRadius; j < in.width() - gRadius; j += spacing ){
00234                         
00235                                 gLocations[gNumLocs][0] = j;
00236                                 gLocations[gNumLocs][1] = i;
00237                                 
00238                                 //cerr << "fPoint " << gNumLocs << ":\t" << i << " " << j << endl;
00239                                 
00240                                 gNumLocs++;
00241                         }
00242                 }
00243                 cerr << "Total fiducial points: " << gNumLocs << endl;
00244 
00245                 // Prepare Gabor API array
00246                 float *frameBuf = new float[in.width()*in.height()];
00247                 float *u_values = new float[in.width()*in.height()];
00248                 float *v_values = new float[in.width()*in.height()];
00249                 
00250                 
00251                 float** pixels = CreateMatrix( (float)0, in.height(), in.width() );
00252 
00253                 // Do something with each pixel...
00254                 int counter = 0;
00255                 vigra::FRGBImage::iterator img_iter(luv.begin()),end(luv.end());
00256                 for(; img_iter != end; ++img_iter) {
00257 
00258                         // [0] is L, [1] is U, [2] is V
00259                         // We only want L for Gabor filtering
00260                         frameBuf[counter] = (*img_iter)[0];
00261                         
00262                         u_values[counter] = (*img_iter)[1];
00263                         v_values[counter] = (*img_iter)[2];
00264                 
00265                         //cout << "Pixel " << counter << " - L: " << (*img_iter)[0] << endl;
00266                         //cout << "Pixel " << counter << " - U: " << (*img_iter)[1] << endl;
00267                         //cout << "Pixel " << counter << " - V: " << (*img_iter)[2] << endl;
00268                         counter++;
00269                 }
00270 
00271 
00272                 int k = 0;
00273                 for (int i = 0; i < in.height(); i++ ){
00274                         for (int j = 0; j < in.width(); j++ ){
00275                                 pixels[i][j] = frameBuf[k];
00276                                 //cout << i << " " << j << " = " << k << " - " << frameBuf[k] << endl;
00277                                 k++;
00278                         }
00279                 }
00280 
00281                 char basename[] = "gabor_filters/celeste"; 
00282 
00283                 float *response = NULL;
00284                 int len = 0;
00285 
00286                 response = ProcessChannel( pixels, in.height(), in.width(), response, &len, basename );
00287 
00288                 // Deal with mask unless -p || -n flags are on
00289                 if (pos == 0 && neg == 0){
00290                 
00291                         // Iterator for mask
00292                         vigra::FRGBImage::iterator tmp_mask_iter(mask_in.begin()),mask_end(mask_in.end());
00293                         mask_iter = tmp_mask_iter;
00294                         mask_end = NULL;
00295                 }
00296                 
00297                 cerr << "Generating feature vector by Gabor filtering..." << endl;
00298                 
00299                 // Do something nice with response
00300                 int vector_length = (int)len/gNumLocs;
00301                 for ( int j = 0; j < gNumLocs; j++ ){
00302                         
00303                         //cerr << gLocations[j][0] << "," << gLocations[j][1] << endl;
00304                         
00305                         int pixel_number = gLocations[j][0] + (in.width() * (gLocations[j][1] - 1)) - 1;
00306 
00307                         // Apply label                  
00308                         if (pos){
00309                                 cout << "+1 ";
00310                         }else if (neg){
00311                                 cout << "-1 ";
00312                         }else{
00313                                 // In the mask, clouds are black, non-clouds are white
00314                                 if (mask_iter[pixel_number][0] != 0 || mask_iter[pixel_number][1] != 0 || mask_iter[pixel_number][2] != 0){
00315                                         // So this must be non-cloud = -ve example
00316                                         cout << "-1 ";
00317                                 }else{
00318                                         // So this must be cloud = +ve example
00319                                         cout << "+1 ";
00320                                 }                       
00321                         }
00322 
00323                         int feature = 1;
00324                         for ( int v = (j * vector_length); v < ((j + 1) * vector_length); v++){
00325                                 cout << feature << ":" << response[v] << " ";
00326                                 feature++;
00327                         }
00328 
00329                         // Work out average colour - U + V channels
00330                         
00331                         float u_sum = 0, v_sum = 0;
00332                         int pixels_in_region = (gRadius * 2)*(gRadius * 2);
00333                         
00334                         // height
00335                         //cout << endl << "Pixel " << pixel_number << " x:" << gLocations[j][0] << " y:" <<
00336                         //gLocations[j][1] << " width: " <<  in.width() << endl;
00337                         
00338                         for (int t = 1 - gRadius; t <= gRadius; t++){                   
00339                         
00340                                 int this_y_pixel = pixel_number + (t * in.width());
00341                                 //cout << "t = " << t << " pixel= " << pixel_number << " + " << (t * in.width()) << endl;
00342                                 // width
00343                                 for (int r = 1 - gRadius; r <= gRadius; r++){                   
00344                         
00345                                         int this_x_pixel = this_y_pixel + r;
00346                                         
00347                                         //if (this_x_pixel == pixel_number){
00348                                         //      cout << "*" << this_x_pixel << "* ";
00349                                         //}else{
00350                                         //      cout << this_x_pixel << " ";
00351                                         //}
00352                                         
00353                                         u_sum += u_values[this_x_pixel];
00354                                         v_sum += v_values[this_x_pixel];
00355                                         
00356                                         //cout << "u = " << u_values[this_x_pixel] << "(" << u_sum << ")" << endl;
00357                                         //cout << "v = " << v_values[this_x_pixel] << "(" << v_sum << ")" << endl;
00358                         
00359                                 }
00360                                 //cout << endl;
00361                         }
00362                         //cout << endl;
00363 
00364                         float u_ave = (float)u_sum/pixels_in_region;
00365                         float v_ave = (float)v_sum/pixels_in_region;
00366 
00367                         // Now work out standard deviation for U and V channels
00368                         u_sum = 0, v_sum = 0;
00369 
00370                         for (int t = 1 - gRadius; t <= gRadius; t++){                   
00371                                 int this_y_pixel = pixel_number + (t * in.width());
00372                                 
00373                                 for (int r = 1 - gRadius; r <= gRadius; r++){                   
00374                         
00375                                         int this_x_pixel = this_y_pixel + r;
00376                                         
00377                                         u_sum +=  pow(u_values[this_x_pixel]-u_ave,2);
00378                                         v_sum +=  pow(v_values[this_x_pixel]-v_ave,2);
00379 
00380                                 }
00381                         }
00382                         
00383                         
00384                         float std_u = sqrt(u_sum/(pixels_in_region-1));
00385                         float std_v = sqrt(v_sum/(pixels_in_region-1)); 
00386                         
00387                         //cerr << "U sum = " << u_sum << " U ave = " << u_ave << " U std = " << std_u << endl;
00388                         //cerr << "V sum = " << v_sum << " V ave = " << v_ave << " V std = " << std_v << endl << endl;
00389                         
00390                         cout << feature << ":" << u_ave << " ";
00391                         feature++;
00392                         cout << feature << ":" << std_u << " ";
00393                         feature++;
00394                         cout << feature << ":" << v_ave << " ";
00395                         feature++;
00396                         cout << feature << ":" << std_v << " ";
00397                         feature++;                              
00398 
00399                         // Add the U/V values for this actual pixel
00400 
00401                         cout << feature << ":" << u_values[pixel_number] << " ";
00402                         feature++;
00403                         cout << feature << ":" << v_values[pixel_number] << " ";
00404                         feature++;                                      
00405                                 
00406                                 
00407                         //cout << "# FP_" << j << "_Pixel_" << pixel_number << "_Pos_" << gLocations[j][0] << "-" << gLocations[j][1] <<
00408                         //"_Mask_RGB_" << mask_iter[pixel_number][0] << "," << mask_iter[pixel_number][1] << "," <<
00409                         //mask_iter[pixel_number][2] << endl;
00410                         cout << endl;
00411                 }
00412 
00413                 delete[] response;
00414                 delete[] frameBuf;
00415         delete[] u_values;
00416         delete[] v_values;
00417 
00418                 // Export images
00419                 //exportImage(srcImageRange(in), ImageExportInfo("output_images/image_reduced.jpg"));
00420                 //exportImage(srcImageRange(luv), ImageExportInfo("output_images/luv_reduced.jpg"));
00421                 //
00422                 //if (pos == 0 && neg == 0){
00423                 //      exportImage(srcImageRange(mask_in), ImageExportInfo("output_images/mask_reduced.jpg"));
00424                 //}
00425                         
00426                 //cout << "Done." << endl;
00427         
00428         }catch (vigra::StdException & e){
00429         
00430                 // catch any errors that might have occured and print their reason
00431                 std::cout << e.what() << std::endl;
00432                 return 1;
00433                 
00434         }
00435     
00436         return 0;
00437         
00438 }

Generated on 29 Jul 2015 for Hugintrunk by  doxygen 1.4.7