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

Generated on Wed Apr 23 01:25:31 2014 for Hugintrunk by  doxygen 1.3.9.1