Changeset 97 for liacs/MIR2010/SourceCode/main.cpp
- Timestamp:
- Apr 6, 2010, 7:16:33 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
liacs/MIR2010/SourceCode/main.cpp
r96 r97 40 40 float average[CATEGORY_SIZE][BIN_COUNT*BIN_COUNT*BIN_COUNT]; 41 41 42 43 // Find common coloured shapes as characteristics 44 // Walk over image with SPREAD steps, if pixel -within TOLERANCE- matches previous pixel 45 // make the size of the specific block bigger. 46 #define TOLERANCE 20 47 #define SPREAD 20 48 #define MAX_SIZE 500 49 float average_block[CATEGORY_SIZE][MAX_SIZE/SPREAD]; 50 51 42 52 // Some prototyping foo on functions 53 #define p_err(err_msg) printf("ERROR: %s\n", err_msg); 43 54 #define _return(err_msg, retval) printf("DEBUG: %s\n",err_msg); cin.get(); return(retval); 44 45 bool verbose = false; 55 #define cout_status(msg,flag) cout << msg; (flag) ? cout << " off" : cout << " on"; cout << endl; 56 57 58 bool opt_verbose = false; 59 bool opt_histogram = true; 60 bool opt_block = true; 46 61 47 62 bool file_exists(const char * filename) … … 114 129 cout << "3. determine winter sport" << endl; 115 130 cout << "4. batch test winter sport" << endl; 116 cout << "v. Turn verbose mode "; 117 if (verbose) 118 cout << "off" << endl; 119 else 120 cout << "on" << endl; 131 cout_status("v. Turn verbose mode", opt_verbose); 132 cout_status("h. Turn histogram classifier", opt_histogram); 133 cout_status("b. Turn block classifier", opt_block); 134 121 135 cout << endl; 122 136 cout << "Please select option, or type 'q' to quit: "; … … 126 140 // start the chosen option 127 141 switch (c) 128 { 142 { 129 143 case 'q': 130 144 return 0; … … 158 172 break; 159 173 case 'v': 160 verbose = (!verbose); 174 opt_verbose = (!opt_verbose); 175 break; 176 case 'b': 177 opt_block = (!opt_block); 178 break; 179 case 'h': 180 opt_histogram = (!opt_histogram); 181 break; 161 182 default: 162 183 continue; … … 207 228 } 208 229 230 // histogram should be a preallocated array of size BIN_COUNT*BIN_COUNT*BIN_COUNT elements and will 231 // be filled with the color histogram of the image where path points at 232 bool CalculateBlock(const char *path, float *block) 233 { 234 // load the image 235 CxImage image(path, CXIMAGE_FORMAT_JPG); 236 if (!image.IsValid()) 237 return false; 238 // clear histogram 239 memset(block, 0, MAX_SIZE/SPREAD * sizeof(float)); 240 // walk through the pixels to fill the histogram 241 const int width = (int)image.GetWidth(); 242 const int height = (int)image.GetHeight(); 243 244 int rgb_value = 0; 245 int rgb_prev = 0; 246 247 int block_size = 0; 248 249 for (int y = 0; y < height; y += SPREAD) 250 { 251 for (int x = 0; x < width; x += SPREAD) 252 { 253 // Note: CxImage library starts counting at lower-left corner of the image, 254 // which is seen as the top of the image. 255 RGBQUAD rgb = image.BlindGetPixelColor(x, y, false); 256 rgb_value = (rgb.rgbRed + rgb.rgbBlue + rgb.rgbGreen); 257 258 if (abs(rgb_value - rgb_prev) > TOLERANCE) { 259 block[block_size]++; 260 block_size = 1; 261 } 262 rgb_prev = rgb_value; 263 } 264 } 265 return true; 266 } 267 209 268 bool CalculateDescriptors(const char *basedir) 210 269 { 211 270 // the histogram that we reuse for each image 212 271 float *histogram = new float[BIN_COUNT*BIN_COUNT*BIN_COUNT]; 272 float *block = new float[MAX_SIZE/SPREAD]; 213 273 // walk through all images 214 274 // Note: each of the three categories has 50 images … … 234 294 if (!CalculateDescriptor(path, histogram)) 235 295 goto failure; 236 // save the descriptor to disk 296 297 if (!CalculateBlock(path, block)) 298 goto failure; 299 300 // save the descriptor,block to disk 237 301 SAFE_SPRINTF(path, sizeof(path), "%s%i.dat", catdir, i); 238 302 if ((file = fopen(path, "wb")) == NULL) … … 240 304 if (fwrite(histogram, sizeof(float), BIN_COUNT*BIN_COUNT*BIN_COUNT, file) != BIN_COUNT*BIN_COUNT*BIN_COUNT) 241 305 goto failure; 306 if (fwrite(block, sizeof(float), MAX_SIZE/SPREAD, file) != MAX_SIZE/SPREAD) 307 goto failure; 242 308 SAFE_CLOSEFILE(file); 309 310 243 311 } 244 312 } 245 313 // release resources 246 314 SAFE_DELETE_ARRAY(histogram); 315 SAFE_DELETE_ARRAY(block); 247 316 return true; 248 317 … … 250 319 SAFE_CLOSEFILE(file); 251 320 SAFE_DELETE_ARRAY(histogram); 321 SAFE_DELETE_ARRAY(block); 252 322 return false; 253 323 } … … 258 328 // characteristics of that category 259 329 float *histogram = new float[BIN_COUNT*BIN_COUNT*BIN_COUNT]; 330 float *block = new float[MAX_SIZE/SPREAD]; 331 float *average_block = new float[MAX_SIZE/SPREAD]; 260 332 float *average = new float[BIN_COUNT*BIN_COUNT*BIN_COUNT]; 261 333 // walk through all descriptors … … 277 349 SAFE_SPRINTF(path, sizeof(path), "%s%i.dat", catdir, i); 278 350 if (!file_exists(path)) { 351 p_err("File does not exists"); 279 352 continue; 280 353 } 281 354 cout << "[" << catname << "] processing image " << i << endl; 282 355 // load the histogram descriptor 283 if ((file = fopen(path, "rb")) == NULL) 284 goto failure; 285 if (fread(histogram, sizeof(float), BIN_COUNT*BIN_COUNT*BIN_COUNT, file) != BIN_COUNT*BIN_COUNT*BIN_COUNT) 286 goto failure; 356 if ((file = fopen(path, "rb")) == NULL) { 357 p_err("Cannot open average datafile"); 358 goto failure; 359 } 360 if (fread(histogram, sizeof(float), BIN_COUNT*BIN_COUNT*BIN_COUNT, file) != BIN_COUNT*BIN_COUNT*BIN_COUNT) { 361 p_err("Cannot read histogram"); 362 goto failure; 363 } 364 if (fread(block, sizeof(float), MAX_SIZE/SPREAD, file) != MAX_SIZE/SPREAD) { 365 p_err("Cannot read block"); 366 goto failure; 367 } 368 287 369 SAFE_CLOSEFILE(file); 288 370 // add the value of each bin to the average … … 290 372 average[b] += histogram[b]; 291 373 374 for (int b = 0; b < MAX_SIZE/SPREAD; b++) 375 average_block[b] += block[b]; 376 292 377 c_size++; 293 378 } … … 295 380 for (int b = 0; b < BIN_COUNT*BIN_COUNT*BIN_COUNT; b++) 296 381 average[b] /= c_size; 382 383 for (int b = 0; b < MAX_SIZE/SPREAD; b++) 384 average_block[b] /= c_size; 385 297 386 // save the average to disk 298 387 SAFE_SPRINTF(path, sizeof(path), "%s%s.dat", catdir, "average"); … … 301 390 if (fwrite(average, sizeof(float), BIN_COUNT*BIN_COUNT*BIN_COUNT, file) != BIN_COUNT*BIN_COUNT*BIN_COUNT) 302 391 goto failure; 392 if (fwrite(average_block, sizeof(float), MAX_SIZE/SPREAD, file) != MAX_SIZE/SPREAD) 393 goto failure; 394 303 395 SAFE_CLOSEFILE(file); 304 396 } … … 306 398 SAFE_DELETE_ARRAY(histogram); 307 399 SAFE_DELETE_ARRAY(average); 400 SAFE_DELETE_ARRAY(block); 308 401 return true; 309 402 … … 311 404 SAFE_CLOSEFILE(file); 312 405 SAFE_DELETE_ARRAY(histogram); 313 SAFE_DELETE_ARRAY( average);406 SAFE_DELETE_ARRAY(block); 314 407 return false; 315 408 } … … 335 428 if (fread(average[c], sizeof(float), BIN_COUNT*BIN_COUNT*BIN_COUNT, file) != BIN_COUNT*BIN_COUNT*BIN_COUNT) 336 429 return false; 430 if (fread(average_block[c], sizeof(float), MAX_SIZE/SPREAD, file) != MAX_SIZE/SPREAD) 431 return false; 432 337 433 SAFE_CLOSEFILE(file); 338 434 } … … 340 436 } 341 437 342 int DetermineCategory(const char *path, const int guess=-1 ) {438 int DetermineCategory(const char *path, const int guess=-1, const bool verbose=false) { 343 439 float *histogram = new float[BIN_COUNT*BIN_COUNT*BIN_COUNT]; 440 float *block = new float[MAX_SIZE/SPREAD]; 344 441 float cat2dist[CATEGORY_SIZE]; 442 float cat2block[CATEGORY_SIZE]; 345 443 346 444 /* First category default best canidate */ 347 int retval = 0; 445 int cat_histogram = 0; 446 int cat_block = 0; 348 447 349 448 /* calculate the histogram of the image */ … … 351 450 return -1; 352 451 452 if (!CalculateBlock(path, block)) 453 return -1; 454 353 455 /* determine the distance to each category */ 354 456 for (int c = 0; c < CATEGORY_SIZE; c++) … … 356 458 // determine distance 357 459 cat2dist[c] = 0.0f; 460 cat2block[c] = 0.0f; 358 461 for (int b = 0; b < BIN_COUNT*BIN_COUNT*BIN_COUNT; b++) 359 462 cat2dist[c] += fabs(histogram[b] - average[c][b]); 463 464 for (int b = 0; b < MAX_SIZE/SPREAD; b++) 465 cat2block[c] += fabs(block[b] - average_block[c][b]); 360 466 } 361 467 362 468 /* determine the winning category */ 363 for (int i = 1; i < CATEGORY_SIZE; i++) 364 if (cat2dist[i] < cat2dist[retval]) 365 retval = i; 469 for (int i = 1; i < CATEGORY_SIZE; i++) { 470 if (cat2dist[i] < cat2dist[cat_histogram]) 471 cat_histogram = i; 472 if (cat2block[i] < cat2block[cat_block]) 473 cat_block = i; 474 } 366 475 367 476 if (verbose) { 368 477 /* Dirty hack to show some more details in case of failure */ 369 if ( guess != -1 && guess != retval) {478 if (opt_histogram && guess != -1 && guess != cat_histogram) { 370 479 for (int i = 0; i < CATEGORY_SIZE; i++) { 371 printf("%s Distance to %-20s: %f %s\n", (retval == i) ? "*" : " ", 372 categories[i], cat2dist[i],(retval == i) ? "*" : ""); 373 } 374 } 480 printf("%s [histogram] distance to %-20s: %f %s\n", (cat_histogram == i) ? "*" : " ", 481 categories[i], cat2dist[i],(cat_histogram == i) ? "*" : ""); 482 } 483 } 484 if (opt_block && guess != -1 && guess != cat_block) { 485 for (int i = 0; i < CATEGORY_SIZE; i++) { 486 printf("%s [block] distance to %-20s: %f %s\n", (cat_block == i) ? "*" : " ", 487 categories[i], cat2block[i],(cat_block == i) ? "*" : ""); 488 } 489 } 490 375 491 } 376 492 377 493 /* return result */ 378 return retval; 494 if (opt_histogram) { 495 return cat_histogram; 496 } 497 else if (opt_block) { 498 return cat_block; 499 } else { 500 return -1; 501 } 379 502 } 380 503 … … 452 575 c_succes[c]++; 453 576 } else { 454 cout << "[" << catname << "] testing image " << i << " : FAIL" << endl; } 577 cout << "[" << catname << "] testing image " << i << " : FAIL" << endl; 578 DetermineCategory(path,c,opt_verbose); 579 } 455 580 } 456 581 cout << "[" << catname << "] results " << c_succes[c] << "/" << c_total[c] << endl; … … 459 584 /* Display grand total */ 460 585 cout << "=== Totals ===" << endl; 586 cout << "Clasifier used: "; 587 if (opt_histogram) 588 cout << "histogram"; 589 else if (opt_block) 590 cout << "block"; 591 cout << endl; 592 461 593 for (int c = 0; c < CATEGORY_SIZE; c++) 462 594 {
Note:
See TracChangeset
for help on using the changeset viewer.