// // Programmer: Craig Stuart Sapp // Creation Date: Sun Sep 30 23:06:34 PDT 2007 // Last Modified: Tue Oct 2 04:57:29 PDT 2007 // Filename: ...sig/examples/all/smoother.cpp // Web Address: http://sig.sapp.org/examples/museinfo/humdrum/smoother.cpp // Syntax: C++; museinfo // // Description: Smoothes data with exponential smoothing filter. // #include "humdrum.h" #include #include #ifndef OLDCPP using namespace std; #endif #define GEOMETRIC 1 #define ARITHMETIC 2 #define EMPTY 0 #define PEAK 1 #define VALLEY 2 /////////////////////////////////////////////////////////////////////////// // function declarations void checkOptions (Options& opts, int argc, char* argv[]); void example (void); void usage (const char* command); void processFile (HumdrumFile& infile); void smoothData (Array& output, Array& input, double gain); void generateRow (Array& imagerow, int row, int rows, double gain, Array& sequence); void printImage (Array >& image); // global variables Options options; // database for command-line arguments double sgain = 0.05; // maximum smoothing amount int height = 100; // number of pixels high for image // (width controlled by sequence length) int method = GEOMETRIC; // GEOMETRIC or ARITHMETIC interpolation // betwin lines in image. /////////////////////////////////////////////////////////////////////////// int main(int argc, char* argv[]) { HumdrumFile infile; // process the command-line options checkOptions(options, argc, argv); string filename; infile.clear(); // if no command-line arguments read data file from standard input int numinputs = options.getArgCount(); if (numinputs < 1) { infile.read(cin); } else { filename = options.getArg(1); infile.read(filename.c_str()); } processFile(infile); } /////////////////////////////////////////////////////////////////////////// ////////////////////////////// // // processFile -- only read the first row for processing for now... // void processFile(HumdrumFile& infile) { Array sequence; sequence.setSize(infile.getNumLines()); sequence.setSize(0); double value; int i; for (i=0; i > image; image.setSize(height); image.allowGrowth(0); for (i=0; i >& image) { cout << "P3\n"; cout << image[0].getSize() << " " << image.getSize() << "\n"; cout << "255\n"; int i, j; for (i=0; i& imagerow, int row, int rows, double gain, Array& sequence) { Array smoothed; double localgain; if (method == GEOMETRIC) { localgain = gain * pow(1.0 / gain, (double)row/(rows-1)); } else { localgain = (double)row/(rows-1) * (1.0 - gain); } smoothData(smoothed, sequence, localgain); int i; for (i=2; i smoothed[i-1] && smoothed[i] > smoothed[i+1] && smoothed[i] > smoothed[i-2] && smoothed[i] > smoothed[i+2] ) { imagerow[i] = PEAK; } else if (smoothed[i] < smoothed[i-1] && smoothed[i] < smoothed[i+1] && smoothed[i] < smoothed[i-2] && smoothed[i] < smoothed[i+2] ) { imagerow[i] = VALLEY; } } } ////////////////////////////// // // smoothData -- // void smoothData(Array& output, Array& input, double gain) { int thesize = input.getSize(); output.setSize(thesize); double filterk = gain; double oneminusk = 1.0 - filterk; // reverse filtering first output[thesize-1] = input[thesize-1]; int i; for (i=thesize-2; i>=0; i--) { output[i] = filterk*input[i] + oneminusk*output[i+1]; } // then forward filtering for (i=1; i