From: <st...@us...> - 2009-06-05 12:53:02
|
Revision: 3918 http://hugin.svn.sourceforge.net/hugin/?rev=3918&view=rev Author: stativ Date: 2009-06-05 12:21:00 +0000 (Fri, 05 Jun 2009) Log Message: ----------- Fixed verbosity handling. It still can't write merged files. Modified Paths: -------------- hugin/branches/gsoc2009_deghosting/src/deghosting/hugin_hdrmerge.cpp hugin/branches/gsoc2009_deghosting/src/deghosting/jbu.cpp hugin/branches/gsoc2009_deghosting/src/deghosting/jbu.h hugin/branches/gsoc2009_deghosting/src/deghosting/khan.h hugin/branches/gsoc2009_deghosting/src/deghosting/support.cpp Added Paths: ----------- hugin/branches/gsoc2009_deghosting/src/deghosting/khan.cpp Removed Paths: ------------- hugin/branches/gsoc2009_deghosting/src/deghosting/khan.tcc Modified: hugin/branches/gsoc2009_deghosting/src/deghosting/hugin_hdrmerge.cpp =================================================================== --- hugin/branches/gsoc2009_deghosting/src/deghosting/hugin_hdrmerge.cpp 2009-06-05 05:53:17 UTC (rev 3917) +++ hugin/branches/gsoc2009_deghosting/src/deghosting/hugin_hdrmerge.cpp 2009-06-05 12:21:00 UTC (rev 3918) @@ -134,36 +134,36 @@ << "Valid options are:" << std::endl << " -o prefix output file" << std::endl << " -m mode merge mode, can be one of: avg, avg_slow, khan (default), if avg, no" << std::endl - << " -i, -s, or -d options apply" << std::endl - << " -i iter number of iterations to execute (default is 1)" << std::endl + << " -i, -s, or -d options apply" << std::endl + << " -i iter number of iterations to execute (default is 1)" << std::endl << " -c Only consider pixels that are defined in all images (avg mode only)" << std::endl - << " -s file debug files to save each iteration, can be one of:" << std::endl - << " a - all debug files (can only be used alone)" << std::endl - << " w - calculated weights from each iteration" << std::endl - << " r - result image from each iteration" << std::endl - << " s - source images before processing" << std::endl - << " if verbose >= 3, all debug files are output unless specified" << std::endl - << " -a calcs apply one or more advanced caculations, can be one or more of:" << std::endl - << " b - biasing weights logarithmically" << std::endl - << " c - choose pixels with heighest weight instead of averaging" << std::endl - << " (overrides options -a b and -a d)" << endl - << " d - choose a pixel with the heighest weight instead of" << endl - << " averaging when all pixel weights are within 10% of eachother" << endl - << " h - favor a high signal to noise ratio" << std::endl - << " i - ignore alpha channel" << endl - << " n - do not use luminance images for estimating initial weights" << endl - << " (bases weights on input images itself)" << endl -/* << " m - multi-scale calculation of weights" << std::endl - << " s - favor choosing from the same image" << std::endl - << " u - use joint bilateral upscaling" << std::endl - << " ex: -d hms" << std::endl -*/ << " -e export each initial weight to <input_file_paths>_iw.<ext>" << std::endl - << " -l load a previously exported initial weight with respect " << endl - << " to the input file names" << std::endl - << " NOTE: if both -e and -l options are on, the program will " << endl - << " calculate and save the initial weights, then wait " << endl - << " until user indicates that it can continue by loading " << endl - << " the previously saved weights" << endl + << " -s file debug files to save each iteration, can be one of:" << std::endl + << " a - all debug files (can only be used alone)" << std::endl + << " w - calculated weights from each iteration" << std::endl + << " r - result image from each iteration" << std::endl + << " s - source images before processing" << std::endl + << " if verbose >= 3, all debug files are output unless specified" << std::endl + << " -a calcs apply one or more advanced caculations, can be one or more of:" << std::endl + << " b - biasing weights logarithmically" << std::endl + << " c - choose pixels with heighest weight instead of averaging" << std::endl + << " (overrides options -a b and -a d)" << endl + << " d - choose a pixel with the heighest weight instead of" << endl + << " averaging when all pixel weights are within 10% of eachother" << endl + << " h - favor a high signal to noise ratio" << std::endl + << " i - ignore alpha channel" << endl + << " n - do not use luminance images for estimating initial weights" << endl + << " (bases weights on input images itself)" << endl +/* << " m - multi-scale calculation of weights" << std::endl + << " s - favor choosing from the same image" << std::endl + << " u - use joint bilateral upscaling" << std::endl + << " ex: -d hms" << std::endl +*/ << " -e export each initial weight to <input_file_paths>_iw.<ext>" << std::endl + << " -l load a previously exported initial weight with respect " << endl + << " to the input file names" << std::endl + << " NOTE: if both -e and -l options are on, the program will " << endl + << " calculate and save the initial weights, then wait " << endl + << " until user indicates that it can continue by loading " << endl + << " the previously saved weights" << endl << " -v Verbose, print progress messages, repeat for" << std::endl << " even more verbose output" << std::endl << " -h Display help (this text)" << std::endl @@ -184,10 +184,10 @@ std::string outputFile = "merged.hdr"; std::string mode = "khan"; bool onlyCompleteOverlap = false; - int num_iters = 1; - uint8_t save = 0; - uint16_t adv = 0; - uint8_t ui = 0; + int num_iters = 1; + uint8_t save = 0; + uint16_t adv = 0; + uint8_t ui = 0; string basename; while ((c = getopt (argc, argv, optstring)) != -1) { @@ -198,129 +198,129 @@ case 'c': onlyCompleteOverlap = true; break; - case 'i': - num_iters = atoi(optarg); - break; - case 'e': - ui += khanAdvModes::UI_EXPORT_INIT_WEIGHTS; - if(g_verbose > 0) - cout << "Exporting initial weights" << endl; - break; - case 'l': - ui += khanAdvModes::UI_IMPORT_INIT_WEIGHTS; - if(g_verbose > 0) - cout << "Importing initial weights" << endl; - break; - case 's': - for(char *c = optarg; *c; c++) { - switch(*c) { - case 'w': - save += khanAdvModes::SAVE_WEIGHTS; - if(g_verbose > 0) - cout << "Saving weights from each iteration" << endl; - break; - case 'r': - save += khanAdvModes::SAVE_RESULTS; - if(g_verbose > 0) - cout << "Saving results from each iteration" << endl; - break; - case 's': - save += khanAdvModes::SAVE_SOURCES; - if(g_verbose > 0) - cout << "Saving sources after loading" << endl; - break; - case 'a': - save = khanAdvModes::SAVE_ALL; - if(g_verbose > 0) - cout << "Saving all debug outputs" << endl; - break; - default: - cerr << "Invalid argument for option -s: " << *c << std::endl; - usage(argv[0]); - return 1; - } - } - break; - case 'a': - for(char *c = optarg; *c; c++) { - switch(*c) { - case 'b': - if(adv & khanAdvModes::ADV_UNAVG) { - cerr << "Cannot use b with c in option -a" << endl; - usage(argv[0]); - return 1; - } - adv += khanAdvModes::ADV_BIAS; - if(g_verbose > 0) - cout << "Applying: logarithmic bias of weights" << endl; - break; - case 'c': - if(adv & khanAdvModes::ADV_BIAS) { - cout << "Warning: overriding log bias of weights " - << "width option -a c" << endl; - adv -= khanAdvModes::ADV_BIAS; - } - if(adv & khanAdvModes::ADV_UNAVG2) { - cout << "Warning: overriding option -a d with option " - << "-a c" << endl; - adv-= khanAdvModes::ADV_UNAVG2; - } - adv += khanAdvModes::ADV_UNAVG; - if(g_verbose > 0) { - cout << "Applying: choose pixel with largest weight" << endl; - } - break; - case 'd': - if(adv & khanAdvModes::ADV_UNAVG) { - cout << "Warning: overriding option -a d with option " - << "-a c" << endl; - } - else { - adv+= khanAdvModes::ADV_UNAVG2; - cout << "Applying: choosing pixel with the largest weight " - << "when weights are similar" << endl; - } - break; - case 'h': - adv += khanAdvModes::ADV_SNR; - if(g_verbose > 0) - cout << "Applying: favoring high signal to noise ratio" - << endl; - break; - case 'i': - adv += khanAdvModes::ADV_ALPHA; - if(g_verbose > 0) - cout << "Applying: ignore alpha channel" << endl; - break; - case 'n': - adv += khanAdvModes::ADV_NOLUM; - if(g_verbose > 0) - cout << "Using input images to estimate initial weights instead of luminance" << endl; - break; -/* case 'm': - adv += ADV_MULTI; - if(g_verbose > 0) - cout << "Applying: multi-scaling" << endl; - break; - case 's': - adv += ADV_SAME; - if(g_verbose > 0) - cout << "Applying: favor choosing from the same image" << endl; - break; - case 'u': - adv += ADV_JBU; - if(g_verbose > 0) { - cout << "Applying: use joint bilateral upsampling" - << endl; - } - break; -*/ default: - cerr << "Invalid argument for option -a: " << *c << std::endl; - usage(argv[0]); - return 1; - } - } - break; + case 'i': + num_iters = atoi(optarg); + break; + case 'e': + ui += khanAdvModes::UI_EXPORT_INIT_WEIGHTS; + if(g_verbose > 0) + cout << "Exporting initial weights" << endl; + break; + case 'l': + ui += khanAdvModes::UI_IMPORT_INIT_WEIGHTS; + if(g_verbose > 0) + cout << "Importing initial weights" << endl; + break; + case 's': + for(char *c = optarg; *c; c++) { + switch(*c) { + case 'w': + save += khanAdvModes::SAVE_WEIGHTS; + if(g_verbose > 0) + cout << "Saving weights from each iteration" << endl; + break; + case 'r': + save += khanAdvModes::SAVE_RESULTS; + if(g_verbose > 0) + cout << "Saving results from each iteration" << endl; + break; + case 's': + save += khanAdvModes::SAVE_SOURCES; + if(g_verbose > 0) + cout << "Saving sources after loading" << endl; + break; + case 'a': + save = khanAdvModes::SAVE_ALL; + if(g_verbose > 0) + cout << "Saving all debug outputs" << endl; + break; + default: + cerr << "Invalid argument for option -s: " << *c << std::endl; + usage(argv[0]); + return 1; + } + } + break; + case 'a': + for(char *c = optarg; *c; c++) { + switch(*c) { + case 'b': + if(adv & khanAdvModes::ADV_UNAVG) { + cerr << "Cannot use b with c in option -a" << endl; + usage(argv[0]); + return 1; + } + adv += khanAdvModes::ADV_BIAS; + if(g_verbose > 0) + cout << "Applying: logarithmic bias of weights" << endl; + break; + case 'c': + if(adv & khanAdvModes::ADV_BIAS) { + cout << "Warning: overriding log bias of weights " + << "width option -a c" << endl; + adv -= khanAdvModes::ADV_BIAS; + } + if(adv & khanAdvModes::ADV_UNAVG2) { + cout << "Warning: overriding option -a d with option " + << "-a c" << endl; + adv-= khanAdvModes::ADV_UNAVG2; + } + adv += khanAdvModes::ADV_UNAVG; + if(g_verbose > 0) { + cout << "Applying: choose pixel with largest weight" << endl; + } + break; + case 'd': + if(adv & khanAdvModes::ADV_UNAVG) { + cout << "Warning: overriding option -a d with option " + << "-a c" << endl; + } + else { + adv+= khanAdvModes::ADV_UNAVG2; + cout << "Applying: choosing pixel with the largest weight " + << "when weights are similar" << endl; + } + break; + case 'h': + adv += khanAdvModes::ADV_SNR; + if(g_verbose > 0) + cout << "Applying: favoring high signal to noise ratio" + << endl; + break; + case 'i': + adv += khanAdvModes::ADV_ALPHA; + if(g_verbose > 0) + cout << "Applying: ignore alpha channel" << endl; + break; + case 'n': + adv += khanAdvModes::ADV_NOLUM; + if(g_verbose > 0) + cout << "Using input images to estimate initial weights instead of luminance" << endl; + break; +/* case 'm': + adv += ADV_MULTI; + if(g_verbose > 0) + cout << "Applying: multi-scaling" << endl; + break; + case 's': + adv += ADV_SAME; + if(g_verbose > 0) + cout << "Applying: favor choosing from the same image" << endl; + break; + case 'u': + adv += ADV_JBU; + if(g_verbose > 0) { + cout << "Applying: use joint bilateral upsampling" + << endl; + } + break; +*/ default: + cerr << "Invalid argument for option -a: " << *c << std::endl; + usage(argv[0]); + return 1; + } + } + break; case 'o': outputFile = optarg; break; @@ -335,12 +335,12 @@ usage(argv[0]); return 1; } - }//end while + }//end while - cout << endl; + cout << endl; - if(g_verbose > 2) - save = khanAdvModes::SAVE_ALL; + /*if(g_verbose > 2) + save = khanAdvModes::SAVE_ALL;*/ unsigned nFiles = argc - optind; if (nFiles == 0) { @@ -392,8 +392,9 @@ if (g_verbose > 0) { cout << "Running Khan algorithm" << std::endl; } + // ALREADY CHANGED - khan<weightMexicanHatFunctor<int,float> > deghoster(inputFiles, num_iters, adv, save, ui); + khan<weightMexicanHatFunctor<int,float> > deghoster(inputFiles, num_iters, adv, save, ui, g_verbose); const vector<FImagePtr> weights = deghoster.createWeightMasks(); // save output file @@ -403,9 +404,10 @@ weightedAverageOfImageFiles(inputFiles, deghoster.getWidth(), deghoster.getHeight(), weights, &output); - //ImageExportInfo exinfo(outputFile.c_str()); - //exinfo.setPixelType("FLOAT"); - //exportImageAlpha(srcImageRange(output), srcImage(mask), exinfo); + ImageExportInfo exinfo(outputFile.c_str()); + exinfo.setPixelType("FLOAT"); + BImage mask(output.width(), output.height(), 255); + exportImageAlpha(srcImageRange(output), srcImage(mask), exinfo); } else { std::cerr << "Unknown merge mode, see help for a list of possible modes" << std::endl; return 1; Modified: hugin/branches/gsoc2009_deghosting/src/deghosting/jbu.cpp =================================================================== --- hugin/branches/gsoc2009_deghosting/src/deghosting/jbu.cpp 2009-06-05 05:53:17 UTC (rev 3917) +++ hugin/branches/gsoc2009_deghosting/src/deghosting/jbu.cpp 2009-06-05 12:21:00 UTC (rev 3918) @@ -43,18 +43,18 @@ * destImgs is ptr to an empty vector to be filled in */ void jointBilateralUpsampling(vector<FImagePtr> *sources, - vector<FImagePtr> *refs, - vector<FImagePtr> *destImgs, int num_neighbors) + vector<FImagePtr> *refs, + vector<FImagePtr> *destImgs, int num_neighbors) { - int num_layers = sources->size(); - bool destEmpty = destImgs->size() == 0; - for(int i = 0; i < num_layers; i++) { - FImagePtr tmp = jbuImage(sources->at(i), refs->at(i), num_neighbors); - if(!destEmpty) - destImgs->at(i) = tmp; - else - destImgs->push_back(tmp); - } + int num_layers = sources->size(); + bool destEmpty = destImgs->size() == 0; + for(int i = 0; i < num_layers; i++) { + FImagePtr tmp = jbuImage(sources->at(i), refs->at(i), num_neighbors); + if(!destEmpty) + destImgs->at(i) = tmp; + else + destImgs->push_back(tmp); + } } @@ -62,139 +62,139 @@ * creates the resulting FImagePtr and returns it */ FImagePtr jbuImage(FImagePtr source, FImagePtr refIm, int num_neighbors) -{ - int width = refIm->width(); - int height = refIm->height(); - int s_width = source->width(); - int s_height = source->height(); - float scale = s_width / width; - - FImagePtr dest = FImagePtr(new FImage(width, height)); - float sigma = 0.5; - int mu = 0; - - for(int y = 0; y < height; y++) { - float *refPixLoc = (float *)(refIm->data()) + y * width; - - if(g_verbose > 2) - cout << "y: " << y << "\n" - << "\trefPixLoc: " << hex << refPixLoc << endl; - - for(int x = 0; x < width; x++) { - float refPix = *(refPixLoc + x); - - float total_val = 0; - float normalizing_factor = 0; - - //prevent black areas fro all rgausses being 0 - float norgauss = 0; - float norgauss_normalize = 0; - - //find coords in source - float o_x = x * scale; - float o_y = y * scale; - - if(g_verbose > 2) - cout << "x: " << x << "\n" - << "\trefPixLoc+x: " << hex << refPixLoc + x << "\n" - << "\to_x: " << o_x << "\n" - << "\to_y: " << o_y << endl; - - //for each neighbor for the source - for(int j = -num_neighbors; j <= num_neighbors; j++) { - int r_y = (int)round(o_y + j); - r_y = (r_y > 0 ? (r_y < s_height ? r_y : s_height-1) : 0); - float *srcPixLoc = (float *)source->data() + r_y * s_width; - //corresponding reference pixel - float *neighborPixLoc = (float *)refIm->data() + - (int) (r_y * scale * width); - - if(g_verbose > 3) - cout << "\tj: " << j << "\n" - << "\t\tr_y: " << r_y << "\n" - << "\t\tsrcPixLoc: " << hex << srcPixLoc << "\n" - << "\t\tneighborPixLoc: " << hex << neighborPixLoc << endl; - - for(int i = -num_neighbors; i <= num_neighbors; i++) { - //find coords in source - int r_x = (int)round(o_x + i); - r_x = (r_x > 0 ? (r_x < s_width ? r_x : s_width-1) : 0); - float srcPix = *(srcPixLoc + r_x); - //in ref img - neighborPixLoc += int(r_x * scale); - float neighborPix = *neighborPixLoc; - - if(g_verbose > 3) - cout << "\ti: " << i << "\n" - << "\t\tr_x: " << r_x << "\n" - << "\t\tsrcPixLoc+r_x: " << hex << srcPixLoc + r_x << "\n" - << "\t\tsrcPix: " << srcPix << "\n" - << "\t\tneighborPixLoc: " << hex << neighborPixLoc << "\n" - << " \t\tneighborPix: " << neighborPix << endl; - - //gauss dist to center - float sgauss = simpleGauss(dist(o_x, o_y, r_x, r_y), - sigma, mu); - //gauss radiance diff to center in ref - float rgauss = simpleGauss(abs(refPix - neighborPix), - sigma, mu); - - //multiply gausses by value in source and add to total val - norgauss = srcPix * sgauss; - norgauss_normalize += sgauss; - float totalgauss = sgauss * rgauss; - normalizing_factor += totalgauss; - total_val += srcPix * totalgauss; - - if(g_verbose > 3) - cout << "\t\tsgauss: " << sgauss << "\n" - << "\t\trgauss: " << rgauss << "\n" - << "\t\ttotalgauss+srcPix: " << totalgauss + - srcPix << endl; - - } //end for i - }//end for j - - //normalize and store - - if(g_verbose > 2) - cout << "\tnormalizing_factor: " << normalizing_factor << "\n" - << "\ttotal_val(before): " << total_val << endl; +{ + int width = refIm->width(); + int height = refIm->height(); + int s_width = source->width(); + int s_height = source->height(); + float scale = s_width / width; + + FImagePtr dest = FImagePtr(new FImage(width, height)); + float sigma = 0.5; + int mu = 0; + + for(int y = 0; y < height; y++) { + float *refPixLoc = (float *)(refIm->data()) + y * width; + + if(g_verbose > 2) + cout << "y: " << y << "\n" + << "\trefPixLoc: " << hex << refPixLoc << endl; + + for(int x = 0; x < width; x++) { + float refPix = *(refPixLoc + x); + + float total_val = 0; + float normalizing_factor = 0; + + //prevent black areas fro all rgausses being 0 + float norgauss = 0; + float norgauss_normalize = 0; + + //find coords in source + float o_x = x * scale; + float o_y = y * scale; + + if(g_verbose > 2) + cout << "x: " << x << "\n" + << "\trefPixLoc+x: " << hex << refPixLoc + x << "\n" + << "\to_x: " << o_x << "\n" + << "\to_y: " << o_y << endl; + + //for each neighbor for the source + for(int j = -num_neighbors; j <= num_neighbors; j++) { + int r_y = (int)round(o_y + j); + r_y = (r_y > 0 ? (r_y < s_height ? r_y : s_height-1) : 0); + float *srcPixLoc = (float *)source->data() + r_y * s_width; + //corresponding reference pixel + float *neighborPixLoc = (float *)refIm->data() + + (int) (r_y * scale * width); + + if(g_verbose > 3) + cout << "\tj: " << j << "\n" + << "\t\tr_y: " << r_y << "\n" + << "\t\tsrcPixLoc: " << hex << srcPixLoc << "\n" + << "\t\tneighborPixLoc: " << hex << neighborPixLoc << endl; + + for(int i = -num_neighbors; i <= num_neighbors; i++) { + //find coords in source + int r_x = (int)round(o_x + i); + r_x = (r_x > 0 ? (r_x < s_width ? r_x : s_width-1) : 0); + float srcPix = *(srcPixLoc + r_x); + //in ref img + neighborPixLoc += int(r_x * scale); + float neighborPix = *neighborPixLoc; + + if(g_verbose > 3) + cout << "\ti: " << i << "\n" + << "\t\tr_x: " << r_x << "\n" + << "\t\tsrcPixLoc+r_x: " << hex << srcPixLoc + r_x << "\n" + << "\t\tsrcPix: " << srcPix << "\n" + << "\t\tneighborPixLoc: " << hex << neighborPixLoc << "\n" + << " \t\tneighborPix: " << neighborPix << endl; + + //gauss dist to center + float sgauss = simpleGauss(dist(o_x, o_y, r_x, r_y), + sigma, mu); + //gauss radiance diff to center in ref + float rgauss = simpleGauss(abs(refPix - neighborPix), + sigma, mu); + + //multiply gausses by value in source and add to total val + norgauss = srcPix * sgauss; + norgauss_normalize += sgauss; + float totalgauss = sgauss * rgauss; + normalizing_factor += totalgauss; + total_val += srcPix * totalgauss; + + if(g_verbose > 3) + cout << "\t\tsgauss: " << sgauss << "\n" + << "\t\trgauss: " << rgauss << "\n" + << "\t\ttotalgauss+srcPix: " << totalgauss + + srcPix << endl; + + } //end for i + }//end for j + + //normalize and store + + if(g_verbose > 2) + cout << "\tnormalizing_factor: " << normalizing_factor << "\n" + << "\ttotal_val(before): " << total_val << endl; - if(total_val) { - total_val /= normalizing_factor; - *((float *)dest->data() + y * width + x) = total_val; - } - else { - total_val = norgauss/norgauss_normalize; - } - - if(g_verbose > 3) - cout << "\ttotal_val(after): " << total_val << "\n" - << "stored in: " << hex << dest->data() + - y * width + x << endl; - }//end for x - }//end for y - - return dest; + if(total_val) { + total_val /= normalizing_factor; + *((float *)dest->data() + y * width + x) = total_val; + } + else { + total_val = norgauss/norgauss_normalize; + } + + if(g_verbose > 3) + cout << "\ttotal_val(after): " << total_val << "\n" + << "stored in: " << hex << dest->data() + + y * width + x << endl; + }//end for x + }//end for y + + return dest; } /** given 2 floating point pixel locations, computes the distance */ float dist(float x1, float y1, float x2, float y2) { - return sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2)); + return sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2)); } /** gaussian applied to a single variable */ float simpleGauss(float x, float sigma, float mu) { - if(sigma == 0) { - cerr << "simpleGauss: sigma must be non-zero" << endl; - exit(1); - } - float pi = 3.1415926; - float x_p = x - mu; - float exponent = std::exp(x_p * x_p / (-2 * sigma * sigma)); - exponent /= sqrt(2 * pi) * sigma; - return exponent; + if(sigma == 0) { + cerr << "simpleGauss: sigma must be non-zero" << endl; + exit(1); + } + float pi = 3.1415926; + float x_p = x - mu; + float exponent = std::exp(x_p * x_p / (-2 * sigma * sigma)); + exponent /= sqrt(2 * pi) * sigma; + return exponent; } Modified: hugin/branches/gsoc2009_deghosting/src/deghosting/jbu.h =================================================================== --- hugin/branches/gsoc2009_deghosting/src/deghosting/jbu.h 2009-06-05 05:53:17 UTC (rev 3917) +++ hugin/branches/gsoc2009_deghosting/src/deghosting/jbu.h 2009-06-05 12:21:00 UTC (rev 3918) @@ -42,9 +42,9 @@ /** upsamples multiple images given vector to store results in */ void jointBilateralUpsampling(std::vector<FImagePtr> *sources, - std::vector<FImagePtr> *refs, - std::vector<FImagePtr> *destImgs, - int num_neighbors); + std::vector<FImagePtr> *refs, + std::vector<FImagePtr> *destImgs, + int num_neighbors); /** upsamples a single image and returns the FImagePtr to the result */ FImagePtr jbuImage(FImagePtr source, FImagePtr refIm, int num_neighbors); Copied: hugin/branches/gsoc2009_deghosting/src/deghosting/khan.cpp (from rev 3912, hugin/branches/gsoc2009_deghosting/src/deghosting/khan.tcc) =================================================================== --- hugin/branches/gsoc2009_deghosting/src/deghosting/khan.cpp (rev 0) +++ hugin/branches/gsoc2009_deghosting/src/deghosting/khan.cpp 2009-06-05 12:21:00 UTC (rev 3918) @@ -0,0 +1,866 @@ +// -*- c-basic-offset: 4 -*- + +/** @file khan.cpp + * + * @brief Implementation of the khan deghosting algorithm + * + * @author Jing Jin <ji...@gm...> + * ported to the current interface by Lukas Jirkovsky + * + * $Id: khan.cpp 3626 2009-02-04 08:50:47Z stativ $ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <hugin_config.h> +#include <fstream> +#include <sstream> +#include <cmath> +#include <algorithm> + +#include <boost/shared_ptr.hpp> + +#include <hugin_utils/utils.h> + +// include vigra image processing library +#include <vigra/error.hxx> +#include <vigra/functorexpression.hxx> +#include <vigra/transformimage.hxx> +#include <vigra/combineimages.hxx> +#include <vigra/resizeimage.hxx> + +#include <vigra_ext/impexalpha.hxx> +#include <vigra_ext/utils.h> + +#include "khan.h" +#include "support.h" + +#ifdef _MSC_VER +#define snprintf _snprintf +#endif + +#define ENABLE_SAME 0 /*-a s option currently doesn't work */ +#define ENABLE_SCALING 0 /*-a m and u options currently don't work */ + +namespace deghosting { + +using namespace std; +using namespace hugin_utils; +using namespace vigra; +using namespace vigra::functor; +using vigra::NumericTraits; + +template <class T> +khan<T>::khan(vector<string>& setInputFiles, int setIter, uint16_t setFlags, uint8_t setSave, uint8_t setUI, int setVerbosity) + :inputFiles(setInputFiles),iterations(setIter),adv_mode(setFlags),save_mode(setSave),ui_mode(setUI),verbosity(setVerbosity) +{ + ; +} + +template <class T> +khan<T>::~khan() { + ; +} + +/** favor high SNR function + * f(x) = 1 - (x-220/255)^4 +*/ +template <class T> +float khan<T>::favorHighSNR(unsigned char x) +{ + double t = x/255 - 0.8627; + t *= t; // ^2 + t *= t; // ^4 + t *= t; // ^8 + return 1.0 - x; +} + +template <class T> +vector<FImagePtr> khan<T>::createWeightMasks() +{ + ////////////////////////////////////////////////////////////////////////// + // 1. SETUP. load and prepare images + + // log grayscale images + std::vector<FImagePtr> grayImages; + + // transparency images + vector<BImagePtr> alpha_images; + + // initial weights (maybe 8 bit would be enough for them?) + std::vector<FImagePtr> imgWeights; + + //file infos for images + vector<ImageImportInfo> exrInfo; + vector<ImageImportInfo> grayInfo; + + //load images and prepare initial weights + for (unsigned i = 0; i < inputFiles.size(); i++) { + + + if (verbosity > 0) { + std::cout << "Loading and preparing " << inputFiles[i] << std::endl; + } + + // load image from disk + vigra::ImageImportInfo info(inputFiles[i].c_str()); + + if(verbosity >1) + cout << "Loading source image: " << inputFiles[i].c_str() << endl; + exrInfo.push_back(info); + BImagePtr origGray(new BImage(info.size())); + FRGBImage img(info.size()); + FImagePtr gray(new FImage(info.size())); + + // load image + vigra::importImageAlpha(info, vigra::destImage(img), + destImage(*origGray)); + + // convert image to grayscale (and take logarithm) + vigra::RGBToGrayAccessor<ImageType::value_type> color2gray; + transformImage(srcImageRange(img, color2gray), + destImage(*gray), + log(Arg1()+Param(1.f))); + + // store for later use + grayImages.push_back(gray); + if(!(adv_mode & khanAdvModes::ADV_ALPHA)) + alpha_images.push_back(origGray); + + // for debugging purposes, save floating point tiff files + if (save_mode & khanAdvModes::SAVE_SOURCES) { + char tmpfn[100]; + snprintf(tmpfn, 99, "debug_init_gray_%d.tiff", i); + ImageExportInfo exGray(tmpfn); + exportImage(srcImageRange(*gray), exGray.setPixelType("UINT8")); + if(!(adv_mode & khanAdvModes::ADV_ALPHA)) { + snprintf(tmpfn, 99, "debug_init_alpha_%d.tiff", i); + exGray = ImageExportInfo(tmpfn); + exportImage(srcImageRange(*origGray), exGray.setPixelType("UINT8")); + } + } + + //if calculating weights from scratch + if(!(ui_mode & khanAdvModes::UI_IMPORT_INIT_WEIGHTS) || + (ui_mode & khanAdvModes::UI_EXPORT_INIT_WEIGHTS)) { + //load image + BImagePtr origGray(new BImage(info.size())); + // if weights should be based on input image instead of luminance image + if (adv_mode & khanAdvModes::ADV_NOLUM) { + vigra::copyImage(srcImageRange(img,color2gray), destImage(*origGray)); + } + else { // base weights on luminance image + std::string grayFile = hugin_utils::stripExtension(inputFiles[i]) + "_gray.pgm"; + + if(verbosity > 1) + cout << "Loading luminance image: " << grayFile << endl; + + vigra::ImageImportInfo infog(grayFile.c_str()); + grayInfo.push_back(infog); + + vigra::importImage(infog, destImage(*origGray)); + } + FImagePtr weight(new FImage(info.size())); + + // calculate initial weights, using mexican hat function + transformImage(srcImageRange(*origGray), + destImage(*weight), + weightFunctor); + + if(adv_mode & khanAdvModes::ADV_SNR) { + if(verbosity > 1) + cout << "favoring high snr..." << endl; + + FImagePtr snrWeight(new FImage(info.size())); + transformImage(srcImageRange(*origGray), destImage(*snrWeight), + &khan<T>::favorHighSNR); + + //weight(x) = weightMexicanHat(x) * favorHighSNR(x) + combineTwoImages(srcImageRange(*weight), srcImage(*snrWeight), + destImage(*weight), Arg1() * Arg2()); + } + + imgWeights.push_back(weight); + + // for debugging purposes, save floating point tiff files + if (save_mode & khanAdvModes::SAVE_WEIGHTS) { + char tmpfn[100]; + snprintf(tmpfn, 99, "debug_init_weights_%d.tiff", i); + ImageExportInfo exWeights(tmpfn); + exportImage(srcImageRange(*weight), exWeights.setPixelType("UINT8")); + } + } + } + + if(ui_mode & khanAdvModes::UI_EXPORT_INIT_WEIGHTS) { + if(!saveImages(inputFiles, "iw", imgWeights)) + cerr << "Cannot export initial weights" << endl; + else if(verbosity > 0) + cout << "Saved initial weights in source folder" << endl; + } + + if(ui_mode & khanAdvModes::UI_IMPORT_INIT_WEIGHTS) { + string s; + if(ui_mode & khanAdvModes::UI_EXPORT_INIT_WEIGHTS) { //just exported weights + while(true) { + cout << "Enter 'c' to load initial weights from source folder" << endl + << "Enter 'q' to cancel loading initial weights: "; + cin >> s; + + if(s[0] == 'c' || s[0] == 'q') + break; + } + } + + if(!s.length() || s[0] == 'c') { + vector<FImagePtr> tmpWeights; + if(!deghosting::loadImages(inputFiles, "iw", &tmpWeights)) { + cerr << "Cannot import initial weights" << endl; + /*if(!imgWeights.size()) + return false;*/ + } + else { + imgWeights = tmpWeights; + if(verbosity > 0) + cout << "Loaded initial weights from source folder" << endl; + } + } + } + + ////////////////////////////////////////////////////////////////////////// + // 2. Estimation of weights + + // images used to compute weight + vector<vector<float> > source_images; + // final weights + vector<vector<float> > weights; + // alpha mask + vector<vector<char> > alpha; + + //pos+size info for input images + vector<Rect2D> img_bounds; + + //size of final composite + int width, height; + + if(verbosity > 1) + cout << "Remappin input images" << endl; + + if((width = Fimages2Vectors(exrInfo, + alpha_images, grayImages, &source_images, &img_bounds)) == -1) { + + cerr << "Error converting images to vectors" << endl; + abort(); + } + + if(!((adv_mode & khanAdvModes::ADV_JBU) || (adv_mode & khanAdvModes::ADV_MULTI))) { + if(verbosity > 1) + cout << "Clearing gray input images" << endl; + grayImages.clear(); + } + height = source_images.size()/width; + + + if(Fimages2Vectors(exrInfo, alpha_images, imgWeights, &weights) == -1) { + cerr << "Error converting images to vectors" << endl; + cerr << "Perhaps *_gray.pgm files missing from command line?" << endl; + abort(); + } + + if(verbosity > 3) { //check consistency + cout << "checking image and weight vectors for consistent size" <<endl; + assert(source_images.size() == weights.size()); + for(unsigned i = 0; i < source_images.size(); i++) + assert(source_images.at(i).size() == weights.at(i).size()); + } + + if(!((adv_mode & khanAdvModes::ADV_JBU) || (adv_mode & khanAdvModes::ADV_MULTI))) { + if(verbosity > 1) + cout << "Clearing initial weight images" << endl; + imgWeights.clear(); + } + + if (verbosity > 0) { + std::cout << "deghosting (Khan algorithm) " << std::endl; + } + + int bias = 5; //hat function coefficient to make "wrong" pixels less weighted + //min value 1 + int rad_neighbors = 1; +#if ENABLE_SCALING + int jbu_neighbors = 2; +#endif + vector<vector<float> > init_weights(weights); + + if(verbosity > 0) + std::cout << "deghosting..." << std::endl; + + //variables used for multi-scaling + int proportion = 1; + int nw, nh; + vector <FImagePtr> smallGrayImages; + vector <FImagePtr> smallInitWeights; + vector<FImagePtr> smallWeights; + vector<BImagePtr> smallAlphaImages; + + //for each iteration + for(int iter = 0; iter < iterations; iter++) { + + if(verbosity > 0) + std::cout << "\n\niteration " << iter << endl; + + if(adv_mode & khanAdvModes::ADV_JBU || adv_mode & khanAdvModes::ADV_MULTI) { + proportion = 1 << ((iterations - iter)/2); + nw = width / proportion; + nh = height / proportion; + } + + try { + #if ENABLE_SCALING + //small image + if((proportion > 1)) { + //diff than last size, need to resize + + if(!smallGrayImages.size() || + smallGrayImages[0]->width() != + img_bounds[0].width() / proportion) { + if(verbosity > 1) + std::cout << "resizing to 1/" << proportion << " size" << endl; + + //don't use jbu if smaller + bool smaller = !smallGrayImages.size() || + (smallGrayImages[0]->width() > + img_bounds[0].width() / proportion); + + weights.clear(); + source_images.clear(); + init_weights.clear(); + smallWeights.clear(); + + if(smaller) { //1st time, need to initialize + smallGrayImages.resize(img_bounds.size()); + smallInitWeights.resize(img_bounds.size()); + smallAlphaImages.resize(img_bounds.size()); + Fvectors2Images(img_bounds, alpha_images, weights, width, + &smallWeights); + } + else { + Fvectors2Images(img_bounds, smallAlphaImages, weights, + width * (proportion >> 1), &smallWeights); + // ^-- width of last iter + } + + assert(smallWeights.size() == img_bounds.size()); + + for(unsigned i = 0; i < smallWeights.size(); i++) { + int w = img_bounds.at(i).width(); + int h = img_bounds.at(i).height(); + + FImagePtr smallGray(new FImage(w, h)); + FImagePtr newInitWeight(new FImage(w, h)); + BImagePtr smallAlpha(new BImage(w, h)); + //resize input img + resizeImageLinearInterpolation( + srcImageRange(*(grayImages.at(i))), + destImageRange(*smallGray)); + smallGrayImages.at(i) = smallGray; + + //resize init_weights + resizeImageLinearInterpolation( + srcImageRange(*(imgWeights.at(i))), + destImageRange(*newInitWeight)); + smallInitWeights.at(i) = newInitWeight; + + //resize alpha images + if(!(adv_mode & ADV_ALPHA)) { + resizeImageLinearInterpolation( + srcImageRange(*(alpha_images.at(i))), + destImageRange(*smallAlpha)); + smallAlphaImages.at(i) = smallAlpha; + } + + //resize weights + if(smaller && (adv_mode & ADV_JBU)) { + smallWeights.at(i) = jbuImage(smallWeights.at(i), + smallGray, jbu_neighbors); + } + else { + FImagePtr newWeight(new FImage(w, h)); + resizeImageLinearInterpolation( + srcImageRange(*(smallWeights.at(i))), + destImageRange(*newWeight)); + //replace old weights w/ new weights + smallWeights.at(i) = newWeight; + } + + } //end for i + + //convert everything to vectors + if(Fimages2Vectors(exrInfo, alpha_images, smallWeights, + &weights) == -1) + abort(); + if(Fimages2Vectors(exrInfo, alpha_images, smallGrayImages, + &source_images) == -1) + abort(); + if(Fimages2Vectors(exrInfo, alpha_images, smallInitWeights, + &init_weights) == -1) + abort(); + + } // end if != ns + + khanIteration(source_images, nh, nw, &weights, init_weights, + rad_neighbors, adv_mode); + } // end if proportion + else {//if just computing normal sized + if(smallWeights.size() && + smallWeights[0]->width() != img_bounds[0].width()) { //nw == width + if(verbosity > 1) { + std::cout << "resizing to 1/1" << " size" << endl; + } + + //delete cache for smaller layers to save memory + smallGrayImages.clear(); + smallInitWeights.clear(); + smallAlphaImages.clear(); + + weights.clear(); + source_images.clear(); + init_weights.clear(); + smallWeights.clear(); + Fvectors2Images(img_bounds, alpha_images, weights, width, + &smallWeights); + + for(unsigned i = 0; i < smallWeights.size(); i++) { + int w = img_bounds.at(i).width(); + int h = img_bounds.at(i).height(); + //resize weights + FImagePtr newWeight(new FImage(w, h)); + resizeImageLinearInterpolation( + srcImageRange(*(smallWeights.at(i))), + destImageRange(*newWeight)); + //replace old weights w/ new weights + smallWeights.at(i) = newWeight; + }//end for + + //convert everything to vectors + if(Fimages2Vectors(exrInfo, alpha_images, smallWeights, + &weights) == -1) + abort(); + smallWeights.clear(); + + if(Fimages2Vectors(exrInfo, alpha_images, grayImages, + &source_images) == -1) + abort(); + grayImages.clear(); + + if(Fimages2Vectors(exrInfo, alpha_images, imgWeights, + &init_weights) == -1) + abort(); + imgWeights.clear(); + }//end if + #endif + khanIteration(source_images, height, width, &weights, + init_weights, rad_neighbors, adv_mode); + #if ENABLE_SCALING + } + #endif + } + catch(std::exception &e) { + cerr << "caught exception in khanMain(1): " << e.what() << endl; + abort(); + } + + vector<FImagePtr> w; + //save files for debugging purposes + if(save_mode & khanAdvModes::SAVE_WEIGHTS) { + if(verbosity > 1) + std::cout << "saving debug weights..." << endl; + + Fvectors2Images(img_bounds, alpha_images, weights, width, &w); + + char tmpfn[100]; + for(unsigned i = 0; i < w.size(); i++) { + snprintf(tmpfn, 99, "iter%d_weight_layer%d.tiff", iter, i); + ImageExportInfo exWeight(tmpfn); + exportImage(srcImageRange(*(w.at(i))), exWeight.setPixelType("UINT8")); + } + } + if((save_mode & khanAdvModes::SAVE_RESULTS)) { + if(verbosity > 1) + std::cout << "saving debug result..." << endl; + + char tmpfn[100]; + snprintf(tmpfn, 99, "iter%d_result.exr", iter); + FRGBImage debug_out; + BImage debug_mask; + + if(!w.size()) + Fvectors2Images(img_bounds, alpha_images, weights, width, &w); + + #if ENABLE_SCALING + //need to upscale weights 1st + if(adv_mode & ADV_JBU) { + jointBilateralUpsampling(&weights, &grayImages, &w, + jbu_neighbors); + } + elseif(adv_mode & ADV_MULTI) { + for(int i = 0; i < num_layers; i++) { + FImagePtr tmpW(new FImage(width, height)); + resizeImageLinearInterpolation( + srcImageRange(*(w.at(i))), + destImageRange(*tmpW)); + tmpWeights.push_back(tmpW); + } + } + #endif + + vector<FImagePtr> w; + Fvectors2Images(img_bounds, alpha_images, weights, width, &w); + weightedAverageOfImageFiles(inputFiles, width, height, w, &debug_out, + &debug_mask); + ImageExportInfo exinfo(tmpfn); + exportImageAlpha(srcImageRange(debug_out), srcImage(debug_mask), exinfo); + } + } //end iteration loop + + #if ENABLE_SCALING + if(weights[0]->width() < grayImages[0]->width()) { + if(verbosity > 1) + cout << "performing final joint bilateral upsampling" << endl; + jointBilateralUpsampling(&weights, &grayImages, &weights, + jbu_neighbors); + } + #endif + + if(adv_mode & khanAdvModes::ADV_BIAS) { + //bias and renormalize weights + if(verbosity > 0) { + std::cout << "\nadjusting weights" << endl; + } + for(int i = 0; i < height; i++) { + int y_offset = i * width; + for(int j = 0; j < width; j++) { + int total_offset = y_offset + j; + float sum = 0; + vector<float> *tmp_weights = &(weights.at(total_offset)); + int num_layers = tmp_weights->size(); + + //cout <<"raar" << endl; + for(int layer = 0; layer < num_layers; layer++) { + float tmp = tmp_weights->at(layer); + tmp = pow(tmp, bias); + sum += tmp; + tmp_weights->at(layer) = tmp; + } + + float avg = 1/(float)num_layers; + for(int layer = 0; layer < num_layers; layer++) { + tmp_weights->at(layer) = + (sum ? tmp_weights->at(layer) / sum : avg); + } + } // end for j + } // end for i + } + else if(adv_mode & khanAdvModes::ADV_UNAVG) { + //make largest weight = 1, rest 0 + if(verbosity > 0) + std::cout << "\nadjusting weights" << endl; + + FImagePtr w; + + if(save_mode & khanAdvModes::SAVE_WEIGHTS) + w = FImagePtr(new FImage(Size2D(width, height))); + + for(int i = 0; i < height; i++) { + int y_offset = i * width; + for(int j = 0; j < width; j++) { + vector<int> max_ind; + float max = 0; //consider everything w/in 1% of max as max + int total_offset = y_offset + j; + vector<float> *tmpWeights = &(weights.at(total_offset)); + int num_layers = tmpWeights->size(); + + for(int layer = 0; layer < num_layers; layer++) { + float tmp = tmpWeights->at(layer); + if(tmp > max + max * 0.01) { + //make prev max 0 + while(!max_ind.empty()) { + tmpWeights->at(layer) = 0; + max_ind.pop_back(); + } + //make curr 1 + tmpWeights->at(layer) = 1; + + max = tmp; + max_ind.push_back(layer); + } + else if(tmp > max - max * 0.01) { + max_ind.push_back(layer); + } + else { //make curr 0 + tmpWeights->at(layer) = 0; + } + }//end for layer + + if((save_mode & khanAdvModes::SAVE_WEIGHTS) && max_ind.size() == 1) { + *(float *)(w->data() + total_offset) = + (max_ind[0] + 1) / (float)num_layers; + } + } //end for j + } // end for i + + if(save_mode & khanAdvModes::SAVE_WEIGHTS) { //save labels + if(verbosity > 1) + cout << "saving weight labels..." << endl; + + ImageExportInfo exWeight("weight_labels.tiff"); + exportImage(srcImageRange(*w), exWeight.setPixelType("UINT8")); + } + } + + // apply weights and store result in output image + vector<FImagePtr> w; + Fvectors2Images(img_bounds, alpha_images, weights, width, &w); + weights.clear(); + alpha_images.clear(); + khan<T>::width = width; + khan<T>::height = height; + return w; + //return true; +}//end khanMain + +/** writes the new weights in the given weights object pointer + */ +template <class T> +void khan<T>::khanIteration(const std::vector<std::vector<float> > &source_images, + const int height, const int width, + std::vector<std::vector<float> > *weights, + const std::vector<std::vector<float> > &init_weights, + const int rad_neighbors, const unsigned int adv_mode) +{ + try { + if(verbosity > 0) + std::cout << "processing..." << endl; + + if(verbosity > 3) + cout << "copying prev weights" << endl; + + vector<vector<float> > old_weights = *weights; + + //for each row + for(int row = 0; row < height; row++) { + int row_offset = row * width; + + if(verbosity ==2 || verbosity == 3) { + if(row % 100) { + if(verbosity == 3 && !(row % 10)) + cout << "." << flush; + } + else + cout << "\nrow " << row << " to " << (row +100) << flush; + } + + //for each column + for (int col = 0; col < width; col++) { + int total_offset = col + row_offset; + + if(verbosity > 3) + cout << "(x, y) = (" << col << ", " << row << ")" << endl; + + //get descriptors + vector<int> neighbor_offsets; + khanNeighbors(&neighbor_offsets, col, row, width, height, rad_neighbors); + + float total_sum = 0; + std::vector<float> raw_weights; + float max_weight = 0; + float min_weight = FLT_MAX; + + int num_layers = old_weights.at(total_offset).size(); + assert((unsigned)num_layers == source_images.at(total_offset).size()); + //for each layer + for(int layer = 0; layer < num_layers; layer++) { + if(verbosity > 3) { + cout << "layer " << layer << endl; + } + + //initialize sum to 0 + float sum_weight = 0; + float sum_prev_weight = 0; + //get center pixel + float curr_px = source_images.at(total_offset).at(layer); + + if(verbosity >3) + cout << "\tpixel = " << curr_px << endl; + //for each neighbor location + for(unsigned n = 0; n < neighbor_offsets.size(); n++) { + int n_offset = neighbor_offsets.at(n); + vector<float> *px_neighbor_w = &(old_weights.at(n_offset)); + const vector<float> *px_neighbor_v = + &(source_images.at(n_offset)); + unsigned num_l = px_neighbor_w->size(); + assert(num_l == px_neighbor_v->size()); + float tmp_weight = 0; + float tmp_prev_weight = 0; + + if(verbosity > 3) { + cout << "\t\tneighbor " << n << endl + << "\t\t\toffset: " << n_offset << endl; + } + + //number of layers at this neighbor location + for(unsigned l = 0; l < num_l; l++) { + + if(verbosity > 3) { + cout << "\t\t\tlayer " << l << endl + << "\t\t\tvalue = " << px_neighbor_v->at(l) << endl + << " \t\t\tweight = " << px_neighbor_w->at(l) + << endl; + } + + //diff against center + float val = curr_px - px_neighbor_v->at(l); + + //gaussian + val = std::exp(val * val * -0.5) / sqrt(2 * 3.14159); + //multiply by prev weight + val *= px_neighbor_w->at(l); + + if(verbosity > 3) { + cout << "\t\t\tresult = " << val << endl; + } + //add to sum + tmp_prev_weight += px_neighbor_w->at(l); + tmp_weight += val; + } //end l loop + if(num_l) { + //make sure each position gets same amount of weight + //regardless of number of layers + sum_prev_weight += tmp_prev_weight / num_l; + sum_weight += tmp_weight / num_l; + } + } //end neighbor loop + + if(sum_prev_weight == 0) { + sum_prev_weight = 1; + } + + sum_weight = sum_weight / sum_prev_weight * + init_weights.at(total_offset).at(layer); + + + #if ENABLE_SAME + if(adv_mode &ADV_SAME) { + //sum of neighbors (on same img) weights + float sum_neighbor_weights = 0; + for(int n = 0; n < num_neighbors / num_layers; n++) { + try { + sum_neighbor_weights += + *(old_weights.at(layer)->data() + neighbor_ptr_vec.at(n)); + } + catch(std::exception &e) { + abort(); + } + } + sum_weight *= sum_neighbor_weights; + } + #endif + + if(sum_weight > max_weight) + max_weight = sum_weight; + if(sum_weight < min_weight) + min_weight = sum_weight; + + //store in weights + raw_weights.push_back(sum_weight); + total_sum += sum_weight; + if(verbosity > 3) { + cout << "\t\traw weight = " << sum_weight << endl; + } + + } //end layer loop + /* + cout << "maxweigt: " << max_weight << endl; + cout << "minweight: " << min_weight << endl; + */ + //if diff is too small, just choose one with the heighest weight + if((adv_mode & khanAdvModes::ADV_UNAVG2) && + (min_weight >= 0.9 * max_weight)) { + bool tmp = true; + ... [truncated message content] |