Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

phANNSystem.cpp

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------
00002     Phission : 
00003         Realtime Vision Processing System
00004     
00005     Copyright (C) 2003-2005 Philip D.S. Thoren (pthoren@cs.uml.edu)
00006     University of Massachusetts at Lowell,
00007     Laboratory for Artificial Intelligence and Robotics
00008     
00009     This file is part of Phission.
00010 
00011  ---------------------------------------------------------------------------*/
00012 #include <time.h>
00013 #include <phANNSystem.h>
00014 #include <autoblob_Filter.h>
00015 #include <random_selection.h>
00016 
00017 #define PRE_RESIZE_CANNY_INPUT() 1
00018 #define PRE_RESIZE_SOBEL_INPUT() 1
00019 #define PRE_RESIZE_HIST_INPUT() 0
00020 
00021 /* ------------------------------------------------------------------------ */
00022 #ifdef __cplusplus
00023 extern "C" {
00024 #endif
00025 
00026 /* ------------------------------------------------------------------------ *
00027  * This randomizes the pixels of the image. 
00028  *
00029  * Make sure srand48(time(NULL)) or something equivalent is called at some 
00030  * point before invoking this function. This ensures that the image is 
00031  * random.
00032  *
00033  * Try not to call srand48 EVERY single time randomize_image is invoked if 
00034  * the function is invoked in a loop. Try to call srand48 once before the 
00035  * loop is started. 
00036  * ------------------------------------------------------------------------ */
00037 int randomize_pixels( uint32_t width,
00038                      uint32_t height,
00039                      uint32_t format,
00040                      phImage  *image )
00041 {
00042     phFUNCTION("randomize_image")
00043     uint8_t *imgptr     = NULL;
00044     uint32_t i          = 0;
00045     uint32_t limit      = 0;
00046 
00047     rc  = image->allocate(width,height,format);
00048     phCHECK_RC(rc,NULL,"image->allocate");
00049 
00050     imgptr = (uint8_t *)image->getImage();
00051 
00052     limit = image->getSize();
00053     
00054     for (i = 0; i < limit; i++ )
00055     {
00056         *imgptr = lrand48() % 256;
00057         imgptr++;
00058     }   
00059         
00060     return phSUCCESS;
00061 error:
00062     return phFAIL;
00063 }
00064  
00065 /* ------------------------------------------------------------------------ */
00066 int random_gradient( uint32_t width,
00067                   uint32_t height,
00068                   uint32_t format,
00069                   phImage  *image )
00070 {
00071     phFUNCTION("random_gradient")
00072     uint8_t *imgptr     = NULL;
00073     uint32_t i          = 0;
00074     uint32_t j          = 0;
00075     uint32_t limit      = 0;
00076     uint32_t depth      = 0;
00077     int32_t  pixel[phCOLOR_MAXELEMS];
00078     int32_t  pixval     = 0;
00079     int32_t  pixchng    = 0;
00080 
00081 
00082     rc  = image->allocate(width,height,format);
00083     phCHECK_RC(rc,NULL,"image->allocate");
00084 
00085     imgptr = (uint8_t *)image->getImage();
00086 
00087     depth = phImageFormatToDepth(format);
00088     for (i = 0; i < depth; i++ )
00089     {
00090         pixel[i] = lrand48() % 256;
00091     }
00092     
00093     limit = image->getSize() / depth;
00094     
00095     for (i = 0; i < limit; i++ )
00096     {
00097         /* Random pixel channel adjustment */
00098         pixchng = (lrand48() % 16) - 8;
00099         
00100         /* Random value change */
00101         for (j = 0; j < depth; j++ )
00102         {
00103             pixval = pixel[j] + pixchng;
00104 
00105             if (pixval < 0) 
00106                 pixval = 256 - pixval;
00107             else if (pixval > 255) 
00108                 pixval = pixval % 256;
00109 
00110             /* Assign the new value to the image*/
00111             pixel[j] = *imgptr = pixval;
00112            
00113             imgptr++;
00114         }
00115     }   
00116         
00117     return phSUCCESS;
00118 error:
00119     return phFAIL;
00120 }   
00121 
00122 /* ------------------------------------------------------------------------ */
00123 int random_image( uint32_t width,
00124                   uint32_t height,
00125                   uint32_t format,
00126                   phImage  *image )
00127 {
00128     phFUNCTION("random_image")
00129     uint8_t *imgptr     = NULL;
00130     uint32_t i          = 0;
00131     uint32_t j          = 0;
00132     uint32_t k          = 0;
00133     uint32_t depth      = 0;
00134     int      use_object_pixel = 0;
00135     uint32_t width_left = 0;
00136     uint32_t width_mid  = 0;
00137     int32_t  *pixel     = NULL;
00138     int32_t  object_pixel[phCOLOR_MAXELEMS];
00139     int32_t  notobj_pixel[phCOLOR_MAXELEMS];
00140     int32_t  pixval     = 0;
00141     int32_t  pixchng    = 0;
00142     uint32_t start_format = phImageRGB24;
00143 
00144     rc  = image->allocate(width,height,start_format);
00145     phCHECK_RC(rc,NULL,"image->allocate");
00146 
00147     imgptr = (uint8_t *)image->getImage();
00148 
00149     depth = phImageFormatToDepth(start_format);
00150     for (i = 0; i < depth; i++ )
00151     {
00152         object_pixel[i] = lrand48() % 250;
00153         notobj_pixel[i] = lrand48() % 250;
00154     }
00155     
00156     use_object_pixel = 0;
00157     pixel = notobj_pixel;
00158 
00159     for (i = 0; i < height; i++ )
00160     {
00161         width_left = lrand48() % (width - (width / 2));
00162         width_mid  = (lrand48() % (width - width_left));
00163         for (j = 0; j < width; j++ )
00164         {
00165             /* if the random number generator hits 1,
00166              * then use one pixel color, otherwise use the other */
00167             if (j == width_left)
00168                 pixel = object_pixel;
00169             else if (j == (width_left + width_mid))
00170                 pixel = notobj_pixel;
00171             
00172             /* Random pixel channel adjustment */
00173             pixchng = (lrand48() % 8) - 4;
00174             
00175             /* Random value change */
00176             for (k = 0; k < depth; k++ )
00177             {
00178                 pixval = pixel[k] + pixchng;
00179                 
00180                 if (pixval < 0) 
00181                     pixval = 256 - pixval;
00182                 else if (pixval > 255) 
00183                     pixval = pixval % 256;
00184                 
00185                 /* Assign the new value to the image*/
00186                 *imgptr = pixval;
00187                 
00188                 imgptr++;
00189             }
00190         }   
00191     }
00192 
00193     rc = image->convert(format);
00194     phCHECK_RC(rc,NULL,"image->convert(%s)",
00195                 phImageFormatToString(format));
00196     
00197     return phSUCCESS;
00198 error:
00199     return phFAIL;
00200 }   
00201 
00202 #ifdef __cplusplus
00203 }
00204 #endif
00205 /* ------------------------------------------------------------------------ */
00206 phANNSystem::phANNSystem( image_data_collection data, int32_t flags )
00207 {
00208     phFUNCTION("phANNSystem::phANNSystem")
00209 
00210     /* if the input flag if 0, set it to be all the inputs */
00211     if (flags == 0)   flags = phML_ALL;
00212     this->m_flags           = flags;    
00213     
00214     this->m_img_inputs      = 0;
00215     this->m_indiv_inputs    = 0;
00216     this->m_data            = data;
00217     this->m_width           = idc_get_width( data ); 
00218     this->m_height          = idc_get_height( data ); 
00219     
00220     this->m_bright          = NULL;
00221     this->m_bright_stepping =   10;
00222     this->m_bright_level    =   0;
00223     
00224     this->m_canny_resize    = NULL;
00225     this->m_sobel_resize    = NULL;
00226     
00227     this->m_hist_resize     = NULL;
00228     this->m_histograms      = NULL;
00229     this->m_histogram_data  = NULL;
00230     this->m_histogram_bins  = 32;
00231     this->m_hsv_convert     = NULL;
00232     
00233     this->m_canny           = NULL;
00234     this->m_canny_grey_conv = NULL;
00235     
00236     this->m_sobel           = NULL;
00237     this->m_sobel_grey_conv = NULL;
00238 
00239     this->m_system          = NULL;
00240     this->m_pipelines       = NULL;
00241     this->m_displays        = NULL;
00242 
00243     this->m_width_box       = 1.8;
00244     this->m_height_box      = 1.4;
00245     
00246     /* Count up the number of inputs according to the flags */
00247     if (flags & phML_RGB)     this->m_img_inputs += 3;
00248     if (flags & phML_HSV)     this->m_img_inputs += 3;
00249     if (flags & phML_CANNY)   this->m_img_inputs += 1;
00250     if (flags & phML_SOBEL)   this->m_img_inputs += 1;
00251     if (flags & phML_GREY)    this->m_img_inputs += 1;
00252     if (flags & phML_RATIO)   this->m_indiv_inputs += 1;
00253     if (flags & phML_HISTRGB) 
00254             this->m_indiv_inputs += (this->m_histogram_bins * 3);/*6*/
00255     if (flags & phML_HISTHSV)
00256             this->m_indiv_inputs += (this->m_histogram_bins * 3);/*6*/
00257 
00258     this->m_total_histograms= 0;
00259     this->m_histrgb_index   = 0;
00260     this->m_histhsv_index   = 0;
00261  
00262     this->m_total_pipelines = 0;
00263     this->m_bright_pipe     = this->m_total_pipelines++;
00264     this->m_canny_pipe      = this->m_total_pipelines++;
00265     this->m_sobel_pipe      = this->m_total_pipelines++;
00266     this->m_hist_pipe       = this->m_total_pipelines++;
00267     
00268     this->m_no_displays     = 0;
00269     this->m_total_displays  = 0;
00270     this->m_img_disp        = this->m_total_displays++;
00271     this->m_canny_disp      = this->m_total_displays++;
00272     this->m_sobel_disp      = this->m_total_displays++;
00273     this->m_histrgb_disp    = this->m_total_displays++;
00274     this->m_histhsv_disp    = this->m_total_displays++;
00275    
00276     this->m_total_images    = 0;
00277     this->m_input_image     = this->m_total_images++;
00278     this->m_rgb_image       = this->m_total_images++;
00279     this->m_hsv_image       = this->m_total_images++;
00280     this->m_grey_image      = this->m_total_images++;
00281     this->m_canny_image     = this->m_total_images++;
00282     this->m_sobel_image     = this->m_total_images++;
00283 
00284     this->m_ptr_count           = 0;
00285     this->m_ptr_array           = NULL;
00286     this->m_ptr_size_array      = NULL;
00287     this->m_ptr_stepping_array  = NULL;
00288     this->m_ptr_name_array      = NULL;
00289 
00290     rc = this->allocate();
00291     phPRINT_RC(rc,NULL,"this->allocate()");
00292 
00293     rc = this->connect_elements();
00294     phPRINT_RC(rc,NULL,"this->connect_elements()");
00295 
00296     rc = this->add_filters();
00297     phPRINT_RC(rc,NULL,"this->add_filters()");
00298 
00299     /* ANN stuff */
00300     this->m_training_algorithm = FANN_TRAIN_RPROP;
00301     this->m_connection_rate = 0.7;
00302     this->m_learning_rate   = 0.7;
00303     this->m_num_layers      = 3;
00304     this->m_num_hidden      = 3;
00305     this->m_num_output      = idc_get_ntags( this->m_data );
00306     this->m_ann_source      = 0;
00307     this->m_ann             = NULL;
00308 
00309     this->m_ann_file        = (char *)phCalloc(256,sizeof(char));
00310     phPRINT_PTR(this->m_ann_file,"phCalloc","phCalloc failed.");
00311 
00312     this->m_logfp           = NULL;
00313     this->m_logfile         = (char *)phCalloc(256,sizeof(char));
00314     phPRINT_PTR(this->m_logfile,"phCalloc","phCalloc failed.");
00315 
00316     this->m_ann_datafile    = (char *)phCalloc(256,sizeof(char));
00317     phPRINT_PTR(this->m_ann_datafile,"phCalloc","phCalloc failed.");
00318 
00319     this->m_input_nodes       = NULL;
00320     this->m_input_nodes_size  = 0;
00321     this->m_input_nodes_count = 0;
00322     this->m_output_nodes      = NULL;
00323     this->m_output_nodes_size = 0;
00324     this->m_output_nodes_count= 0;
00325     this->m_image_ratio       = 0.0;
00326 }
00327 
00328 /* ------------------------------------------------------------------------ */
00329 phANNSystem::~phANNSystem( )
00330 {
00331     phFUNCTION("phANNSystem::~phANNSystem")
00332     uint32_t i = 0;
00333 
00334     this->closeLogFile();
00335 
00336     phFree(this->m_input_nodes);
00337     phFree(this->m_output_nodes);
00338 
00339     rc = this->destroyNetwork();
00340     phPRINT_RC(rc,NULL,"this->destroyNetwork()");
00341 
00342     phFree(this->m_ann_file);
00343     phFree(this->m_logfile);
00344     phFree(this->m_ann_datafile);
00345     
00346     phFree(this->m_ptr_array);
00347     phFree(this->m_ptr_size_array);
00348     phFree(this->m_ptr_stepping_array);
00349     phFree(this->m_ptr_name_array);
00350 
00351     phDelete(this->m_system);
00352     phDelete(this->m_canny);
00353     phDelete(this->m_sobel);
00354     phDelete(this->m_hsv_convert);
00355     phDelete(this->m_bright);
00356     phDelete(this->m_gauss);
00357     phDelete(this->m_hist_resize);
00358     
00359     phDelete(this->m_canny_resize);
00360     phDelete(this->m_sobel_resize);
00361     
00362     for (i = 0; i < this->m_total_histograms; i++ )
00363     {
00364         phDelete(this->m_histograms[i]);
00365         phDelete(this->m_histogram_data[i]);
00366     }
00367     phDeleteArray(this->m_histograms);
00368     phDeleteArray(this->m_histogram_data);
00369     
00370     for (i = 0; i < this->m_total_displays; i++ )
00371     {
00372         phDelete(this->m_displays[i]);
00373     }
00374     phDeleteArray(this->m_displays);
00375 
00376     for (i = 0; i < this->m_total_pipelines; i++ )
00377     {
00378         phDelete(this->m_pipelines[i]);
00379     }
00380     phDeleteArray(this->m_pipelines);
00381     
00382     for (i = 0; i < this->m_total_images; i++ )
00383     {
00384         phDelete(this->m_images[i]);
00385     }
00386     phDeleteArray(this->m_images);
00387 }
00388 
00389 /* ------------------------------------------------------------------------ */
00390 int phANNSystem::allocate( )
00391 {
00392     phFUNCTION("phANNSystem::allocate")
00393     uint32_t i = 0;
00394     uint32_t x = 0;
00395     uint32_t y = 0;
00396 
00397     /* -------------------------------------------------------------- */
00398     this->m_ptr_count = this->m_total_images;
00399     
00400     this->m_ptr_array           
00401         = (uint8_t **)phCalloc(this->m_ptr_count,sizeof(uint8_t*));
00402     phCHECK_PTR(this->m_ptr_array,"phCalloc","phCalloc failed");
00403     this->m_ptr_size_array      
00404         = (uint32_t *)phCalloc(this->m_ptr_count,sizeof(uint32_t));
00405     phCHECK_PTR(this->m_ptr_size_array,"phCalloc","phCalloc failed");
00406     this->m_ptr_stepping_array  
00407         = (uint32_t *)phCalloc(this->m_ptr_count,sizeof(uint32_t));
00408     phCHECK_PTR(this->m_ptr_stepping_array,"phCalloc","phCalloc failed");
00409     this->m_ptr_name_array      
00410         = (char **)phCalloc(this->m_ptr_count,sizeof(char *));
00411     phCHECK_PTR(this->m_ptr_name_array,"phCalloc","phCalloc failed");
00412     
00413     this->m_ptr_name_array[0]   = "rgb";
00414     this->m_ptr_name_array[1]   = "hsv";
00415     this->m_ptr_name_array[2]   = "grey";
00416     this->m_ptr_name_array[3]   = "canny";
00417     this->m_ptr_name_array[4]   = "sobel";
00418 
00419     /* ------------------------------------------------------------------ */
00420     /* allocate the system and filters */
00421     this->m_system = new phSystem();
00422     
00423     /* -------------------------------------------------------------- */
00424     /* allocate the displays and the display pointer array */
00425     this->m_displays = new phDisplayInterface *[this->m_total_displays];
00426     for (i = 0; i < this->m_total_displays; i++ )
00427     {
00428         this->m_displays[i] = new X11Display();
00429     }
00430     
00431     /* -------------------------------------------------------------- */
00432     /* allocate the pipelines and the pipeline pointer array */
00433     this->m_pipelines = new phPipeline *[this->m_total_pipelines];
00434     for (i = 0; i < this->m_total_pipelines; i++ )
00435     {
00436         this->m_pipelines[i] = new phPipeline();
00437 
00438         rc = this->m_system->add(this->m_pipelines[i]);
00439         phPRINT_RC(rc,NULL,"this->m_system->add(pipelines[%d])",i);
00440     }
00441 
00442     /* -------------------------------------------------------------- */
00443     this->m_bright = new brightness_Filter();
00444     this->m_gauss  = new gaussianBlur_Filter();
00445     this->m_canny_resize = new resize_Filter(this->m_width,this->m_height);
00446     this->m_sobel_resize = new resize_Filter(this->m_width,this->m_height);
00447     this->m_hist_resize = new resize_Filter(this->m_width,this->m_height);
00448     
00449     /* -------------------------------------------------------------- */
00450     /* Set up the histogram data and filter arrays */
00451     if (this->m_flags & (phML_HISTRGB | phML_HISTHSV))
00452     {
00453         if (this->m_flags & phML_HISTRGB)
00454         {
00455             this->m_histrgb_index = this->m_total_histograms++;
00456         }
00457         if (this->m_flags & phML_HISTHSV)
00458         {
00459             this->m_histhsv_index = this->m_total_histograms++;
00460         }
00461 
00462         this->m_histograms      = new histogram_Filter *[this->m_total_histograms];
00463         this->m_histogram_data  = new phHistogramData *[this->m_total_histograms];
00464         for (i = 0; i < this->m_total_histograms; i++ )
00465         {
00466             this->m_histograms[i] = 
00467                 new histogram_Filter(0,0,
00468                                      this->m_width,this->m_height,
00469                                      this->m_histogram_bins,0,NULL);
00470 #if 0
00471             this->m_histograms[i]->setBoxSize(this->m_width_box,
00472                                               this->m_height_box);
00473 #endif
00474             this->m_histogram_data[i] = new phHistogramData();
00475 
00476             rc = this->m_histogram_data[i]->connect(this->m_histograms[i]->getLiveHistogramOutput());
00477             phPRINT_RC(rc,NULL,"histogram_data->connect");
00478         }
00479     }
00480 
00481     /* -------------------------------------------------------------- */
00482     /* histogram */
00483     if (this->m_flags & (phML_HISTHSV | phML_HSV))
00484     {
00485         this->m_hsv_convert = new convert_Filter(phImageHSV24);
00486     }
00487     
00488     /* -------------------------------------------------------------- */
00489     /* canny */
00490     if (this->m_flags & phML_CANNY)
00491     {
00492         this->m_canny_grey_conv = new convert_Filter(phImageGREY8);
00493 #if PH_HAVE_OPENCV
00494         this->m_canny           = new cv_canny_Filter(70,200,3);
00495 #else
00496         this->m_canny           = new canny_Filter(100,200);
00497 #endif
00498     }
00499     
00500     /* -------------------------------------------------------------- */
00501     /* sobel */
00502     if (this->m_flags & phML_SOBEL)
00503     {
00504         this->m_sobel_grey_conv = new convert_Filter(phImageGREY8);
00505         this->m_sobel           = new sobel_Filter();
00506     }
00507 
00508     /* -------------------------------------------------------------- */
00509     /* allocate the images and image pointer array */
00510     this->m_images = new phImage *[this->m_total_images];
00511     for (i = 0; i < this->m_total_images; i++ )
00512     {
00513         this->m_images[i] = new phImage();
00514     }
00515  
00516     return phSUCCESS;
00517 error:
00518     return phFAIL;
00519 }
00520 
00521 /* ------------------------------------------------------------------------ */
00522 int phANNSystem::connect_elements( )
00523 {
00524     phFUNCTION("phANNSystem::connect_elements")
00525 
00526     phLiveObject *source = NULL;
00527     phLiveObject *s      = NULL;
00528 
00529     /* -------------------------------------------------------------- */
00530     source = this->m_images[this->m_input_image];
00531     rc = this->m_pipelines[this->m_bright_pipe]->setLiveSourceInput(source);
00532     phPRINT_RC(rc,NULL,
00533                "this->m_pipelines[this->m_bright_pipe]->setLiveSourceInput");
00534 
00535     source = this->m_pipelines[this->m_bright_pipe]->getLiveSourceOutput();
00536 
00537     /* -------------------------------------------------------------- */
00538     /* If we're inputing an RGB image into the neural network, then
00539        we need to connect the RGB image */
00540     if (this->m_flags & phML_RGB)
00541     {
00542         rc = this->m_images[this->m_rgb_image]->connect(source);
00543         phPRINT_RC(rc,NULL,"images[this->m_rgb_image]->connect");
00544     }
00545     
00546     /* -------------------------------------------------------------- */
00547     /* If we're inputing a grey scale image into the neural network,
00548        then we need to connect the grey image */
00549     if (this->m_flags & phML_GREY)
00550     {
00551         rc = this->m_images[this->m_grey_image]->connect(source);
00552         phPRINT_RC(rc,NULL,"images[this->m_grey_image]->connect");
00553     }
00554  
00555     /* -------------------------------------------------------------- */
00556     /* If we're inputing an HSV image into the neural network,
00557        then we need to connect the grey image */
00558     if (this->m_flags & phML_HSV)
00559     {
00560         s = this->m_pipelines[this->m_hist_pipe]->getLiveSourceOutput();
00561         rc = this->m_images[this->m_hsv_image]->connect(s);
00562         phPRINT_RC(rc,NULL,"images[this->m_grey_image]->connect");
00563     }
00564    
00565     /* -------------------------------------------------------------- */
00566     /* histogram */
00567     if (this->m_flags & (phML_HISTRGB | phML_HISTHSV | phML_HSV))
00568     {
00569         rc = this->m_pipelines[this->m_hist_pipe]->setLiveSourceInput(source);
00570         phPRINT_RC(rc,NULL,"pipelines[this->m_hist_pipe]->setLiveSourceInput");
00571     }
00572     
00573     /* -------------------------------------------------------------- */
00574     /* canny */
00575     if (this->m_flags & phML_CANNY)
00576     {
00577         rc = this->m_pipelines[this->m_canny_pipe]->setLiveSourceInput(source);
00578         phPRINT_RC(rc,NULL,"pipelines[this->m_canny_pipe]->setLiveSourceInput");
00579 
00580         s = this->m_pipelines[this->m_canny_pipe]->getLiveSourceOutput();
00581         rc = this->m_images[this->m_canny_image]->connect(s);
00582         phPRINT_RC(rc,NULL,"images[this->m_canny_image]->connect");
00583     }
00584     
00585     /* -------------------------------------------------------------- */
00586     /* sobel */
00587     if (this->m_flags & phML_SOBEL)
00588     {
00589         rc = this->m_pipelines[this->m_sobel_pipe]->setLiveSourceInput(source);
00590         phPRINT_RC(rc,NULL,"pipelines[this->m_sobel_pipe]->setLiveSourceInput");
00591 
00592         s = this->m_pipelines[this->m_sobel_pipe]->getLiveSourceOutput();
00593         rc = this->m_images[this->m_sobel_image]->connect(s);
00594         phPRINT_RC(rc,NULL,"images[this->m_sobel_image]->connect");
00595     }
00596     
00597     return phSUCCESS;
00598 }
00599 
00600 /* ------------------------------------------------------------------------ */
00601 int phANNSystem::pipeline_add( uint32_t index,  phFilter *filter )
00602 {
00603     phFUNCTION("phANNSystem::pipeline_add")
00604         
00605     if ((index < this->m_total_pipelines) && (filter != NULL))
00606     {
00607         rc = this->m_pipelines[index]->add(filter);
00608         phPRINT_RC(rc,NULL,"pipelines[%d]->add(%p:%s)",
00609                    index,filter,filter->getName());
00610     }
00611     return phSUCCESS;
00612 }
00613 
00614 /* ------------------------------------------------------------------------ */
00615 int phANNSystem::add_filters( )
00616 {
00617     phFUNCTION("phANNSystem::add_filters")
00618 
00619     /* brightness adjustment */
00620     this->pipeline_add(this->m_bright_pipe,this->m_bright);
00621     //this->pipeline_add(this->m_bright_pipe,this->m_gauss);
00622 
00623     /* -------------------------------------------------------------- */
00624     /* histogram */
00625     if (this->m_flags & (phML_HISTRGB | phML_HISTHSV | phML_HSV))
00626     {
00627 #if PRE_RESIZE_HIST_INPUT()
00628         this->pipeline_add(this->m_hist_pipe,
00629                            this->m_hist_resize);
00630 #endif
00631         if (this->m_flags & phML_HISTRGB)
00632         {
00633             this->pipeline_add(this->m_hist_pipe,
00634                                this->m_histograms[this->m_histrgb_index]);
00635         }
00636         if (this->m_flags & (phML_HISTHSV | phML_HSV))
00637         {
00638             this->pipeline_add(this->m_hist_pipe, this->m_hsv_convert);
00639         }
00640         if (this->m_flags & phML_HISTHSV)
00641         {
00642             this->pipeline_add(this->m_hist_pipe, 
00643                                this->m_histograms[this->m_histhsv_index]);
00644         }
00645     }
00646     
00647     /* -------------------------------------------------------------- */
00648     /* canny */
00649     if (this->m_flags & phML_CANNY)
00650     {
00651 #if PRE_RESIZE_CANNY_INPUT()
00652         this->pipeline_add(this->m_canny_pipe,
00653                            this->m_canny_resize);
00654 #endif
00655         this->pipeline_add(this->m_canny_pipe,this->m_canny_grey_conv);
00656         this->pipeline_add(this->m_canny_pipe,this->m_canny);
00657     }
00658     
00659     /* -------------------------------------------------------------- */
00660     /* sobel */
00661     if (this->m_flags & phML_SOBEL)
00662     {
00663 #if PRE_RESIZE_SOBEL_INPUT()
00664         this->pipeline_add(this->m_sobel_pipe,
00665                            this->m_sobel_resize);
00666 #endif
00667         this->pipeline_add(this->m_sobel_pipe,this->m_sobel);
00668         this->pipeline_add(this->m_sobel_pipe,this->m_sobel_grey_conv);
00669     }
00670     
00671     return phSUCCESS;
00672 }
00673 
00674 /* ------------------------------------------------------------------------ */
00675 int phANNSystem::connect_displays( )
00676 {
00677     phFUNCTION("phANNSystem::connect_displays")
00678     uint32_t i = 0;
00679     uint32_t x = 0;
00680     uint32_t y = 0;
00681     phLiveObject *source = NULL;
00682 
00683     if (this->m_no_displays) return phSUCCESS;
00684 
00685     /* -------------------------------------------------------------- */
00686     /* add the displays to the system and set the x,y coords */
00687     for (i = 0; i < this->m_total_displays; i++ )
00688     {
00689         rc = this->m_system->add(this->m_displays[i]);
00690         phPRINT_RC(rc,NULL,"system->add(display)");
00691         
00692         x = 50+(i*(((this->m_width<170)?170:this->m_width)+16));
00693         y = 50;
00694         rc = this->m_displays[i]->move(x,y);
00695         phPRINT_RC(rc,NULL,"displays[%u]->move",i);
00696     }
00697 
00698     /* -------------------------------------------------------------- */
00699     /* Raw image display, brightness adjusted */
00700     source = this->m_pipelines[this->m_bright_pipe]->getLiveSourceOutput();
00701     rc = this->m_displays[this->m_img_disp]->setLiveSourceInput(source);
00702     phPRINT_RC(rc,NULL,"display_pipe");
00703 
00704     /* -------------------------------------------------------------- */
00705     /* histogram */
00706     if (this->m_flags & phML_HISTRGB)
00707     {
00708         /* RGB histogram display */
00709         source = this->m_histogram_data[this->m_histrgb_index]->getImage();
00710         rc = this->m_displays[this->m_histrgb_disp]->setLiveSourceInput(source);
00711         phPRINT_RC(rc,NULL,"displays[HISTRGB_DISP]");
00712     }
00713     if (this->m_flags & phML_HISTHSV)
00714     {
00715         /* HSV histogram display */
00716         source = this->m_histogram_data[this->m_histhsv_index]->getImage();
00717         rc = this->m_displays[this->m_histhsv_disp]->setLiveSourceInput(source);
00718         phPRINT_RC(rc,NULL,"displays[HISTHSV_DISP]");
00719     }
00720     
00721     /* -------------------------------------------------------------- */
00722     /* canny */
00723     if (this->m_flags & phML_CANNY)
00724     {
00725         /* Canny edge detection display */
00726         source = this->m_pipelines[this->m_canny_pipe]->getLiveSourceOutput();
00727         rc = this->m_displays[this->m_canny_disp]->setLiveSourceInput(source);
00728         phPRINT_RC(rc,NULL,"displays[this->m_canny_disp]");
00729     }
00730     
00731     /* -------------------------------------------------------------- */
00732     /* sobel */
00733     if (this->m_flags & phML_SOBEL)
00734     {
00735         /* Sobel edge detection display */
00736         source = this->m_pipelines[this->m_sobel_pipe]->getLiveSourceOutput();
00737         rc = this->m_displays[this->m_sobel_disp]->setLiveSourceInput(source);
00738         phPRINT_RC(rc,NULL,"display_pipe");
00739     }
00740     
00741     return phSUCCESS;
00742 }
00743 
00744 /* ------------------------------------------------------------------------ */
00745 int phANNSystem::disconnect_displays( )
00746 {
00747     phFUNCTION("phANNSystem::disconnect_displays")
00748     uint32_t i = 0;
00749 
00750     for (i = 0; i < this->m_total_displays; i++ )
00751     {
00752         if ((this->m_displays[i] != NULL) && (this->m_no_displays == 0))
00753         {
00754             rc = this->m_system->remove(this->m_displays[i]);
00755             phPRINT_RC(rc,NULL,"system->remove(display)");
00756         
00757             rc = this->m_displays[i]->setLiveSourceInput(NULL);
00758             phPRINT_RC(rc,NULL,
00759                     "this->m_displays[i:%d]->setLiveSourceInput(NULL)",i);
00760         }
00761     }
00762     
00763     return phSUCCESS;
00764 }
00765 
00766 /* ------------------------------------------------------------------------ */
00767 int phANNSystem::startup()
00768 {
00769     phFUNCTION("phANNSystem::startup");
00770 
00771     rc = this->connect_displays();
00772     phPRINT_RC(rc,NULL,"this->connect_displays()");
00773 
00774     rc = this->m_system->startup();
00775     phPRINT_RC(rc,NULL,"system->startup()");
00776 
00777     return rc;
00778 }
00779 
00780 /* ------------------------------------------------------------------------ */
00781 int phANNSystem::shutdown()
00782 {
00783     phFUNCTION("phANNSystem::shutdown");
00784 
00785     rc = this->m_system->shutdown();
00786     phPRINT_RC(rc,NULL,"system->shutdown()");
00787 
00788     rc = this->disconnect_displays();
00789     phPRINT_RC(rc,NULL,"this->disconnect_displays()");
00790 
00791     return rc;
00792 }
00793 
00794 /* ------------------------------------------------------------------------ */
00795 int phANNSystem::useDisplays( int use )
00796 {
00797     return (this->m_no_displays = (use ? 0 : 1));
00798 }
00799 
00800 /* ------------------------------------------------------------------------ */
00801 int phANNSystem::setBrightnessStep ( int step  )
00802 {
00803     this->m_bright_stepping = step;
00804     return phSUCCESS;
00805 }
00806 
00807 /* ------------------------------------------------------------------------ */
00808 int phANNSystem::setBrightnessLevel( int level )
00809 {
00810     int32_t value = (this->m_bright_stepping * level);
00811     this->m_bright_level = level;
00812     this->m_bright->set( value );
00813     return phSUCCESS;
00814 }
00815 
00816 /* ------------------------------------------------------------------------ */
00817 uint32_t phANNSystem::getInputCount()
00818 {
00819     return (this->m_width * this->m_height * this->m_img_inputs) + 
00820             this->m_indiv_inputs;
00821 }
00822 
00823 /* ------------------------------------------------------------------------ */
00824 int phANNSystem::update( )
00825 {
00826     phFUNCTION("phANNSystem::update")
00827     uint32_t    k           = 0;
00828     uint32_t    l           = 0;
00829     uint32_t    m           = 0;
00830     uint32_t    input_index = 0;
00831 
00832     uint8_t    *ptr         = NULL;
00833     uint32_t    ptr_size    = 0;
00834     uint32_t    ptr_stepping= 0;
00835     char       *ptr_name    = NULL;
00836 
00837     float       histogrammed_pixels = 0.0;
00838     uint32_t    bin_total           = 0;
00839     uint32_t    *cnt_array          = NULL;
00840 
00841     /* Get the number of inputs */
00842     this->m_input_nodes_count = this->getInputCount();
00843     if (this->m_input_nodes_count == 0) 
00844     {
00845         return phFAIL;
00846     }
00847     
00848     /* allocate the array if it isn't allocated; clear the data too */
00849     phDALLOC(this->m_input_nodes,
00850              this->m_input_nodes_size,
00851              this->m_input_nodes_count,
00852              fann_type);
00853 
00854     /* -------------------------------------------------------------- */
00855     /* UPDATE IMAGES */
00856     /* -------------------------------------------------------------- */
00857     /* Updqate the pipeline output images : HSV, GREY, CANNY, SOBEL */
00858     for ( k = this->m_rgb_image; k < this->m_total_images; k++ )
00859     {
00860         /* Check the input flags for the presence of the
00861          * image we want to update; Don't update it if
00862          * it's unwanted as an input to the ANN */
00863         if ((1<<(k-1)) & this->m_flags)
00864         {
00865             rc = this->m_images[k]->update();
00866             phPRINT_RC(rc,NULL,"this->m_images[k:%d]->update()",k);
00867             
00868             rc = this->m_images[k]->resize(this->m_width,
00869                                            this->m_height);
00870             phPRINT_RC(rc,NULL,"this->m_images[k:%d]->resize(%u,%u)",
00871                     k,this->m_width,this->m_height);
00872         }
00873     }
00874 
00875     if (this->m_flags & phML_GREY)
00876     {
00877         /* The grey scale still need to be converted */
00878         rc = this->m_images[this->m_grey_image]->convert(phImageGREY8);
00879         phPRINT_RC(rc,NULL,"images[this->m_grey_image]->convert");
00880     }
00881 
00882     /* -------------------------------------------------------------- */
00883     /* UPDATE HISTOGRAMS */
00884     /* -------------------------------------------------------------- */
00885     for ( k = 0; k < this->m_total_histograms; k++ )
00886     {
00887         /* Check the input flags to see if we want to
00888          * update the hist data; 6 is the start for the
00889          * histogram flags in the phML_ flags */ 
00890         if (this->m_flags & (1<<(k+6)))
00891         {
00892             rc = this->m_histogram_data[k]->update();
00893             phPRINT_RC(rc,NULL,"histogram_data[k]->update()");
00894 
00895             if (this->m_no_displays == 0)
00896             {
00897                 rc = this->m_histogram_data[k]->generateImage(120);
00898                 phPRINT_RC(rc,NULL,"histogram_data[k]->generateImage()");
00899             }
00900         }
00901     }
00902 
00903     /* -------------------------------------------------------------- */
00904     /* COPY IMAGES TO INPUT NODES */
00905     /* -------------------------------------------------------------- */
00906 
00907     /* Set up the pointer arrays to make things a bit easier in the
00908      * copying loop, next */
00909     for (k = this->m_rgb_image; k < this->m_total_images; k++ )
00910     {
00911         /* save time here by only copying the info we need
00912          * because everything else we're not going to
00913          * touch */
00914         if ((1<<(k-1)) & this->m_flags)
00915         {
00916             this->m_ptr_array[k]         = (uint8_t*)this->m_images[k]->getImage();
00917             this->m_ptr_size_array[k]    = this->m_images[k]->getSize();
00918             this->m_ptr_stepping_array[k]= 
00919                 phImageFormatToDepth(this->m_images[k]->getFormat());
00920             if (this->m_ptr_array[k] == NULL)
00921             {
00922                 phPROGRESS("WARNING !!! Image %d data == NULL\n",k);
00923             }
00924             if (this->m_ptr_size_array[k] == 0)
00925             {
00926                 phPROGRESS("WARNING !!! Image %d size == 0\n",k);
00927             }
00928         }
00929     }
00930 
00931     /* SET UP THE INPUT NODES */
00932 
00933     /* copy all the image data to the input node array */
00934     for (k = this->m_rgb_image; k < this->m_total_images; k++ )
00935     {
00936         /* Check the input flags for the presence of the
00937          * image we want to copy to the input nodes. */
00938         /* The -1 is to offset the k to match up the 1<<x
00939          * with the flags in this->m_flags */
00940         if ((1<<(k-1)) & this->m_flags)
00941         {
00942             ptr         = this->m_ptr_array[k];
00943             ptr_size    = this->m_ptr_size_array[k];
00944             ptr_stepping= this->m_ptr_stepping_array[k];
00945             ptr_name    = this->m_ptr_name_array[k];
00946 
00947             for ( m = 0; m < ptr_stepping; m++ )
00948             {
00949                 for ( l = 0; l < ptr_size; l += ptr_stepping )
00950                 {
00951                     if (input_index >= this->m_input_nodes_count)
00952                     {
00953                         phPROGRESS("WARNING!!! %d >= %d\n",
00954                                     input_index,
00955                                     this->m_input_nodes_count);
00956 #if 0
00957                         exit(1);
00958 #endif
00959                     }
00960                     this->m_input_nodes[input_index++] = ((fann_type)(ptr[l+m])) - 127;
00961                 }
00962             }
00963         }
00964     }
00965 
00966     /* -------------------------------------------------------------- */
00967     /* COPY HISTOGRAM PERCENTAGES */
00968     /* -------------------------------------------------------------- */
00969 
00970     /* -------------------------------------------------------------- */
00971     /* copy the histogram information to the input node arrays */
00972     histogrammed_pixels = this->m_images[this->m_input_image]->getWidth() *
00973                           this->m_images[this->m_input_image]->getHeight();
00974     for (k = 0; k < this->m_total_histograms; k++ )
00975     {
00976         /* Only copy over the histogram data if we're
00977          * inputing it into the ANN */
00978         if ((1<<(k+6)) & this->m_flags)
00979         {
00980             bin_total= this->m_histogram_data[k]->getBinStep() * 
00981                 this->m_histogram_data[k]->getBinCount();
00982             cnt_array= this->m_histogram_data[k]->getBinCntArray();
00983 
00984             for ( m = 0; m < bin_total; m++ )
00985             {
00986                 this->m_input_nodes[input_index++] = 
00987                     (fann_type)(cnt_array[m] / histogrammed_pixels);
00988             }
00989         }
00990     }
00991 
00992     /* The final input is the ratio */
00993     if (this->m_flags & phML_RATIO)
00994     {
00995         /* ratio is for the w/h ratio of the current img */
00996         this->m_input_nodes[input_index++] = (fann_type)this->m_image_ratio;
00997     }
00998 
00999     return phSUCCESS;
01000 error:
01001     return phFAIL;
01002 }
01003 
01004 /* ------------------------------------------------------------------------ */
01005 int phANNSystem::setOutputNodes( const uint32_t     nids,
01006                                  const uint32_t    *output_tag_ids )
01007 {
01008     phFUNCTION("phANNSystem::setOutputNodes")
01009     uint32_t ntags  = 0;
01010     uint32_t m      = 0;
01011     
01012     ntags = idc_get_ntags( this->m_data );
01013     
01014     this->m_output_nodes_count = ntags;
01015         
01016     /* IMPORTANT!! This resets all the nodes to 0 */
01017     /* this reinitializes the output nodes or allocates more */
01018     phDALLOC(this->m_output_nodes,
01019              this->m_output_nodes_size,
01020              this->m_output_nodes_count,
01021              fann_type);
01022 
01023     /* Set up the output nodes */
01024     for ( m = 0; m < nids; m++ )
01025     {
01026         if (output_tag_ids[m] < ntags)
01027         {
01028             this->m_output_nodes[output_tag_ids[m]] = 1.0F;
01029         }
01030     }
01031     /* clear all nodes that aren't 1.0 by setting them to -1.0 */
01032     for (m = 0; m < ntags; m++ )
01033     {
01034         if (this->m_output_nodes[m] < 1.0F)
01035         {
01036             this->m_output_nodes[m] = -1.0F;
01037         }
01038     }
01039  
01040     return phSUCCESS;
01041 error:
01042     return phFAIL;
01043 }
01044 
01045 /* ------------------------------------------------------------------------ */
01046 int phANNSystem::setInputImage( char           *filename,
01047                                 float           ratio,
01048                                 const uint32_t  nids,
01049                                 const uint32_t *output_tag_ids )
01050 {
01051     phFUNCTION("phANNSystem::setInputImage(char*,float,uint32_t,uint32_t*)")
01052 
01053     /* Load up the image */
01054     rc = this->m_images[this->m_input_image]->load( filename );
01055     phCHECK_RC(rc, NULL, 
01056                "this->m_images[this->m_input_image]->load( %s )", 
01057                filename );
01058 
01059     this->m_image_ratio = ratio;
01060     
01061     rc = this->update();
01062     phCHECK_RC(rc,NULL,"update");
01063 
01064     rc = this->setOutputNodes( nids, output_tag_ids );
01065     phCHECK_RC(rc,NULL,"setOutputNodes");
01066 
01067     return phSUCCESS;
01068 error:
01069     return phFAIL;
01070 }
01071 
01072 /* ------------------------------------------------------------------------ */
01073 int phANNSystem::setInputImage( phImage        &image,
01074                                 float           ratio,
01075                                 const uint32_t  nids,
01076                                 const uint32_t *output_tag_ids )
01077 {
01078     phFUNCTION("phANNSystem::setInputImage(phImage,float,uint32_t,uint32_t*)")
01079 
01080     rc = image.copy(this->m_images[this->m_input_image]);
01081     phCHECK_RC(rc,NULL,"image.copy(images[this->m_input_image])");
01082 
01083     this->m_image_ratio = ratio;
01084     
01085     rc = this->update();
01086     phCHECK_RC(rc,NULL,"update");
01087 
01088     rc = this->setOutputNodes( nids, output_tag_ids );
01089     phCHECK_RC(rc,NULL,"setOutputNodes");
01090 
01091     return phSUCCESS;
01092 error:
01093     return phFAIL;
01094 }
01095 
01096 /* ------------------------------------------------------------------------ */
01097 int phANNSystem::setInputImage( char  *filename, 
01098                                 float ratio )
01099 {
01100     phFUNCTION("phANNSystem::setInputImage(char*,float)")
01101 
01102     /* Load up the image */
01103     rc = this->m_images[this->m_input_image]->load( filename );
01104     phCHECK_RC(rc, NULL, 
01105                "this->m_images[this->m_input_image]->load( %s )", 
01106                filename );
01107 
01108     this->m_image_ratio = ratio;
01109     
01110     rc = this->update();
01111     phCHECK_RC(rc,NULL,"update");
01112 
01113     return phSUCCESS;
01114 error:
01115     return phFAIL;
01116 }
01117 
01118 /* ------------------------------------------------------------------------ */
01119 int phANNSystem::setInputImage( phImage &image,
01120                                 float   ratio )
01121 {
01122     phFUNCTION("phANNSystem::setInputImage(phImage&,float)")
01123 
01124     rc = image.copy(this->m_images[this->m_input_image]);
01125     phCHECK_RC(rc,NULL,"image.copy(images[this->m_input_image])");
01126 
01127     this->m_image_ratio = ratio;
01128     
01129     rc = this->update();
01130     phCHECK_RC(rc,NULL,"update");
01131 
01132     return phSUCCESS;
01133 error:
01134     return phFAIL;
01135 }
01136 /* ------------------------------------------------------------------------ */
01137 int phANNSystem::getInputNodes( uint32_t       *input_count,
01138                                 uint32_t       *input_size,
01139                                 fann_type     **pinput_nodes )
01140 {
01141     phFUNCTION("phANNSystem::getInputNodes")
01142     uint32_t size = 0;
01143     uint32_t count= 0;
01144     
01145     /* allocate the array if necessary */
01146     if (pinput_nodes == NULL) return phFAIL;
01147   
01148     /* set */
01149     count = this->m_input_nodes_count;
01150     if (input_count != NULL)*input_count = count;
01151     
01152     /* allocate the array if it isn't allocated; clear the data too */
01153     if (input_size != NULL) size = *input_size;
01154     phDALLOC((*pinput_nodes), size, count, fann_type);
01155     if (input_size != NULL) *input_size = size;
01156     
01157     /* copy */
01158     phMemcpy(*pinput_nodes,
01159              this->m_input_nodes,
01160              this->m_input_nodes_size);
01161 
01162     return phSUCCESS;
01163 error:
01164     return phFAIL;
01165 }
01166 
01167 /* ------------------------------------------------------------------------ */
01168 int phANNSystem::getOutputNodes(uint32_t       *output_count,
01169                                 uint32_t       *output_size,
01170                                 fann_type     **poutput_nodes )
01171 {
01172     phFUNCTION("phANNSystem::getOutputNodes")
01173     uint32_t size = 0;
01174     uint32_t count= 0;
01175     
01176     /* allocate the array if necessary */
01177     if (poutput_nodes == NULL) return phFAIL;
01178   
01179     count = this->m_output_nodes_count;
01180     if (output_count != NULL)*output_count = count;
01181 
01182     /* allocate */
01183     if (output_size != NULL) size = *output_size;
01184     phDALLOC((*poutput_nodes), size, count, fann_type);
01185     if (output_size != NULL) *output_size = size;
01186 
01187     /* copy */
01188     phMemcpy(*poutput_nodes,
01189              this->m_output_nodes,
01190              this->m_output_nodes_size);
01191 
01192     return phSUCCESS;
01193 error:
01194     return phFAIL;
01195 }
01196 
01197 /* ------------------------------------------------------------------------ */
01198 int phANNSystem::getNodes( uint32_t       *input_count,
01199                            uint32_t       *input_size,
01200                            fann_type     **pinput_nodes,
01201                            uint32_t       *output_count,
01202                            uint32_t       *output_size,
01203                            fann_type     **poutput_nodes )
01204 {
01205     phFUNCTION("phANNSystem::getNodes")
01206 
01207     rc = this->getInputNodes(input_count,input_size,pinput_nodes);
01208     phCHECK_RC(rc,NULL,"getInputNodes");
01209 
01210     rc = this->getOutputNodes(output_count,output_size,poutput_nodes);
01211     phCHECK_RC(rc,NULL,"getOutputNodes");
01212 
01213     return phSUCCESS;
01214 error:
01215     return phFAIL;
01216 }
01217 
01218 /* ------------------------------------------------------------------------ */
01219 int phANNSystem::getNodes( fann_type     **pinput_nodes,
01220                            fann_type     **poutput_nodes )
01221 {
01222     phFUNCTION("phANNSystem::getNodes(fann_type **,fann_type **)")
01223 
01224     rc = this->getInputNodes(NULL,NULL,pinput_nodes);
01225     phCHECK_RC(rc,NULL,"getInputNodes");
01226 
01227     rc = this->getOutputNodes(NULL,NULL,poutput_nodes);
01228     phCHECK_RC(rc,NULL,"getOutputNodes");
01229 
01230     return phSUCCESS;
01231 error:
01232     return phFAIL;
01233 }
01234 /* ------------------------------------------------------------------------ */
01235 FILE *phANNSystem::openLogFile( const char *prefix,
01236                                 const char *suffix )
01237 {
01238     phFUNCTION("phANNSystem::openLogFile")
01239 
01240     if (this->m_logfp)
01241     {
01242         this->closeLogFile();
01243     }
01244         
01245     snprintf(this->m_logfile,
01246              255,
01247              "%s_flgs%03x_alg%d_lyrs%02u_in%05u_h%03u_o%03u_w%03u_h%03u_%s.log",
01248              prefix, 
01249              this->m_flags,
01250              this->m_training_algorithm,
01251              this->m_num_layers,
01252              this->getInputCount(), 
01253              this->m_num_hidden, 
01254              this->m_num_output,
01255              this->m_width, 
01256              this->m_height,
01257              suffix );
01258 
01259     phPRINT("Opening log file for statistical output: %s\n",
01260             this->m_logfile );
01261     this->m_logfp = fopen( this->m_logfile,"w+" );
01262     phCHECK_PTR(this->m_logfp,"fopen",
01263                 "fopen %s failed.",this->m_logfile );
01264 
01265     return this->m_logfp;
01266 error:
01267     return NULL;
01268 }
01269 
01270 /* ------------------------------------------------------------------------ */
01271 int phANNSystem::closeLogFile()
01272 {
01273     phFUNCTION("phANNSystem::closeLogFile")
01274     
01275     /* close the logfile */
01276     if (this->m_logfp != NULL)
01277     {
01278         phPRINT("Closing log file.\n");
01279         fclose(this->m_logfp);
01280         this->m_logfp = NULL;
01281     }
01282 
01283     return phSUCCESS;
01284 }
01285 
01286 /* ------------------------------------------------------------------------ */
01287 int phANNSystem::createNetwork()
01288 {
01289     phFUNCTION("phANNSystem::createNetwork")
01290     uint32_t i = 0;
01291 
01292     if (this->m_ann_source == 1)
01293     {
01294         phPRINT("Opening ANN from %s\n",this->m_ann_file);
01295         this->m_ann = fann_create_from_file( this->m_ann_file );
01296         phPRINT("Done.\n");
01297         if (this->m_ann == NULL) goto error;
01298 
01299         this->m_learning_rate       = fann_get_learning_rate(this->m_ann);
01300         this->m_num_output          = fann_get_num_output(this->m_ann);
01301         this->m_training_algorithm  = fann_get_training_algorithm(this->m_ann);
01302         /* connection_rate */
01303         /* num_hidden ?? */
01304         /* num_layers ?? */
01305     }
01306     else
01307     {
01308         unsigned int *neurons_per_layer = 
01309             (unsigned int *)phCalloc(this->m_num_layers,sizeof(unsigned int));
01310         phCHECK_PTR(neurons_per_layer,"phCalloc","phCalloc failed.");
01311         
01312         /* Print out the first arguments to the creation function */
01313         phPRINT("Creating new ANN( %f, %f, %u, ",
01314                 this->m_connection_rate, 
01315                 this->m_learning_rate, 
01316                 this->m_num_layers );
01317 
01318         /* Set the number of input nodes */
01319         neurons_per_layer[0] = this->getInputCount();
01320         /* Print the number of input neurons */
01321         phPRINT(" { %u ", neurons_per_layer[0] );
01322         /* Set the number of output nodes */
01323         neurons_per_layer[this->m_num_layers - 1] = this->m_num_output;
01324         /* Set the hidden layer number of nodes */
01325         for (i = 1; i < (this->m_num_layers - 1); i++ )
01326         {
01327             neurons_per_layer[i] = this->m_num_hidden;
01328             phPRINT(" %u,", neurons_per_layer[i] );
01329         }
01330         /* Print the output node count */
01331         phPRINT(" %u} )\n", this->m_num_output );
01332         
01333         /* Create the FANN ANN With the specific arguments */
01334         this->m_ann = fann_create_array(  this->m_connection_rate, 
01335                                           this->m_learning_rate, 
01336                                           this->m_num_layers,
01337                                           neurons_per_layer );
01338         phPRINT("Done.\n");
01339         phCHECK_PTR(this->m_ann,NULL,"fann_create");
01340 
01341         /* Set the training algorithm; it will be saved in the ann .net file
01342          * when the system is saved */
01343         fann_set_training_algorithm(this->m_ann,
01344                                     this->m_training_algorithm);
01345 
01346         /* Set the activation function to FANN_SIGMOID_SYMMETRIC because the
01347            system being used here outputs -1.0 for no and 1.0 for yes */
01348         fann_set_activation_function_hidden(this->m_ann,FANN_SIGMOID_SYMMETRIC);
01349         fann_set_activation_function_output(this->m_ann,FANN_SIGMOID_SYMMETRIC);
01350         
01351         phPRINT("Input Nodes        : %u\n", this->getInputCount() );
01352         phPRINT("Hidden nodes       : %u\n",this->m_num_hidden );
01353         phPRINT("Output nodes       : %u\n",this->m_num_output);
01354         phPRINT("Number of Layers   : %u\n",this->m_num_layers);
01355 
01356         phFree(neurons_per_layer);
01357     }
01358     fann_print_parameters( this->m_ann );
01359 
01360     return phSUCCESS;
01361 error:
01362     return phFAIL;
01363 }
01364 
01365 /* ------------------------------------------------------------------------ */
01366 int phANNSystem::destroyNetwork()
01367 {
01368     phFUNCTION("phANNSystem::destroyNetwork")
01369 
01370     if (this->m_ann != NULL)
01371     {
01372         fann_destroy(this->m_ann);
01373         this->m_ann = NULL;
01374     }
01375 
01376     return phSUCCESS;
01377 }
01378 
01379 /* ------------------------------------------------------------------------ */
01380 int phANNSystem::setNetwork( char *ann_startfile )
01381 {
01382     phFUNCTION("phANNSystem::setNetwork")
01383 
01384     this->m_ann_source  = 1;
01385     snprintf(this->m_ann_file,255,"%s",ann_startfile);
01386     
01387     return phSUCCESS;
01388 error:
01389     return phFAIL;
01390 }
01391 
01392 /* ------------------------------------------------------------------------ */
01393 int phANNSystem::setNetwork(float       connection_rate, 
01394                             float       learning_rate, 
01395                             int32_t     training_algorithm,
01396                             uint32_t    num_layers,
01397                             uint32_t    num_hidden )
01398 {
01399     phFUNCTION("phANNSystem::setNetwork")
01400 
01401     this->m_ann_source          = 0;
01402         
01403     this->m_connection_rate     = connection_rate;
01404     this->m_learning_rate       = learning_rate;
01405     this->m_training_algorithm  = training_algorithm;
01406     
01407     if (num_layers < 2)
01408         this->m_num_layers = 2;
01409     else
01410         this->m_num_layers          = num_layers;
01411     
01412     if ((this->getInputCount() > 0) && (num_hidden == 0))
01413     {
01414         this->m_num_hidden = this->getInputCount() / 600;
01415     }
01416     else
01417     {
01418         this->m_num_hidden = num_hidden;
01419     }
01420     if (this->m_num_hidden < 3)
01421     {
01422         this->m_num_hidden = 3;
01423     }
01424     
01425     return phSUCCESS;
01426 error:
01427     return phFAIL;
01428 }
01429 
01430 /* ------------------------------------------------------------------------ */
01431 int phANNSystem::saveNetwork( const char *prefix,
01432                               const char *suffix )
01433 {
01434     phFUNCTION("phANNSystem::saveNetwork")
01435 
01436     snprintf(this->m_ann_datafile,
01437             255,
01438             "%s_flgs%03x_alg%d_lyrs%02u_in%05u_h%03u_o%03u_w%03u_h%03u_%s.net",
01439             prefix, 
01440             this->m_flags, 
01441             this->m_training_algorithm,
01442             this->m_num_layers,
01443             this->getInputCount(), 
01444             this->m_num_hidden, 
01445             this->m_num_output,
01446             this->m_width, 
01447             this->m_height, 
01448             suffix );
01449     
01450     phPRINT( "\nSaving ANN file: %s\n", this->m_ann_datafile );
01451     fann_save(this->m_ann,this->m_ann_datafile);
01452     phPRINT( "Done saving.\n" );
01453 
01454     return phSUCCESS;
01455 }
01456 
01457 /* ------------------------------------------------------------------------ */
01458 void phANNSystem::print_epoch_info( const char      *label,
01459                                     ml_class_stats  *stats)
01460 {
01461     phFUNCTION("phANNSystem::print_epoch_info")
01462         
01463     float percent_correct   = 0.0;
01464     float percent_incorrect = 0.0;
01465 
01466     /* Print the testing set's final MSE */
01467     percent_correct = ((float)stats->correctly_classified / 
01468                        (float)(stats->nclassifications)) * 100;
01469     percent_incorrect = ((float)stats->incorrectly_classified / 
01470                        (float)(stats->nclassifications)) * 100;
01471     
01472     phPRINT("%s(MSE:%8.20f) (Classified: %5u/%5u of %5u) %0.3f%% %0.3f%%     \n",
01473             label,
01474             fann_get_MSE(this->m_ann),
01475             stats->correctly_classified,
01476             stats->incorrectly_classified,
01477             stats->nclassifications,
01478             percent_correct,
01479             percent_incorrect );
01480 }
01481 
01482 /* ------------------------------------------------------------------------ */
01483 int phANNSystem::generateNodes(int      preload_images,
01484                                int      generate_random,
01485                                uint32_t train_set_size,
01486                                uint32_t test_set_size,
01487                                uint32_t *ptrain_array_count,
01488                                uint32_t *ptest_array_count,
01489                                uint32_t *pinput_array_count,
01490                                fann_type ***pinput_nodes,
01491                                fann_type ***prand_input_nodes,
01492                                uint32_t *poutput_array_count,
01493                                fann_type ***poutput_nodes,
01494                                fann_type ***prand_output_nodes )
01495 {
01496     phFUNCTION("phANNSystem::train")
01497 
01498     /* ------------------------------------------------------------------ */
01499     double          size        = 0.0;
01500     uint32_t        i           = 0;
01501     uint32_t        j           = 0;
01502     uint32_t        last_j      = 1;
01503     
01504     /* The 'array's here point to all the input and output pairing of nodes
01505        that are the result of processing all the data */       
01506     uint32_t        processed_index     = 0;
01507     uint32_t        train_array_count   = 0;
01508     int             train_generated     = 0;
01509     uint32_t        test_array_count    = 0;
01510     fann_type       **input_array  = NULL;
01511     fann_type       **rand_input_array  = NULL;
01512     fann_type       **output_array = NULL;
01513     fann_type       **rand_output_array = NULL;
01514     /* input and output are allocated and populated by this program;
01515      * actual_output is returned from fann_run and compared against the
01516      * output_nodes array to determine correctly classified objects */
01517     fann_type       *input_nodes        = NULL;
01518     fann_type       *output_nodes       = NULL;
01519 
01520     /* ------------------------------------------------------------------ */
01521     random_selection_type   *selection          = NULL;
01522     uint32_t                file_id             = 0; /* i.e. sel. set */
01523     uint32_t                img_set_id          = 0; /* i.e. sel. index */
01524    
01525     /* ------------------------------------------------------------------ */
01526     uint32_t        ntags               = 0;
01527     uint32_t        nsets               = 0;
01528     uint32_t        total_train_imgs    = 0;
01529     uint32_t        total_test_imgs     = 0;
01530     uint32_t        total_imgs          = 0;
01531     uint32_t        set_size            = 0;
01532 
01533     /* ------------------------------------------------------------------ */
01534     /* image_array is used when preloading a set of images */
01535     phImage         *image_array= NULL;
01536     phImage         temp_image;
01537     /* filename is a temporary variable used when opening an image */
01538     char            *filename   = NULL;
01539     /* ratio is used as an input to the network */
01540     float           ratio       = 0.0;
01541     /* nids is used for each image to loop through tags for an image */
01542     uint32_t        nids        = 0;
01543     /* tag_ids is a pointer to an array of tags for activate output nodes */
01544     uint32_t        *tag_ids    = NULL;
01545     /* img is a handle to information of set of images loaded from file   */
01546     image_data_set  img         = NULL;
01547     uint32_t        x1          = 0;
01548     uint32_t        y1          = 0;
01549     uint32_t        x2          = 0;
01550     uint32_t        y2          = 0;
01551 
01552     /* ------------------------------------------------------------------ */
01553     int32_t         b               = 0;
01554     int32_t         bright_level    = 0;
01555     const int32_t   nbright_levels  = 5;
01556     const int32_t   bright_offset   = -4; /* start darker */
01557     const int32_t   initial_bright  = (nbright_levels / 2) + bright_offset;
01558     
01559     int32_t         hue_adjust      = 0;
01560     int32_t         sat_adjust      = 0;
01561     int32_t         val_adjust      = 0;
01562     int32_t         *adjust_arr      = NULL;
01563 
01564     int rand_w = 0;
01565     int rand_h = 0;
01566    
01567     /* ------------------------------------------------------------------ */
01568     /* Check the input parameters. Make sure the information isn't allocated
01569      * because the information will be lost when we set the return parameters
01570      * at the end of this method */
01571     if ((pinput_nodes != NULL) && (*pinput_nodes != NULL))
01572     {
01573         phCHECK_PTR(NULL,NULL,
01574                     "Invalid parameter: *pinput_nodes != NULL");
01575     }
01576     if ((poutput_nodes != NULL) && (*poutput_nodes != NULL))
01577     {
01578         phCHECK_PTR(NULL,NULL,
01579                     "Invalid parameter: *poutput_nodes != NULL");
01580     }
01581     if ((prand_input_nodes != NULL) && (*prand_input_nodes != NULL))
01582     {
01583         phCHECK_PTR(NULL,NULL,
01584                     "Invalid parameter: *prand_input_nodes != NULL");
01585     }
01586     if ((prand_output_nodes != NULL) && (*prand_output_nodes != NULL))
01587     {
01588         phCHECK_PTR(NULL,NULL,
01589                     "Invalid parameter: *prand_output_nodes != NULL");
01590     }
01591     
01592     /* ------------------------------------------------------------------ */
01593     /* retreive the info from the data set */
01594     set_size            = train_set_size + test_set_size;
01595     nsets               = idc_get_nsets( this->m_data );
01596     total_train_imgs    = nsets * train_set_size * nbright_levels;
01597     total_test_imgs     = nsets * test_set_size * nbright_levels;
01598     total_imgs          = total_train_imgs + total_test_imgs;
01599 
01600     /* preload the images if necessary */
01601     if (preload_images)
01602     {
01603         image_array = new phImage[nsets];
01604     }
01605   
01606     size =  (double)(sizeof(fann_type) * 
01607                      (this->getInputCount() + idc_get_ntags( this->m_data )) * 
01608                      total_imgs *
01609                      (generate_random ? 2 : 1));
01610     
01611     phPRINT("Test Set Size      : %u\n",train_set_size);
01612     phPRINT("Train Set Size     : %u\n",test_set_size);
01613     phPRINT("Array Count        : %u\n",total_imgs);
01614     phPRINT("Total Data size    : %.4lf Bytes %.4lf KBytes %.4lf MBytes %.4lf GBytes\n",
01615             size, 
01616             size / 1024, 
01617             size / (1024*1024),
01618             size / (1024 * 1024 * 1024));
01619     
01620     input_array = (fann_type **)phCalloc(total_imgs,sizeof(fann_type *));
01621     phCHECK_PTR(input_array,"phCalloc","phCalloc failed.");
01622     
01623     output_array = (fann_type **)phCalloc(total_imgs,sizeof(fann_type *));
01624     phCHECK_PTR(output_array,"phCalloc","phCalloc failed.");
01625 
01626     if (generate_random)
01627     {
01628         rand_input_array = (fann_type **)phCalloc(total_imgs,sizeof(fann_type *));
01629         phCHECK_PTR(rand_input_array,"phCalloc","phCalloc failed.");
01630     
01631         rand_output_array = (fann_type **)phCalloc(total_imgs,sizeof(fann_type *));
01632         phCHECK_PTR(rand_output_array,"phCalloc","phCalloc failed.");
01633     }
01634     
01635     /* Create random indexes for the training and test sets. */
01636     /* training = array[0] testing = array[train_set_size] */
01637     rc = random_selection_new( this->m_data,
01638                                train_set_size, 
01639                                test_set_size, 
01640                                &selection );
01641     phCHECK_RC(rc,NULL,"random_selection_new failed.");
01642     
01643     /* start up the processing system */
01644     rc = this->startup();
01645     phCHECK_RC(rc,NULL,"this->startup()");
01646     
01647     phPRINT("Number of Image sets   : %u\n", nsets );
01648     phPRINT("Training Images        : %u\n", total_train_imgs );
01649     phPRINT("Testing Images         : %u\n", total_test_imgs );
01650     
01651     processed_index = 0;
01652     
01653     if (generate_random)
01654     {
01655         srand48((unsigned int)time(NULL));
01656     }
01657 
01658     for (j = 0; j < set_size; j++ )
01659     {
01660         if ((j >= train_set_size) && (train_generated == 0))
01661         {
01662             train_array_count = processed_index;
01663             train_generated = 1;
01664         }
01665         
01666         file_id = selection->rset_array[j];
01667 
01668         /* preload the images for the current training set */
01669         if (preload_images)
01670         {
01671             /* load one for each image of the current set index */
01672             for (i = 0; i < nsets; i++ )
01673             {
01674                 img_set_id = selection->rindex_array[j][i];
01675 
01676                 /* Get the image settings */
01677                 img = idc_get_set       ( this->m_data, img_set_id );
01678 
01679                 rc = ids_get_filename  ( img,  file_id, &filename );
01680                 phPRINT_RC(rc,NULL,"ids_get_filename");
01681 
01682                 rc = ids_get_crop_coords( img, &x1, &y1, &x2, &y2 );
01683                 phCHECK_RC(rc, NULL, "ids_get_crop_coords failed.");
01684 
01685                 /* Load up the image */
01686                 rc = image_array[i].load( filename );
01687                 phCHECK_RC(rc, NULL, "image.load( %s )", filename );
01688 
01689                 /* crop the image, don't resize it */
01690                 rc = image_array[i].crop( x1, y1, x2, y2 );
01691                 phCHECK_RC(rc,NULL,
01692                         "images[temp_index]->crop(%u,%u,%u,%u) failed.",
01693                         x1, y1, x2, y2 );
01694             }
01695         }
01696 
01697         for (i = 0; i < nsets; i++ )
01698         {
01699             img_set_id = selection->rindex_array[j][i];
01700 
01701             /* Get the image settings */
01702             img = idc_get_set( this->m_data, img_set_id );
01703 
01704             rc = ids_get_crop_coords( img, &x1, &y1, &x2, &y2 );
01705             phCHECK_RC(rc, NULL, "ids_get_crop_coords failed.");
01706 
01707             ratio       = ids_get_ratio     ( img );
01708             nids        = ids_get_ntags     ( img );
01709             tag_ids     = ids_get_tag_ids   ( img );
01710 
01711             rc = ids_get_hsv_adjust( img, 
01712                     &hue_adjust, &sat_adjust, &val_adjust );
01713             phPRINT_RC( rc, NULL, "ids_get_hsv_adjust" );
01714 
01715             /* set the initial brightness level */
01716             bright_level = initial_bright;
01717 
01718             for (b = 0; b < nbright_levels; b++ )
01719             {
01720                 /* Brightness adjustment loop for training on varying
01721                  * brightness levels. This is artificial and would be
01722                  * better as real world brightness adjustments of lighting */
01723                 if ((!this->m_no_displays) || (last_j != j))
01724                 {
01725                     if (j < train_set_size)
01726                     {
01727                         phPRINT("Processing training set (%5d of %5d)\r", 
01728                                 (j * nsets * nbright_levels) + 
01729                                 (i * nbright_levels) + 
01730                                 (b + 1), /* current set */
01731                                 total_train_imgs /* total image sets */ );
01732                     }
01733                     else 
01734                     {
01735                         phPRINT("Processing test set     (%5d of %5d)\r",
01736                          ((j-train_set_size) * nsets * nbright_levels) + 
01737                          (i * nbright_levels) + 
01738                          (b + 1), /* current set */
01739                          total_test_imgs );
01740                     }
01741                         
01742                     last_j = j;
01743                 }
01744 
01745                 /* Set the brightness level of the brightness
01746                  * adjustment filter */
01747                 rc = this->setBrightnessLevel( bright_level );
01748                 phPRINT_RC(rc,NULL,"this->setBrightnessLevel()");
01749 
01750                 bright_level++;
01751 
01752                 /* load a file from file, the pipeline will see this
01753                  * and brightness adjust the image. The same for the
01754                  * copy in the else statement below. */
01755                 if (!preload_images)
01756                 {
01757                     rc = ids_get_filename  ( img,  file_id, &filename );
01758                     phPRINT_RC(rc,NULL,"ids_get_filename");
01759 
01760                     rc = temp_image.load(filename);
01761                     phCHECK_RC(rc,NULL,"temp_image.load(%s)",filename);
01762 
01763                     /* crop the image, don't resize it */
01764                     rc = temp_image.crop( x1, y1, x2, y2 );
01765                     phCHECK_RC(rc,NULL,
01766                             "images[temp_index]->crop(%u,%u,%u,%u) failed.",
01767                             x1, y1, x2, y2 );
01768 
01769                     rc = this->setInputImage(temp_image,
01770                                              ratio,nids,tag_ids);
01771                     phCHECK_RC(rc, NULL, "this->setInputImage()");
01772                 }
01773                 else /* use the preloaded images */
01774                 {
01775                     rc = this->setInputImage(image_array[i],
01776                                              ratio,nids,tag_ids);
01777                     phCHECK_RC(rc, NULL, "this->setInputImage()");
01778                 }        
01779 
01780                 rc = this->getNodes(&input_nodes,      /* fann_type **  */
01781                                     &output_nodes      /* fann_type **  */ );
01782                 phPRINT_RC(rc,NULL,"this->getNodes()");
01783 
01784                 input_array [processed_index] = input_nodes;
01785                 output_array[processed_index] = output_nodes;
01786                 input_nodes = NULL;
01787                 output_nodes = NULL;
01788 
01789                 /* Input a random image into the set */
01790                 if (generate_random)
01791                 {
01792                     char foofile[256];
01793                     
01794                     if (generate_random == 1)
01795                     {
01796                         rc = random_gradient(this->m_width,
01797                                           this->m_height,
01798                                           phImageRGB24,
01799                                           &temp_image );
01800                         phCHECK_RC(rc,NULL,"random_gradient");
01801                     }
01802                     else if (generate_random == 2)
01803                     {
01804                         rc = randomize_pixels(this->m_width,
01805                                               this->m_height,
01806                                               phImageRGB24,
01807                                               &temp_image );
01808                         phCHECK_RC(rc,NULL,"randomize_pixels");
01809                     }
01810                     else if (generate_random == 3)
01811                     {
01812                         rc = random_image(this->m_width,
01813                                           this->m_height,
01814                                           phImageRGB24,
01815                                           &temp_image );
01816                         phCHECK_RC(rc,NULL,"randomize_pixels");
01817                     }
01818                         
01819 #if 0
01820                     /* save a sampling of the random images */
01821                     if (processed_index < 5000)
01822                     {
01823                         snprintf(foofile,255,"random/file%06u.ppm",
01824                                  processed_index);
01825                         temp_image.save(foofile);
01826                     }
01827 #endif               
01828                     /* the 320 and 240 really don't matter; They could be 
01829                      * any number because we're dividing them; You would 
01830                      * just want the ranges of W and H to be too different */
01831                     rand_w = lrand48() % 321;
01832                     rand_h = lrand48() % 241;
01833                     ratio = ((float)rand_w) / ((float)rand_h);
01834                     
01835                     rc = this->setInputImage(temp_image,ratio,0,NULL);
01836                     phCHECK_RC(rc, NULL, "this->setInputImage()");
01837                 
01838                     rc = this->getNodes(&input_nodes,      /* fann_type **  */
01839                                         &output_nodes      /* fann_type **  */ );
01840                     phPRINT_RC(rc,NULL,"this->getNodes()");
01841 
01842                     rand_input_array [processed_index] = input_nodes;
01843                     rand_output_array[processed_index] = output_nodes;
01844                     input_nodes = NULL;
01845                     output_nodes = NULL;
01846                 }
01847 
01848                 processed_index++;
01849             } /* b : nbright_levels */
01850         } /* i :  nsets */
01851     } /* j : set_size */
01852 
01853     rc = this->shutdown();
01854     phPRINT_RC(rc,NULL,"this->shutdown()");
01855 
01856     /* Free up all the data */
01857     phDeleteArray(image_array);
01858     phFree(filename);
01859 
01860     /* Free the random selection arrays */
01861     rc = random_selection_free( &selection );
01862     phPRINT_RC(rc,NULL,"random_selection_free failed.");
01863 
01864     if (processed_index != total_imgs)
01865     {
01866         phPROGRESS("WARNING !!! All expected images weren't generated.\n");
01867     }
01868 
01869     /* Set the output pointers to the informatin generated from this method */
01870     if (pinput_array_count != NULL)
01871         *pinput_array_count = processed_index;
01872     
01873     if (ptrain_array_count != NULL)
01874         *ptrain_array_count = train_array_count;
01875    
01876     test_array_count = processed_index - train_array_count;
01877     
01878     if (ptest_array_count != NULL)
01879         *ptest_array_count = test_array_count;
01880     
01881     if (poutput_array_count != NULL)
01882         *poutput_array_count = processed_index;
01883     
01884     /* Set the input node array or free it */
01885     if (pinput_nodes == NULL) 
01886     {
01887         for (i = 0; i < total_imgs; i++ )
01888         {
01889             phFree(input_array[i]);
01890         }
01891         phFree(input_array);
01892     }
01893     else
01894         *pinput_nodes = input_array;
01895 
01896     if (poutput_nodes == NULL) 
01897     {
01898         for (i = 0; i < total_imgs; i++ )
01899         {
01900             phFree(output_array[i]);
01901         }
01902         phFree(output_array);
01903     }
01904     else
01905         *poutput_nodes= output_array;
01906 
01907     if (generate_random)
01908     {
01909         if (prand_input_nodes == NULL) 
01910         {
01911             for (i = 0; i < total_imgs; i++ )
01912             {
01913                 phFree(rand_input_array[i]);
01914             }
01915             phFree(rand_input_array);
01916         }
01917         else
01918             *prand_input_nodes = rand_input_array;
01919 
01920         if (prand_output_nodes == NULL) 
01921         {
01922             for (i = 0; i < total_imgs; i++ )
01923             {
01924                 phFree(rand_output_array[i]);
01925             }
01926             phFree(rand_output_array);
01927         }
01928         else
01929             *prand_output_nodes= rand_output_array;
01930     }
01931 
01932 
01933     return phSUCCESS;
01934 
01935 error:
01936     /* Free up all the data */
01937     phDeleteArray(image_array);
01938     phFree(filename);
01939                 
01940     /* Free the random selection arrays */
01941     rc = random_selection_free( &selection );
01942     phPRINT_RC(rc,NULL,"random_selection_free failed.");
01943 
01944     for (i = 0; (i < total_imgs) && (input_array); i++ )
01945     {
01946         phFree(input_array[i]);
01947     }
01948     phFree(input_array);
01949 
01950     for (i = 0; (i < total_imgs) && (output_array); i++ )
01951     {
01952         phFree(output_array[i]);
01953     }
01954     phFree(output_array);
01955     
01956     if (generate_random)
01957     {
01958         for (i = 0; (i < total_imgs) && (rand_input_array); i++ )
01959         {
01960             phFree(rand_input_array[i]);
01961         }
01962         phFree(rand_input_array);
01963 
01964         for (i = 0; (i < total_imgs) && (rand_output_array); i++ )
01965         {
01966             phFree(rand_output_array[i]);
01967         }
01968         phFree(rand_output_array);
01969     }
01970     return phFAIL;
01971 }
01972 
01973 /* ------------------------------------------------------------------------ */
01974 /* train
01975  *      This function is designed to train a neural network. It logs data
01976  *  about training and testing errors including percentages for correctly
01977  *  and incorrectly classified objects.
01978  */
01979 /* ------------------------------------------------------------------------ */
01980 /* preload_images   : Load the current set of images into an array so that 
01981  *                    all the hard drive accesses are done at once.
01982  * train_set_size   : 
01983  * test_set_size    :
01984  * max_epochs       :
01985  * desired_error    :
01986  * start_epoch      :
01987  *
01988  */
01989 /* important parameters: desired error, learning rate, max epochs,
01990  *                       num_layers, connection rate                        */
01991 /* ------------------------------------------------------------------------ */
01992 int phANNSystem::train(int      preload_images,
01993                        int      use_random,
01994                        uint32_t train_set_size,
01995                        uint32_t test_set_size,
01996                        uint32_t max_epochs,
01997                        float    desired_error,
01998                        uint32_t start_epoch )
01999 {
02000     phFUNCTION("phANNSystem::train")
02001 
02002     /* ------------------------------------------------------------------ */
02003     uint32_t    i = 0;
02004     uint32_t    last_j      = 1;
02005     char        *ann_prefix = "ann";
02006     char        suffix[255];
02007     
02008     ml_class_stats  *train_stats        = NULL;
02009     ml_class_stats  *test_stats         = NULL;
02010     ml_class_stats  *rand_train_stats   = NULL;
02011     ml_class_stats  *rand_test_stats    = NULL;
02012     ml_class_stats  *use_stats          = NULL;
02013     ml_class_stats  *rand_use_stats     = NULL;
02014     float           train_mse           = 0.0F;
02015     
02016     /* input and output are allocated and populated by this program;
02017      * actual_output is returned from fann_run and compared against the
02018      * output_nodes array to determine correctly classified objects */
02019     uint32_t    input_array_count   = 0;
02020     fann_type   **input_array       = NULL;
02021     uint32_t    output_array_count  = 0;
02022     fann_type   **output_array      = NULL;
02023     uint32_t    train_array_count   = 0;
02024     uint32_t    test_array_count    = 0;
02025     fann_type   **rand_input_array  = NULL;
02026     fann_type   **rand_output_array = NULL;
02027     
02028     fann_type   *actual_output      = NULL;
02029 
02030     uint32_t    nsets       = 0;
02031     uint32_t    node_index  = 0;
02032     uint32_t    epoch       = 0;
02033     int         trained     = 0;
02034     int         train_done  = 0;
02035 
02036     /* ------------------------------------------------------------------ */
02037     /* retreive the info from the data set */
02038     nsets               = idc_get_nsets( this->m_data );
02039 
02040     /* ------------------------------------------------------------------ */
02041     /* create a new class_stats object to calculate the per epoch stats... */
02042     /* ... for the actual input data */
02043     rc = ml_class_stats_new(this->m_num_output, &train_stats );
02044     phPRINT_RC(rc,NULL,"ml_class_stats_new");
02045     rc = ml_class_stats_new(this->m_num_output, &test_stats );
02046     phPRINT_RC(rc,NULL,"ml_class_stats_new");
02047     /* ... for the randomized information */
02048     if (use_random)
02049     {
02050         rc = ml_class_stats_new(this->m_num_output, &rand_train_stats );
02051         phPRINT_RC(rc,NULL,"ml_class_stats_new");
02052         rc = ml_class_stats_new(this->m_num_output, &rand_test_stats );
02053         phPRINT_RC(rc,NULL,"ml_class_stats_new");
02054     }
02055 
02056     /* Open the log file... */
02057     sprintf(suffix,"nimages%03u_ran%02d", nsets, use_random );
02058     this->openLogFile( ann_prefix, suffix );
02059 
02060     /* print the column headers to the log file */
02061     ml_class_stats_headers_print( this->m_logfp, 
02062                                   train_stats,
02063                                   idc_get_tags( this->m_data ), 
02064                                   idc_get_ntags( this->m_data ));
02065                
02066     /* generate the processed data */           
02067     rc = this->generateNodes( 0 /* preload images */,
02068                               use_random, /* generate random images */
02069                               train_set_size,
02070                               test_set_size,
02071                               &train_array_count,
02072                               &test_array_count,
02073                               &input_array_count,
02074                               &input_array,
02075                               &rand_input_array,
02076                               &output_array_count,
02077                               &output_array,
02078                               &rand_output_array );
02079     phCHECK_RC(rc,NULL,"ann_system->generateNodes");
02080 
02081     /* Create the network */
02082     rc = this->createNetwork();
02083     phPRINT_RC(rc,NULL,"this->createNetwork()");
02084     
02085     /* -------------------------------------------------------------- */
02086     /* Training set */
02087     phPRINT("Input Array Count      : %u\n",input_array_count);
02088     phPRINT("Output Array Count     : %u\n",output_array_count);
02089     phPRINT("Training size          : %u\n",train_array_count );
02090     phPRINT("Testing  size          : %u\n",test_array_count);
02091     phPRINT("\n\n");
02092     for (epoch = start_epoch; 
02093          ((epoch < max_epochs) && (!train_done)) || (epoch < 3); 
02094          epoch++ )
02095     {
02096         phPRINT("\nEpoch:%u\n",epoch);
02097 
02098         /* Reset the MSE for the training set */
02099         fann_reset_MSE(this->m_ann);
02100         ml_class_stats_reset(train_stats);
02101         ml_class_stats_reset(test_stats);
02102         if (use_random)
02103         {
02104             ml_class_stats_reset(rand_train_stats);
02105             ml_class_stats_reset(rand_test_stats);
02106         }
02107         use_stats       = train_stats;
02108         rand_use_stats  = rand_train_stats;
02109 
02110         train_mse   = 0.0F;
02111         trained     = 0;
02112         node_index  = 0;
02113 
02114         /* when node_index is less than train_set_size, we're training...
02115          * when node_index >= train_set_size and less than test_set_size, we're tesing... */
02116         while (node_index < input_array_count)
02117         {
02118             /* OUTPUT RESULTS:
02119              *  from the Training Set training */
02120             /* if node_index == train_set_size, we're on the transition from
02121              * training to testing and we need to reset the MSE for the
02122              * testing set */
02123             if ((node_index == train_array_count) && (trained == 0))
02124             {
02125                 train_mse = fann_get_MSE(this->m_ann);
02126                 
02127                 /* Print the testing set's final MSE */
02128                 phPRINT("Training Session (MSE: %8.20f)           \n",
02129                         fann_get_MSE(this->m_ann) );
02130                 
02131                 /* Reset the MSE,[in]correctly classified variables for the training set testing */
02132                 fann_reset_MSE(this->m_ann);
02133                 trained     = 1;
02134                 node_index  = 0;
02135             }
02136             /* OUTPUT RESULTS:
02137              *  from the Training Set's testing run */
02138             else if (node_index == train_array_count)
02139             {
02140                 /* Print the training set MSE to the log file *
02141                  * Print the classification statistics to file */
02142                 ml_class_stats_set_mse(train_stats,fann_get_MSE(this->m_ann));
02143 
02144                 this->print_epoch_info( "Training Set         ", 
02145                                         train_stats );
02146                 if (use_random)
02147                 {
02148                     this->print_epoch_info( "Training Set (random)", 
02149                                             rand_train_stats );
02150                 }                    
02151                 /* Reset the MSE,[in]correctly classified variables for the validation set testing */
02152                 fann_reset_MSE(this->m_ann);
02153 
02154                 /* switch to using the test_stats variable for the actual
02155                  * testing loop */
02156                 use_stats       = test_stats;
02157                 rand_use_stats  = rand_test_stats;
02158             }
02159 
02160             if ((node_index % 100) == 0)
02161             {
02162                 if (!trained)
02163                 {
02164                     phPRINT("Training               (%5d of %5d)\r", 
02165                             /* total train image sets */
02166                             node_index+1, train_array_count );
02167                 }
02168                 else if (node_index <= train_array_count)
02169                 {
02170                     phPRINT("Training set testing   (%5d of %5d)\r",
02171                             /* total train image sets */
02172                             node_index+1, train_array_count );
02173                 }
02174                 else
02175                 {
02176                     phPRINT("Validation set testing (%5d of %5d)\r",
02177                             (node_index - train_array_count)+1,
02178                             (input_array_count - train_array_count) );
02179                 }
02180             }
02181             
02182             /* TRAIN */
02183             if (!trained)
02184             {
02185                 /* Train on the data * -------------------------------- */
02186                 fann_train(this->m_ann, 
02187                             input_array[node_index], 
02188                             output_array[node_index] );
02189             }
02190             /* TEST */
02191             else
02192             {
02193                 /* Test on the data * -------------------------------- */
02194                 fann_test(this->m_ann, 
02195                           input_array[node_index], 
02196                           output_array[node_index] );
02197 
02198                 /* Run the ANN and get the output for comparison
02199                  * against the expected output so we can compute the
02200                  * correctly classified sets */
02201                 actual_output = fann_run(this->m_ann, 
02202                                          input_array[node_index] );
02203 
02204                 ml_class_stats_classify( use_stats,
02205                                          output_array[node_index],
02206                                          actual_output );
02207             }
02208             
02209             /* RANDOM IMAGE TRAIN */
02210             if ((!trained) && (use_random))
02211             {
02212                 /* Train on the data * -------------------------------- */
02213                 fann_train(this->m_ann, 
02214                            rand_input_array[node_index], 
02215                            rand_output_array[node_index] );
02216             }
02217             /* TEST */
02218             else if (use_random)
02219             {
02220                 /* Test on the data * -------------------------------- */
02221                 fann_test(this->m_ann, 
02222                           rand_input_array[node_index], 
02223                           rand_output_array[node_index] );
02224 
02225                 /* Run the ANN and get the output for comparison
02226                  * against the expected output so we can compute the
02227                  * correctly classified sets */
02228                 actual_output = fann_run(this->m_ann, 
02229                                          rand_input_array[node_index] );
02230 
02231                 ml_class_stats_classify( rand_use_stats,
02232                                          rand_output_array[node_index],
02233                                          actual_output );
02234             }
02235             node_index++;
02236         } /* node_index < input_array_count */
02237 
02238         /* Set the TESTing MSE */
02239         ml_class_stats_set_mse(test_stats,fann_get_MSE(this->m_ann));
02240 
02241         /* Print the stat info to the log file */
02242         rc = ml_class_stats_row_print(this->m_logfp,epoch,train_mse,
02243                                       train_stats,test_stats );
02244         phCHECK_RC(rc,NULL,"ml_class_stats_row_print");
02245         
02246         this->print_epoch_info("Testing Set          ", test_stats);
02247         if (use_random)
02248         {
02249             this->print_epoch_info("Testing Set  (random)", rand_test_stats);
02250         }
02251 
02252         if ( fann_get_MSE(this->m_ann) < desired_error )
02253         {
02254             phPRINT("final MSE: %f\n", fann_get_MSE(this->m_ann));
02255             train_done = 1;
02256         }
02257 
02258         sprintf(suffix,"nimages%03u_ran%02u_epoch%03u", nsets, use_random,epoch );
02259         this->saveNetwork(ann_prefix,suffix);
02260 
02261     } /* epoch : !train_done, max_epochs */
02262 
02263     rc = this->destroyNetwork();
02264     phPRINT_RC(rc,NULL,"this->destroyNetwork()");
02265 
02266     /* Free the processed data */
02267     for (i = 0; i < input_array_count; i++ )
02268     {
02269         phFree(input_array[i]);
02270     }
02271     phFree(input_array);
02272 
02273     for (i = 0; i < output_array_count; i++ )
02274     {
02275         phFree(output_array[i]);
02276     }
02277     phFree(output_array);
02278     
02279     /* Free the statistics object */
02280     rc = ml_class_stats_free(&train_stats);
02281     phPRINT_RC(rc, NULL, "ml_class_stats_free");
02282     rc = ml_class_stats_free(&test_stats);
02283     phPRINT_RC(rc, NULL, "ml_class_stats_free");
02284 
02285     /* Delete the randomized information */
02286     if (use_random)
02287     {
02288         for (i = 0; i < input_array_count; i++ )
02289         {
02290             phFree(rand_input_array[i]);
02291         }
02292         phFree(rand_input_array);
02293 
02294         for (i = 0; i < output_array_count; i++ )
02295         {
02296             phFree(rand_output_array[i]);
02297         }
02298         phFree(rand_output_array);
02299 
02300         /* Free the randomized data  statistics object */
02301         rc = ml_class_stats_free(&rand_train_stats);
02302         phPRINT_RC(rc, NULL, "ml_class_stats_free");
02303         rc = ml_class_stats_free(&rand_test_stats);
02304         phPRINT_RC(rc, NULL, "ml_class_stats_free");
02305     }
02306 
02307     return phSUCCESS;
02308 
02309 error:
02310     /* Free the processed data */
02311     for (i = 0; i < input_array_count; i++ )
02312     {
02313         phFree(input_array[i]);
02314     }
02315     phFree(input_array);
02316 
02317     for (i = 0; i < output_array_count; i++ )
02318     {
02319         phFree(output_array[i]);
02320     }
02321     phFree(output_array);
02322  
02323     /* Free the statistics object */
02324     rc = ml_class_stats_free(&train_stats);
02325     phPRINT_RC(rc, NULL, "ml_class_stats_free");
02326     rc = ml_class_stats_free(&test_stats);
02327     phPRINT_RC(rc, NULL, "ml_class_stats_free");
02328 
02329     /* Delete the randomized information */
02330     if (use_random)
02331     {
02332         for (i = 0; i < input_array_count; i++ )
02333         {
02334             phFree(rand_input_array[i]);
02335         }
02336         phFree(rand_input_array);
02337 
02338         for (i = 0; i < output_array_count; i++ )
02339         {
02340             phFree(rand_output_array[i]);
02341         }
02342         phFree(rand_output_array);
02343 
02344         /* Free the randomized data  statistics object */
02345         rc = ml_class_stats_free(&rand_train_stats);
02346         phPRINT_RC(rc, NULL, "ml_class_stats_free");
02347         rc = ml_class_stats_free(&rand_test_stats);
02348         phPRINT_RC(rc, NULL, "ml_class_stats_free");
02349     }
02350 
02351     return phFAIL;
02352 }
02353     
02354 /* ------------------------------------------------------------------------ */
02355 uint32_t phANNSystem::nodesToString( fann_type *output_nodes,
02356                                      uint32_t  *string_size,
02357                                      char      **string )
02358 {
02359     phFUNCTION("phANNSystem::nodesToString")
02360 
02361     uint32_t    i               = 0;
02362     uint32_t    active_nodes    = 0;
02363     uint32_t    pos             = 0;
02364     uint32_t    len             = 0;
02365     char        **tags          = NULL;
02366     uint32_t    ntags           = 0;
02367     char        *buf            = NULL;
02368 
02369     if ((output_nodes == NULL) || 
02370         (string_size == NULL) ||
02371         (string == NULL))
02372     {
02373         return 0;
02374     }
02375     
02376     tags = idc_get_tags( this->m_data );
02377     ntags = idc_get_ntags( this->m_data );
02378 
02379     if (ntags == 0) return 0;
02380 
02381     if (*string == NULL)
02382     {
02383         *string = (char *)phCalloc(2,sizeof(char));
02384         phCHECK_PTR(*string,"phCalloc","phCalloc failed.");
02385         
02386         *string_size = 2;
02387     }
02388     
02389     phMemset(*string,0,sizeof(char)*(*string_size));
02390     
02391     for (i = 0; (i < this->m_num_output) && (i < ntags); i++ )
02392     {
02393         if (output_nodes[i] >= 0.99999F)
02394         {
02395             active_nodes++;
02396             
02397             if (buf == NULL)
02398             {
02399                 buf = (char *)phCalloc(256,sizeof(char));
02400                 phCHECK_PTR(buf,"phCalloc","phCalloc failed.");
02401             }
02402             
02403             /* print the string to a buffer */
02404             snprintf(buf,255,"[%s]",tags[i]);
02405             
02406             len += strlen(buf);
02407             if (*string_size < (len+pos+1))
02408             {
02409                 /* +1 for the NULL BYTE */
02410                 *string = (char *)phRealloc((*string),(len + 1)*sizeof(char));
02411                 phCHECK_PTR(*string,"phRealloc","phRealloc failed");
02412                 *string_size = len + 1;
02413             }
02414             
02415             sprintf(&((*string)[pos]),"%s",buf);
02416             
02417             pos = strlen((*string));
02418         }
02419     }
02420     
02421     phFree(buf);
02422     return active_nodes;
02423 error:
02424     phFree(buf);
02425     return 0;
02426 }
02427 
02428 /* ------------------------------------------------------------------------ */
02429 /* type - 0:ppm w/input_label == prefix of ppm files; prefix_00000.ppm
02430  *        1:jpg ''
02431  *        2:video capture w/input_label == device string;"/dev/video0","0"
02432  */
02433 /* ------------------------------------------------------------------------ */
02434 int phANNSystem::classify( const char     *input_label,
02435                            const int      input_type,
02436                            const uint32_t total_files )
02437 {
02438     phFUNCTION("phANNSystem::classify")
02439 
02440     int retrc = phSUCCESS;
02441 
02442     /* input and output are allocated and populated by this program;
02443      * actual_output is returned from fann_run and compared against the
02444      * output_nodes array to determine correctly classified objects */
02445     uint32_t        input_nodes_count   = 0;
02446     uint32_t        input_nodes_size    = 0;
02447     fann_type       *input_nodes        = NULL;
02448     fann_type       *actual_output      = NULL;
02449 
02450     char       *class_string        = NULL;
02451     uint32_t    class_string_size   = 0;
02452     
02453     float       ratio               = 0.0;
02454     
02455     int use_hsvthresh = 0;
02456     int use_sobel = 0;
02457     int use_canny = 1;
02458 
02459     int                 loop        = 0;
02460     uint32_t            filecount   = 0;
02461     char                *filename   = NULL;
02462     
02463     phImage             *input_image= NULL;
02464 
02465     gaussianBlur_Filter *gauss      = NULL;
02466     meanNxN_Filter      *mean       = NULL;
02467     medianNxN_Filter    *med        = NULL;
02468     sobel_Filter        *sobel      = NULL;
02469     subtract_Filter     *sub        = NULL;
02470     original_Filter     *orig       = NULL;
02471     inverse_Filter      *inverse    = NULL;
02472     convert_Filter      *grey_convert = NULL;
02473     threshold_Filter    *threshold_grey = NULL;
02474     threshold_Filter    *thresholdr = NULL;
02475     threshold_Filter    *thresholdg = NULL;
02476     threshold_Filter    *thresholdb = NULL;
02477     hsvthreshold_Filter *hsvthresh  = NULL;
02478     convert_Filter      *hsvconvert = NULL;
02479 #if PH_HAVE_OPENCV
02480     cv_canny_Filter     *canny      = NULL;
02481 #else
02482     canny_Filter        *canny      = NULL;
02483 #endif
02484     
02485     phSystem            *system     = NULL;
02486     phPipeline          *pipeline   = NULL;
02487     X11Display          *display    = NULL;
02488     X11Display          *monitor_display    = NULL;
02489 #ifdef WIN32
02490     VFWSource           *capture    = NULL;
02491 #else
02492     V4LCapture          *capture    = NULL;
02493 #endif
02494 
02495     int32_t hl = 0;
02496     int32_t sl = 0;
02497     int32_t vl = 0;
02498     int32_t hu = 0;
02499     int32_t su = 0;
02500     int32_t vu = 0;
02501     
02502     autoblob_Filter *blob       = NULL;
02503     phAutoBlobData  *blob_data  = NULL;
02504     uint32_t        minsize     = 150;
02505     uint32_t        total_blobs = 0;
02506     
02507     phautoblob  blobinfo;
02508     phImage     crop_image;
02509     uint32_t    i = 0;
02510     
02511     /* non-autoblobbing */
02512     phColor     outcolor    = phColorRGB24_new(0,255,255);
02513 
02514     /* autoblobbing */
02515     /* for HSV:
02516      * the SV thresholds effect how well objects with gradients
02517      * are matched. If the gradient is one direction, an S of 
02518      * 10 low and 80 high will match gradients where they get 
02519      * more saturated as they go from the top of the image down.
02520      * The reverse applies for 80 low and 10 high.
02521      * The same goes for the V channel where there may be a gradual
02522      * increase/decrease in the color value and a significant difference
02523      * in the thresholds will match different gradients better */
02524     /* For RGB:
02525      * All the pixel channels can be used the same way as discussed 
02526      * above. When the lower threshold is less than the upper threshold,
02527      * then there is a certain type of gradient that is matched. The 
02528      * gradient is usuallu due to certain lighting. In the case,
02529      * of the auto blob filter, lower to upper is from top left to bottom
02530      * right */
02531 
02532 #if 0
02533     /* good for the solid color blocks */
02534     /* 
02535     phColor     lower_threshold = phColorHSV24_new(1,1,1);
02536     phColor     upper_threshold = phColorHSV24_new(1,1,1);
02537     phColor     loop_threshold  = phColorHSV24_new(0,0,0);
02538     */
02539     /* good for the sphere images */
02540     /*
02541     phColor     lower_threshold = phColorHSV24_new(8,2,2);
02542     phColor     upper_threshold = phColorHSV24_new(8,15,11);
02543     phColor     loop_threshold  = phColorHSV24_new(0,0,0);
02544     */
02545 #else
02546 
02547 /* movie0 */
02548 #if 0
02549     phColor     lower_threshold = phColorHSV24_new(5,24,25);
02550     phColor     upper_threshold = phColorHSV24_new(5,84,55);
02551     phColor     loop_threshold  = phColorHSV24_new(0,0,0);
02552 #endif
02553 /* movie5 */
02554 #if 0
02555     phColor     lower_threshold = phColorHSV24_new(5,20,25);
02556     phColor     upper_threshold = phColorHSV24_new(9,55,55);
02557     phColor     loop_threshold  = phColorHSV24_new(0,0,0);
02558 #endif
02559 #if 0
02560     phColor     lower_threshold = phColorHSV24_new(3,20,25);
02561     phColor     upper_threshold = phColorHSV24_new(5,55,55);
02562     phColor     loop_threshold  = phColorHSV24_new(0,0,0);
02563 #endif
02564 /* Movie 0 with RGB */
02565 #if 1
02566     phColor     lower_threshold = phColorRGB24_new(15,15,15);
02567     phColor     upper_threshold = phColorRGB24_new(18,18,18);
02568     phColor     loop_threshold  = phColorRGB24_new(0,0,0);
02569 #endif
02570 #endif
02571     
02572     uint32_t threshold_value = 80;
02573     
02574     system          = new phSystem();
02575     gauss           = new gaussianBlur_Filter();
02576     mean            = new meanNxN_Filter(3);
02577     med             = new medianNxN_Filter(3);
02578     sobel           = new sobel_Filter();
02579 #if PH_HAVE_OPENCV
02580     //canny           = new cv_canny_Filter(50,175,3);//(40,50);
02581     canny           = new cv_canny_Filter(94,165,3);
02582 #else
02583     canny           = new canny_Filter(100,200);
02584 #endif
02585     sub             = new subtract_Filter();
02586     grey_convert    = new convert_Filter(phImageGREY8);
02587     threshold_grey  = new threshold_Filter(0,threshold_value);
02588     thresholdr      = new threshold_Filter(0,threshold_value);
02589     thresholdg      = new threshold_Filter(1,threshold_value);
02590     thresholdb      = new threshold_Filter(2,threshold_value);
02591     orig            = new original_Filter();
02592     inverse         = new inverse_Filter();
02593     blob            = new autoblob_Filter();
02594     blob_data       = new phAutoBlobData();
02595     pipeline        = new phPipeline();
02596     hsvconvert      = new convert_Filter(phImageHSV24);
02597     hsvthresh       = new hsvthreshold_Filter(  0,  1,  1,
02598                                                 1, 20, 20,
02599                                               255,250,255);
02600     if (this->m_no_displays == 0)
02601     {
02602         display         = new X11Display();
02603         monitor_display = new X11Display();
02604     }
02605 
02606     filename = (char *)phCalloc(513,sizeof(char));
02607     phCHECK_PTR(filename,"phCalloc","phCalloc failed.");
02608 
02609     if (input_type == 2)
02610     {
02611 #ifdef WIN32
02612         capture = new VFWSource();
02613 #else
02614         capture = new V4LCapture();
02615 #endif
02616         rc = capture->set(320,240,(char*)input_label);
02617         phCHECK_RC(rc,NULL,"capture->set");
02618 
02619         rc = pipeline->setLiveSourceInput(capture->getLiveSourceOutput());
02620         phCHECK_RC(rc,NULL,"pipeline->setLiveSourceInput()");
02621 
02622         rc = system->add(capture);
02623         phCHECK_RC(rc,NULL,"system->add(capture)");
02624     }
02625     else
02626     {
02627         input_image     = new phImage();
02628 
02629         rc = pipeline->setLiveSourceInput(input_image);
02630         phCHECK_RC(rc,NULL,"pipeline->setLiveSourceInput()");
02631     }
02632 
02633     if (this->m_no_displays == 0)
02634     {
02635         rc = display->setLiveSourceInput(pipeline->getLiveSourceOutput());
02636         phCHECK_RC(rc,NULL,"display->setLiveSourceInput()");
02637 
02638         rc = system->add(display);
02639         phCHECK_RC(rc,NULL,"system->add(display)");
02640         
02641         rc = system->add(monitor_display);
02642         phCHECK_RC(rc,NULL,"system->add(monitor_display)");
02643     }
02644 
02645     rc = system->add(pipeline);
02646     phCHECK_RC(rc,NULL,"system->add(pipeline)");
02647 
02648     rc = pipeline->add(gauss);
02649     //rc = pipeline->add(mean);
02650     //rc = pipeline->add(med);
02651     
02652     //monitor_display->setLiveSourceInput(input_image);
02653     monitor_display->setLiveSourceInput(canny->getLiveSourceOutput());
02654     //monitor_display->setLiveSourceInput(thresholdb->getLiveSourceOutput());
02655     
02656     if ((use_sobel) || (use_canny))
02657     {
02658         if (use_canny && use_sobel)
02659         {
02660             sub->set(3,1,3);
02661         }
02662         else
02663         {
02664             sub->set(2,1,2);
02665         }
02666         rc = pipeline->add(sub);
02667         rc = pipeline->add(orig);
02668         if (use_canny)
02669         {
02670             rc = pipeline->add(canny);
02671 #if ! PH_HAVE_OPENCV
02672             rc = pipeline->add(inverse);
02673 #endif
02674             rc = pipeline->add(sub);
02675         }
02676         if (use_sobel)
02677         {
02678             if (use_canny) 
02679             {
02680                 rc = pipeline->add(orig);
02681             }
02682             rc = pipeline->add(gauss);
02683             rc = pipeline->add(sobel);
02684             rc = pipeline->add(inverse);
02685 #if 0
02686             rc = pipeline->add(grey_convert);
02687             rc = pipeline->add(threshold_grey);
02688             rc = pipeline->add(gauss);
02689 #endif
02690 #if 1
02691             rc = pipeline->add(thresholdr);
02692             rc = pipeline->add(thresholdg);
02693             rc = pipeline->add(thresholdb);
02694 #endif
02695             //rc = pipeline->add(canny);
02696             rc = pipeline->add(sub);
02697 
02698         }
02699     }
02700     
02701     if (use_hsvthresh)
02702     {
02703         rc = pipeline->add(hsvconvert);
02704         rc = pipeline->add(hsvthresh);
02705     }
02706     rc = pipeline->add(blob);
02707 
02708     rc = blob->setThresholds(lower_threshold,
02709                              upper_threshold,
02710                              loop_threshold);
02711     rc = blob->setAutoBlob();
02712     //rc = blob->setOutcolor(outcolor);
02713     //rc = blob->setDrawRects(1);
02714     rc = blob->setColorBlobs(1);
02715     rc = blob->setColorMinSize(minsize);
02716 
02717     /* connect the blob data to the blob's data output */
02718     rc = blob_data->connect(blob->getLiveBlobOutput());
02719     phPRINT_RC(rc,NULL,"blob_data->connect");
02720 
02721     rc = this->createNetwork();
02722     phPRINT_RC(rc,NULL,"this->createNetwork()");
02723     
02724     rc = this->startup();
02725     phPRINT_RC(rc,NULL,"this->startup");
02726     
02727     rc = system->startup();
02728     phCHECK_RC(rc,NULL,"system->startup()");
02729 
02730     while (((system->displaysOpen() > 0)) || (this->m_no_displays))
02731     {
02732         if (input_type < 2)
02733         {
02734             if (filecount == 0)
02735             {
02736                 //filecount = 10;
02737             }
02738 
02739             sprintf(filename,
02740                     "%s_%04u.%s",
02741                     input_label,
02742                     filecount,
02743                     input_type == 1 ? "jpg" : "ppm");
02744 
02745             rc = input_image->load(filename);
02746             phCHECK_RC(rc,NULL,"input_image->load(%s)",filename);
02747 
02748             rc = blob_data->update();
02749             phPRINT_RC(rc,NULL,"blob_data");
02750             
02751             if ((total_blobs = blob_data->getTotalBlobs(minsize)) > 0)
02752             {
02753                 blobinfo = blob_data->getBlob(0);
02754                 phPRINT("Total Blobs: %5u %5d:( %3d, %3d; %3d, %3d ) ( %3d x %3d )\n",
02755                         blob_data->getTotalBlobs(minsize),
02756                         blobinfo.mass,
02757                         blobinfo.x1,
02758                         blobinfo.y1,
02759                         blobinfo.x2,
02760                         blobinfo.y2,
02761                         blobinfo.w,
02762                         blobinfo.h
02763                         );
02764                 for (i = 0; i < total_blobs; i++ )
02765                 {
02766                     /* The the information on the blob */
02767                     blobinfo = blob_data->getBlob(i);
02768 
02769                     /* Crop the blob out from the input image */
02770                     rc = crop_image.crop(*input_image,
02771                             blobinfo.x1 - 6,
02772                             blobinfo.y1 - 6,
02773                             blobinfo.x2 + 6, 
02774                             blobinfo.y2 + 6);
02775                     phPRINT_RC(rc,NULL,"crop_image.crop");
02776 
02777                     /* Get the ratio of the blobs w/h for input */
02778                     ratio = crop_image.getWidth() / crop_image.getHeight();
02779 
02780                     /* don't resize the image */
02781 #if 0
02782                     rc = crop_image.resize(this->m_width,this->m_height);
02783                     phPRINT_RC(rc,NULL,"crop_image.resize(%u,%u)",
02784                                this->m_width,this->m_height);
02785 #endif
02786                     rc = this->setInputImage( crop_image, ratio );
02787                     phPRINT_RC(rc,NULL,"this->setInputImage(crop_image,ratio)");
02788                     
02789                     rc = this->getInputNodes( &input_nodes_count,/* uint32_t *    */
02790                                               &input_nodes_size, /* uint32_t *    */
02791                                               &input_nodes       /* fann_type **  */ );
02792                     phPRINT_RC(rc,NULL,"this->getInputNodes()");
02793                     
02794                     actual_output = fann_run(this->m_ann, input_nodes);
02795 
02796                     rc = this->nodesToString(actual_output,
02797                                              &class_string_size,
02798                                              &class_string);
02799                     /* rc == number of active nodes */                       
02800                     if (rc)
02801                     {
02802                         phPRINT("%s\n",class_string);
02803                         snprintf(filename,512,"blobs/file%05d_blob%06d_%s.ppm",
02804                                 filecount, i, class_string);
02805                     }
02806                     else
02807                     {
02808                         snprintf(filename,512,"blobs/file%05d_blob%06d_[unknown].ppm",
02809                                 filecount, i );
02810                     }
02811                     crop_image.save(filename);
02812                 }
02813             }
02814             else
02815             {
02816                 phPRINT("Total Blobs: %5u mass_:( x1x, y1y; x2x, y2y ) ( www x hhh )\n",
02817                         blob_data->getTotalBlobs(minsize));
02818             }
02819 
02820             if (total_files > 10)
02821                 filecount += 5;
02822             else
02823                 filecount += 1;
02824             
02825             if (filecount >= total_files)
02826             {
02827                 if (loop)
02828                     filecount = 0;
02829                 else
02830                     system->stopDisplays();
02831             }
02832 
02833             //phUSleep(1333333);
02834         }
02835     }
02836 
02837     goto success;
02838 error:
02839     retrc = phFAIL;
02840 success:
02841     
02842     rc = this->shutdown();
02843     phPRINT_RC(rc,NULL,"this->shutdown");
02844     
02845     rc = this->destroyNetwork();
02846     phPRINT_RC(rc,NULL,"this->destroyNetwork()");
02847     
02848     rc = system->shutdown();
02849     phPRINT_RC(rc,NULL,"system->shutdown()");
02850 
02851     phFree(input_nodes);
02852     phFree(class_string);
02853 
02854     phDelete(input_image);
02855     phDelete(system);
02856     phDelete(gauss);
02857     phDelete(mean);
02858     phDelete(med);
02859     phDelete(sobel);
02860     phDelete(grey_convert);
02861     phDelete(threshold_grey);
02862     phDelete(thresholdr);
02863     phDelete(thresholdg);
02864     phDelete(thresholdb);
02865     phDelete(canny);
02866     phDelete(inverse);
02867     phDelete(sub);
02868     phDelete(orig);
02869     phDelete(hsvconvert);
02870     phDelete(hsvthresh);
02871     phDelete(blob);
02872     phDelete(blob_data);
02873     phDelete(pipeline);
02874     phDelete(display);
02875     phDelete(monitor_display);
02876     phFree(filename);
02877 
02878     return retrc;
02879 }
02880 




Copyright (C) 2002 - 2007 Philip D.S. Thoren ( pthoren@users.sourceforge.net )
University Of Massachusetts at Lowell
Robotics Lab
SourceForge.net Logo

Generated on Sat Jun 16 02:44:06 2007 for phission by  doxygen 1.4.4