📄 selfquotientimage.cc
字号:
const char *help = "\progname: selfQotientImage.cc\n\code2html: This program reads a pgm image (grayscale) and normalizes the lighting conditions according to the Self-Quotient Image approach.\n\\n\The input image is filtered (weighed gaussian) several times, and the illumination-free\n\representation is obtained by dividing the input image by the filtered ones,\n\as described in the article by Wang, Li and Wang: \n\'Face Recognition under Varying Lighting conditions using Self Quotient Image'.\n\\n\version: Torch3 vision2.0, 2004-2005\n\(c) Guillaume Heusch (heusch@idiap.ch)\n";#include "ImageGray.h"#include "DiskXFile.h"#include "CmdLine.h"#include "ipWeighedGaussian.h"#include "ipHistoEqual.h"#include "Timer.h"using namespace Torch;int main(int argc, char **argv){ Timer timer; char *image_filename; char *sqi_filename; int nb_filters = 3; int min_size; int middle_size; int max_size; bool verbose; bool histo; // ------------------------ COMMAND LINE --------------------------------------------------------------------- CmdLine cmd; cmd.setBOption("write log", false); cmd.info(help); cmd.addText("\nArguments:"); cmd.addSCmdArg("image_filename", &image_filename, "input image filename"); cmd.addSCmdArg("sqi_filename", &sqi_filename, "self quotient image filename"); cmd.addText("\nOptions:"); cmd.addBCmdOption("-verbose", &verbose, false, "verbose"); cmd.addICmdOption("-min_size", &min_size, 3, "size of the smallest convolution kernel (must be odd)"); cmd.addICmdOption("-middle_size", &middle_size, 9, "size of the 'middle' convolution kernel (must be odd)"); cmd.addICmdOption("-max_size", &max_size, 15, "size of the biggest convolution kernel (must be odd)"); cmd.addBCmdOption("-histo", &histo, false, "apply histogram equalization on the result"); cmd.read(argc, argv); Allocator *allocator = new Allocator; // ----------------------- LOAD IMAGE -------------------------------------------------------------------------- DiskXFile *image_file = NULL; Image *image_in = NULL; image_in = new(allocator) ImageGray(); image_in->setBOption("verbose", verbose); image_file = new(allocator) DiskXFile(image_filename, "r"); image_in->loadXFile(image_file); if(verbose) { print("Image info:\n"); print(" width = %d\n", image_in->width); print(" height = %d\n", image_in->height); print(" format = %s (%d)\n", image_in->coding, image_in->n_planes); } // ---------------- MULTI-SCALE ANISOTROPIC GAUSSIAN FILTERING ------------------------------------------------------ Image** filtered_array = new Image*[nb_filters]; ipCore *weighedGaussian = NULL; for (int filter_index = 0; filter_index < nb_filters; filter_index++) filtered_array[filter_index] = NULL; for (int filter_index = 0; filter_index < nb_filters; filter_index++) { int size = 0; if (filter_index == 0) size = min_size; if (filter_index == 1) size = middle_size; if (filter_index == 2) size = max_size; weighedGaussian = new(allocator) ipWeighedGaussian(size, image_in->width, image_in->height, "gray"); weighedGaussian->process(image_in); filtered_array[filter_index] = new(allocator) ImageGray(); filtered_array[filter_index]->copyFrom(image_in->width,image_in->height, weighedGaussian->seq_out->frames[0], "gray", 255); filtered_array[filter_index]->updatePixmapFromData(); // ************************************************ // IF YOU WANT TO SAVE THE FILTERED IMAGES // ----------------------------------------------- // char filename[50]; // sprintf(filename, "filtered_%ix%i", size, size); // strcat(filename, ".pgm"); // rescale(filtered_array[filter_index]->data, filtered_array[filter_index]->width, filtered_array[filter_index]->height); // filtered_array[filter_index]->updatePixmapFromData(); // filtered_array[filter_index]->save(filename); // *********************************************** } // ---------------------- BUILD AND SAVE THE SELF-QUOTIENT IMAGE -------------------------------------------- Image** qi_array = new Image*[nb_filters]; for (int i = 0; i < nb_filters; i++) qi_array[i] = NULL; // build the normalized images for (int filter_index = 0; filter_index < nb_filters; filter_index++) { qi_array[filter_index] = new(allocator) ImageGray(image_in->width, image_in->height); for (int i=0; i<(image_in->width*image_in->height); i++) { qi_array[filter_index]->data[i] = log((image_in->data[i]+1)/(filtered_array[filter_index]->data[i]+1)); } int size = 0; if (filter_index == 0) size = min_size; if (filter_index == 1) size = middle_size; if (filter_index == 2) size = max_size; } Image *sqi = NULL; sqi = new(allocator) ImageGray(image_in->width, image_in->height); sqi->setBOption("verbose", verbose); // ---------------------- TEMP -------------- for (int n_image = 0; n_image < nb_filters; n_image++) { for (int i=0; i<(sqi->width*sqi->height); i++) sqi->data[i] += qi_array[n_image]->data[i]; } //rescale between 0-255 scaleGray(sqi->width, sqi->height, sqi->data); // histogram equalization if specified ipCore *histoEq = NULL; if (histo) { histoEq = new(allocator) ipHistoEqual(image_in->width, image_in->height, "gray"); histoEq->process(sqi); } Image *image_out = NULL; image_out = new(allocator) ImageGray(); image_out->setBOption("verbose", verbose); if (histo) image_out->copyFrom(image_in->width, image_in->height, histoEq->seq_out->frames[0], "gray", 255); else image_out->copyFrom(image_in->width, image_in->height, sqi->data, "gray", 255); image_out->updatePixmapFromData(); image_out->save(sqi_filename); // ----------------------- CLEAN UP ----------------------------------------------------------------------- delete[] filtered_array; delete[] qi_array; delete allocator; print("time elapsed: %g\n", timer.getTime()); timer.stop(); return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -