/* File: example3.cpp An example of the use of the Quasisampler class. Reminder: This is a toy implementation, created to aid in understanding how the system works. This example generates a set of points for a grayscale bitmap. Usage: example3 image.pgm [magnitude_factor=200] This is a toy (non-optimized) implementation of the importance sampling technique proposed in the paper: "Fast Hierarchical Importance Sampling with Blue Noise Properties", by Victor Ostromoukhov, Charles Donohue and Pierre-Marc Jodoin, to be presented at SIGGRAPH 2004. Implementation by Charles Donohue, Based on Mathematica code by Victor Ostromoukhov. Universite de Montreal 05.08.04 */ #include <iostream> #include <fstream> #include "quasisampler_prototype.h" using namespace std; class ImageQuasisampler : public Quasisampler { unsigned *data; unsigned w,h; public: ImageQuasisampler(char* filename, double mag) { // Load the grayscale image if ( !loadPGM(filename, mag) ) { data=0; width=height=0; } } // Simple PGM parser (Low fault tolerance) bool loadPGM(char* filename, double mag=1.0) { if (!filename) { cerr << "Could not load PGM: no filename given." << endl; return false; } char buffer[80]; ifstream infile(filename); if ( !infile.is_open() ) { cerr << "Could not open file: " << filename << endl; return false; } infile.getline(buffer,80); if ( strcmp(buffer,"P2") ) { cerr << "PGM file header not recognized (P2 type only)" << endl; return false; } do { infile.getline(buffer,80); } while ( buffer[0]=='#' ); w = atoi(buffer); char *tmp = strchr(buffer,' '); tmp++; // skip whitespace h = atoi(tmp); do { infile.getline(buffer,80); } while ( buffer[0]=='#' ); unsigned maxval; maxval = atoi(buffer); // nb: not used. data = new unsigned[w*h]; for (unsigned i=0; i<w*h; i++) infile >> data[i]; infile.close(); if (mag != 1.0) for (unsigned i=0; i<w*h; i++) data[i] = (unsigned)(data[i]*mag); width = w; height = h; return true; } unsigned getImportanceAt( Point2D pt ) { // Nearest pixel sampling. return data[ w * ((unsigned)(height - pt.y)) + (unsigned)(pt.x) ]; } }; typedef std::vector<Point2D> PointList; int main(int argc, char* argv[]) { if (argc<2) { std::cout << "Usage: " << argv[0] << " image.pgm [magnitude_factor = 200]" << std::endl; } double mag_factor = 200.0; if (argc>2) mag_factor = atof(argv[2]); // initialize sampler ImageQuasisampler test( argv[1], mag_factor ); // generate points PointList points = test.getSamplingPoints(); // print points for ( PointList::iterator it=points.begin(); it!=points.end(); it++ ) std::cout << it->x << "," << it->y << std::endl; return 0; }
00001 /* 00002 00003 File: example3.cpp 00004 00005 An example of the use of the Quasisampler class. 00006 Reminder: This is a toy implementation, created 00007 to aid in understanding how the system works. 00008 00009 This example generates a set of points for a 00010 grayscale bitmap. 00011 00012 Usage: example3 image.pgm [magnitude_factor=200] 00013 00014 This is a toy (non-optimized) implementation of the importance sampling 00015 technique proposed in the paper: 00016 "Fast Hierarchical Importance Sampling with Blue Noise Properties", 00017 by Victor Ostromoukhov, Charles Donohue and Pierre-Marc Jodoin, 00018 to be presented at SIGGRAPH 2004. 00019 00020 00021 Implementation by Charles Donohue, 00022 Based on Mathematica code by Victor Ostromoukhov. 00023 Universite de Montreal 00024 05.08.04 00025 00026 */ 00027 00028 #include <iostream> 00029 #include <fstream> 00030 #include "quasisampler_prototype.h" 00031 using namespace std; 00032 00033 class ImageQuasisampler : public Quasisampler 00034 { 00035 unsigned *data; 00036 unsigned w,h; 00037 00038 public: 00039 ImageQuasisampler(char* filename, double mag) 00040 { 00041 // Load the grayscale image 00042 if ( !loadPGM(filename, mag) ) { data=0; width=height=0; } 00043 } 00044 00045 // Simple PGM parser (Low fault tolerance) 00046 bool loadPGM(char* filename, double mag=1.0) 00047 { 00048 if (!filename) { cerr << "Could not load PGM: no filename given." << endl; return false; } 00049 char buffer[80]; 00050 ifstream infile(filename); 00051 if ( !infile.is_open() ) { cerr << "Could not open file: " << filename << endl; return false; } 00052 infile.getline(buffer,80); 00053 if ( strcmp(buffer,"P2") ) 00054 { cerr << "PGM file header not recognized (P2 type only)" << endl; return false; } 00055 do { infile.getline(buffer,80); } while ( buffer[0]=='#' ); 00056 w = atoi(buffer); 00057 char *tmp = strchr(buffer,' '); tmp++; // skip whitespace 00058 h = atoi(tmp); 00059 do { infile.getline(buffer,80); } while ( buffer[0]=='#' ); 00060 unsigned maxval; 00061 maxval = atoi(buffer); // nb: not used. 00062 data = new unsigned[w*h]; 00063 for (unsigned i=0; i<w*h; i++) infile >> data[i]; 00064 infile.close(); 00065 00066 if (mag != 1.0) for (unsigned i=0; i<w*h; i++) data[i] = (unsigned)(data[i]*mag); 00067 00068 width = w; height = h; 00069 return true; 00070 } 00071 00072 unsigned getImportanceAt( Point2D pt ) 00073 { 00074 // Nearest pixel sampling. 00075 return data[ w * ((unsigned)(height - pt.y)) + (unsigned)(pt.x) ]; 00076 } 00077 }; 00078 00079 00080 typedef std::vector<Point2D> PointList; 00081 00082 int main(int argc, char* argv[]) 00083 { 00084 if (argc<2) 00085 { 00086 std::cout << "Usage: " << argv[0] << " image.pgm [magnitude_factor = 200]" << std::endl; 00087 } 00088 00089 double mag_factor = 200.0; 00090 if (argc>2) mag_factor = atof(argv[2]); 00091 00092 // initialize sampler 00093 ImageQuasisampler test( argv[1], mag_factor ); 00094 00095 // generate points 00096 PointList points = test.getSamplingPoints(); 00097 00098 // print points 00099 for ( PointList::iterator it=points.begin(); it!=points.end(); it++ ) 00100 std::cout << it->x << "," << it->y << std::endl; 00101 00102 return 0; 00103 } 00104