Ignore:
Timestamp:
Apr 6, 2010, 7:16:33 AM (15 years ago)
Author:
Rick van der Zwet
Message:

New classifier block detection. Not yet optimized for blocks

Location:
liacs/MIR2010/SourceCode
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • liacs/MIR2010/SourceCode/hvdzwet.vcproj

    r95 r97  
    256256                        </File>
    257257                        <File
     258                                RelativePath=".\reference_implementation.h"
     259                                >
     260                        </File>
     261                        <File
    258262                                RelativePath="XBrowseForFolder.h"
    259263                                >
  • liacs/MIR2010/SourceCode/main.cpp

    r96 r97  
    4040float average[CATEGORY_SIZE][BIN_COUNT*BIN_COUNT*BIN_COUNT];
    4141
     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
     49float average_block[CATEGORY_SIZE][MAX_SIZE/SPREAD];
     50
     51
    4252// Some prototyping foo on functions
     53#define p_err(err_msg) printf("ERROR: %s\n", err_msg);
    4354#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
     58bool opt_verbose = false;
     59bool opt_histogram = true;
     60bool opt_block = true;
    4661
    4762bool file_exists(const char * filename)
     
    114129                cout << "3. determine winter sport" << endl;
    115130                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
    121135                cout << endl;
    122136                cout << "Please select option, or type 'q' to quit: ";
     
    126140                // start the chosen option
    127141                switch (c)
    128                 {
     142                { 
    129143                case 'q':
    130144                        return 0;
     
    158172                        break;
    159173                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;
    161182                default:
    162183                        continue;
     
    207228}
    208229
     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
     232bool 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
    209268bool CalculateDescriptors(const char *basedir)
    210269{
    211270        // the histogram that we reuse for each image
    212271        float *histogram = new float[BIN_COUNT*BIN_COUNT*BIN_COUNT];
     272        float *block = new float[MAX_SIZE/SPREAD];
    213273        // walk through all images
    214274        // Note: each of the three categories has 50 images
     
    234294                        if (!CalculateDescriptor(path, histogram))
    235295                                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
    237301                        SAFE_SPRINTF(path, sizeof(path), "%s%i.dat", catdir, i);
    238302                        if ((file = fopen(path, "wb")) == NULL)
     
    240304                        if (fwrite(histogram, sizeof(float), BIN_COUNT*BIN_COUNT*BIN_COUNT, file) != BIN_COUNT*BIN_COUNT*BIN_COUNT)
    241305                                goto failure;
     306                        if (fwrite(block, sizeof(float), MAX_SIZE/SPREAD, file) != MAX_SIZE/SPREAD)
     307                                goto failure;
    242308                        SAFE_CLOSEFILE(file);
     309
     310
    243311                }
    244312        }
    245313        // release resources
    246314        SAFE_DELETE_ARRAY(histogram);
     315        SAFE_DELETE_ARRAY(block);
    247316        return true;
    248317
     
    250319        SAFE_CLOSEFILE(file);
    251320        SAFE_DELETE_ARRAY(histogram);
     321        SAFE_DELETE_ARRAY(block);
    252322        return false;
    253323}
     
    258328        // characteristics of that category
    259329        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];
    260332        float *average = new float[BIN_COUNT*BIN_COUNT*BIN_COUNT];
    261333        // walk through all descriptors
     
    277349                        SAFE_SPRINTF(path, sizeof(path), "%s%i.dat", catdir, i);
    278350                        if (!file_exists(path)) {
     351                                p_err("File does not exists");
    279352                                continue;
    280353                        }
    281354                        cout << "[" << catname << "] processing image " << i << endl;
    282355                        // 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
    287369                        SAFE_CLOSEFILE(file);
    288370                        // add the value of each bin to the average
     
    290372                                average[b] += histogram[b];
    291373
     374                        for (int b = 0; b < MAX_SIZE/SPREAD; b++)
     375                                average_block[b] += block[b];
     376
    292377                        c_size++;
    293378                }
     
    295380                for (int b = 0; b < BIN_COUNT*BIN_COUNT*BIN_COUNT; b++)
    296381                        average[b] /= c_size;
     382               
     383                for (int b = 0; b < MAX_SIZE/SPREAD; b++)
     384                        average_block[b] /= c_size;
     385
    297386                // save the average to disk
    298387                SAFE_SPRINTF(path, sizeof(path), "%s%s.dat", catdir, "average");
     
    301390                if (fwrite(average, sizeof(float), BIN_COUNT*BIN_COUNT*BIN_COUNT, file) != BIN_COUNT*BIN_COUNT*BIN_COUNT)
    302391                        goto failure;
     392                if (fwrite(average_block, sizeof(float), MAX_SIZE/SPREAD, file) != MAX_SIZE/SPREAD)
     393                        goto failure;
     394
    303395                SAFE_CLOSEFILE(file);
    304396        }
     
    306398        SAFE_DELETE_ARRAY(histogram);
    307399        SAFE_DELETE_ARRAY(average);
     400        SAFE_DELETE_ARRAY(block);
    308401        return true;
    309402
     
    311404        SAFE_CLOSEFILE(file);
    312405        SAFE_DELETE_ARRAY(histogram);
    313         SAFE_DELETE_ARRAY(average);
     406        SAFE_DELETE_ARRAY(block);
    314407        return false;
    315408}
     
    335428                if (fread(average[c], sizeof(float), BIN_COUNT*BIN_COUNT*BIN_COUNT, file) != BIN_COUNT*BIN_COUNT*BIN_COUNT)
    336429                        return false;
     430                if (fread(average_block[c], sizeof(float), MAX_SIZE/SPREAD, file) != MAX_SIZE/SPREAD)
     431                        return false;
     432
    337433                SAFE_CLOSEFILE(file);
    338434        }
     
    340436}
    341437
    342 int DetermineCategory(const char *path, const int guess=-1) {
     438int DetermineCategory(const char *path, const int guess=-1, const bool verbose=false) {
    343439        float *histogram = new float[BIN_COUNT*BIN_COUNT*BIN_COUNT];
     440        float *block = new float[MAX_SIZE/SPREAD];
    344441        float cat2dist[CATEGORY_SIZE];
     442        float cat2block[CATEGORY_SIZE];
    345443
    346444        /* First category default best canidate */
    347         int retval = 0;
     445        int cat_histogram = 0;
     446        int cat_block = 0;
    348447
    349448        /* calculate the histogram of the image */
     
    351450                return -1;
    352451
     452        if (!CalculateBlock(path, block))
     453                return -1;
     454
    353455        /* determine the distance to each category */
    354456        for (int c = 0; c < CATEGORY_SIZE; c++)
     
    356458                // determine distance
    357459                cat2dist[c] = 0.0f;
     460                cat2block[c] = 0.0f;
    358461                for (int b = 0; b < BIN_COUNT*BIN_COUNT*BIN_COUNT; b++)
    359462                        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]);
    360466        }
    361467
    362468        /* 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        }
    366475
    367476        if (verbose) {
    368477                /* 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) {
    370479                        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
    375491        }
    376492
    377493        /* 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        }
    379502}
    380503
     
    452575                                c_succes[c]++;
    453576                        } else {
    454                                 cout << "[" << catname << "] testing image " << i << " : FAIL" << endl;                 }
     577                                cout << "[" << catname << "] testing image " << i << " : FAIL" << endl;
     578                                DetermineCategory(path,c,opt_verbose);
     579                        }
    455580                }
    456581                cout << "[" << catname << "] results " << c_succes[c] << "/" << c_total[c] << endl;
     
    459584        /* Display grand total */
    460585        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
    461593        for (int c = 0; c < CATEGORY_SIZE; c++)
    462594        {
Note: See TracChangeset for help on using the changeset viewer.