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 |