From: <jin...@us...> - 2007-07-06 04:55:51
|
Revision: 2231 http://hugin.svn.sourceforge.net/hugin/?rev=2231&view=rev Author: jing1986612 Date: 2007-07-05 21:55:49 -0700 (Thu, 05 Jul 2007) Log Message: ----------- khan deghosting standalone working Modified Paths: -------------- hugin/trunk/src/deghosting/khan.cpp Modified: hugin/trunk/src/deghosting/khan.cpp =================================================================== --- hugin/trunk/src/deghosting/khan.cpp 2007-07-05 20:50:56 UTC (rev 2230) +++ hugin/trunk/src/deghosting/khan.cpp 2007-07-06 04:55:49 UTC (rev 2231) @@ -237,16 +237,208 @@ // 1 2 3 4 // 5 6 7 8 // 9 10 11 12 - - // TODO: place call to your Khan routine here + if (g_verbose > 0) { std::cout << "deghosting (Khan algorithm) " << std::endl; } // free gray images to save memory - grayImages.clear(); origGrayImages.clear(); + //setup + int width, height, num_layers; + { + vigra::ImageImportInfo info(inputFiles[0].c_str()); + width = info.width(); + height = info.height(); + } + num_layers = inputFiles.size(); + //hm...er....nobody specified the number of iterations or neighbors?... ok.... + int num_iters = 9; + int rad_neighbors = 1; + int diam_neighbors = 2*rad_neighbors + 1; + int num_neighbors = diam_neighbors * diam_neighbors * num_layers; + std::vector<FImagePtr> init_weights (weights); + + if(g_verbose > 0) { + std::cout << "pre-fetching neighbors..." << std::endl; + } + + //(verified) pre-fetch descriptors as offset to ptr to each layer + // neighbors.at(i * width + j) is the offset for pixel(j, i) from the start of + // the floating point data pointer for each layer + std::vector<vector <int> > neighbors (width * height); + + //each pixel + for(int i = 0; i < height; i++) { + int curr_row = i * width; + for(int j = 0; j < width; j++) { + int curr_px = curr_row + j; + std::vector<int> curr; + + //each neighbor + for(int v = -rad_neighbors; v <= rad_neighbors; v++) { + int n_v = i + v; + if(n_v < 0) + n_v = 0; + else if(n_v >= height) + n_v = height - 1; + n_v = n_v * width; + + for(int h = -rad_neighbors; h <= rad_neighbors; h++) { + int n_h = j + h; + if(n_h < 0) + n_h = 0; + else if(n_h >= width) + n_h = width - 1; + + curr.push_back(n_v + n_h); + } //end h + }//end v + + neighbors.at(curr_px) = curr; + } //end j + } //end i + + if(g_verbose > 0) { + std::cout << "deghosting..." << std::endl; + } + + //for each iteration + for(int iter = 0; iter < num_iters; iter++) { + + if(g_verbose > 0) { + std::cout << "\n\niteration " << iter << "..." << endl; + } + + std::vector<FImagePtr> old_weights (weights); + //for each row + for(int row = 0; row < height; row++) { + + if(g_verbose ==2 || g_verbose == 3) { + if(row % 100) + cout << "."; + else + cout << endl << "row " << row; + } + + //for each column + for (int col = 0; col < width; col++) { + + if(g_verbose > 3 && !(col % 100)) + cout << "(x, y) = (" << col << ", " << row << ")" << endl; + + //get descriptors + std::vector<float> neighbor_values, prev_weight_values; + float sum_prev_weights = 0; + { + std::vector<int>::iterator neighbor_iter; + std::vector<int> neighbor_ptr_vec = neighbors.at(row * width + col); + + for(int layer = 0; layer < num_layers; layer++) { + //*** NEEDS VERIFYING + const float *pixels = grayImages.at(layer)->data(); + const float *weight_ptr = old_weights.at(layer)->data(); + + for(neighbor_iter = neighbor_ptr_vec.begin(); + neighbor_iter != neighbor_ptr_vec.end(); + neighbor_iter++) { + //get the surrounding pixels @ each layer + neighbor_values.push_back(*(pixels + *neighbor_iter)); + //get the weights from last pass @ each layer + float tmp = *(weight_ptr + *neighbor_iter); + prev_weight_values.push_back(tmp); + //add to sum of prev_weights + sum_prev_weights += tmp; + } //end neighbor_iter + + } //end layer + } + + if(g_verbose > 2 && row == 1 && col == 1) { + + cout << "\t\tneighbor values for (1, 1)"; + for(int i = 0; i < num_neighbors; i++) { + if(!(i % diam_neighbors)) { + if(!(i % (diam_neighbors * diam_neighbors))) + cout << "\n"; + cout << "\n\t\t\t"; + } + + cout.fill(' '); + cout.width(10); + cout << neighbor_values.at(i) << ", "; + } + + cout << "\n\t\tprev weights: "; + for(int i = 0; i < num_neighbors; i++) { + if( !(i % diam_neighbors)) { + if(!(i % (diam_neighbors * diam_neighbors))) { + cout << "\n"; + } + cout << "\n\t\t\t"; + } + + cout.fill(' '); + cout.width(10); + cout << prev_weight_values.at(i) << ", "; + } + cout << endl; + } + + float total_sum = 0; + std::vector<float> raw_weights; + + //for each layer + for(int layer = 0; layer < num_layers; layer++) { + //initialize sum to 0 + float sum_weight = 0; + //get center pixel + float curr_px = *(grayImages.at(layer)->data() + row * width + col); + + //for each neighbor + for(int n = 0; n < num_neighbors; n++) { + //diff against center + float val = curr_px - neighbor_values.at(n); + //gaussian + val = exp(val * val * -0.5) / sqrt(2 * 3.14159); + //multiply by prev weight + val *= prev_weight_values.at(n); + //add to sum + sum_weight += val; + } //end neighbor loop + + //divide sum of new by sum of prev weights * init weights + sum_weight = sum_weight / sum_prev_weights * + *(init_weights.at(layer)->data() + row * width + col); + + //store in weights + raw_weights.push_back(sum_weight); + //*(weights.at(layer)->getData() + row * width + column) = sum_weight; + total_sum += sum_weight; + } //end layer loop + + //normalize weights + if(total_sum) { + for(int layer = 0; layer < num_layers; layer++) { + *(float *)(weights.at(layer)->data() + row * width + col) = + raw_weights.at(layer) / total_sum; + } + } + else { + float avg = 1 / (float)num_layers; + for(int layer = 0; layer < num_layers; layer++) { + *(float *)(weights.at(layer)->data() + row * width + col) = avg; + } + } + + } //end column loop + } //end row loop + } //end iteration loop + + // free gray images to save memory + grayImages.clear(); + // apply weights and store result in output image weightedAverageOfImageFiles(inputFiles, weights, output, mask); return true; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |