Main Page   Modules   Class Hierarchy   Compound List   File List   Compound Members   Related Pages   Examples  

Histogram.cpp

00001 /* Copyright (c) 2001 S.E. Grigorescu */
00002 
00003 #include "Histogram.h"
00004 #include <math.h>
00005 #include <strstream.h> 
00006 
00007 template class Histogram< int >;
00008 template class Histogram< float >;
00009 
00010 template< class T > Histogram< T >::Histogram(Image< T > &input, int no_bins = 100)
00011 {
00012   bins = no_bins;
00013   hist = new double[bins];
00014   for (int i = 0; i < bins; hist[i++] = 0.0) ;
00015   img = input;
00016   min_x = (double)img.min();
00017   max_x = (double)img.max();
00018   compute_histogram();
00019 
00020 #ifdef HAVE_LIBPLOTTER
00021   grapher_disp = NULL;
00022   grapher_wrt = NULL;
00023   Width = Height = 600;
00024   bg = "White"; 
00025   top_label = "";
00026   x_label = "";
00027   y_label = "";
00028   title_font_name = "Helvetica";
00029   xy_font_name = "Helvetica";
00030   title_font_size = 0.07;
00031   xy_font_size = 0.0525;
00032   final_min_x = (double)img.min();
00033   final_max_x = (double)img.max();
00034   final_min_y = 0.0;
00035   final_max_y = (double)img.getSize();
00036   final_spacing_x = final_spacing_y = 00.;
00037   final_log_axis = 0;
00038   final_transpose_axes = false;
00039   fill_fraction = 1.0;
00040   x_range_spec = false;
00041   y_range_spec = false;
00042 #endif
00043 }
00044 
00045 template< class T > Histogram< T >::Histogram(Image< T > &input, int no_bins, T min, T max)
00046 {
00047   bins = no_bins;
00048   hist = new double[bins];
00049   for (int i = 0; i < bins; hist[i++] = 0.0) ;
00050   img = input;
00051   min_x = (double)min;
00052   max_x = (double)max;
00053   compute_histogram();
00054 
00055 #ifdef HAVE_LIBPLOTTER
00056   grapher_disp = NULL;
00057   grapher_wrt = NULL;
00058   Width = Height = 600;
00059   bg = "White"; 
00060   top_label = "";
00061   x_label = "";
00062   y_label = "";
00063   title_font_name = "Helvetica";
00064   xy_font_name = "Helvetica";
00065   title_font_size = 0.07;
00066   xy_font_size = 0.0525;
00067   final_min_x = (double)img.min();
00068   final_max_x = (double)img.max();
00069   final_min_y = 0.0; 
00070   final_max_y = (double)img.getSize(); 
00071   final_spacing_x = final_spacing_y = 0.0;  
00072   final_log_axis = 0;
00073   final_transpose_axes = false;
00074   fill_fraction = 1.0;
00075   x_range_spec = false;
00076   y_range_spec = false;
00077 #endif
00078 }
00079 
00080 template< class T > Histogram< T >::~Histogram()
00081 {
00082   delete[] hist;
00083 
00084 #ifdef HAVE_LIBPLOTTER
00085   closeWindow();
00086 #endif
00087 }
00088 
00089 template< class T > void Histogram< T >::compute_histogram()
00090 {
00091   for (int i = 0; i < bins; hist[i++] = 0.0) ;
00092   for (int i = 0; i < img.getSize(); i++)
00093     if (img.getPixels()[i] >= min_x && img.getPixels()[i] <= max_x)
00094       hist[(int)floor((bins-1)*(img.getPixels()[i]-min_x)/(max_x-min_x))]++;
00095 }
00096 
00097 template< class T > void Histogram< T >::equalize(Image< T > &output)
00098 {
00099   output = img;
00100   double *c_hist = new double[bins];
00101   c_hist[0] = hist[0];
00102   for (int i = 1; i < bins; i++)
00103     c_hist[i] = c_hist[i-1] + hist[i];
00104   
00105   for (int i = 0; i < img.getHeight(); i++)
00106     for (int j = 0; j < img.getWidth(); j++) 
00107       if (img[i][j] >= min_x && img[i][j] <= max_x) {
00108         double tmp = c_hist[(int)floor((bins-1)*(img[i][j]-min_x)/(max_x-min_x))];
00109         output[i][j] = (T)((max_x-min_x)*tmp/c_hist[bins-1] + min_x);
00110     }
00111   delete[] c_hist;
00112 }
00113 
00114 #ifdef HAVE_LIBPLOTTER
00115 template< class T > void Histogram< T >::showHistogram()
00116 {
00117   Point *p = NULL;
00118   p = new Point[4 * bins];
00119 
00120   for (int i = 0; i < 4 * bins; i++)
00121     set_point_attr(p[i]);
00122 
00123   int counter = 0; 
00124   for (int i = 0; i < bins; i++)
00125     if (add_point(hist[i], min_x+i*(max_x-min_x)/bins, 
00126                   min_x+(i+1)*(max_x-min_x)/bins, 4*counter, p))
00127       counter++;
00128   
00129   array_bounds (p, 4 * counter, final_transpose_axes, 1,
00130                 &final_min_x, &final_min_y, &final_max_x, &final_max_y,
00131                 x_range_spec, y_range_spec, x_range_spec, y_range_spec);
00132   
00133   ostrstream dim;
00134   dim << Width << "x" << Height << ends;
00135   if (grapher_disp == NULL) grapher_disp = new_grapher ("X", NULL, bg, dim.str(),
00136                                                         "yes", "500", "yes",
00137                                                         "A4", "0", false);
00138   
00139   begin_graph (grapher_disp, 1.0, 0.0, 0.0);  
00140   set_graph_parameters(grapher_disp, 0.005, "black", top_label, title_font_name, 
00141                        title_font_size, 0.01, AXES_AND_BOX, 
00142                        final_min_x, final_max_x, final_spacing_x, 
00143                        final_min_y, final_max_y, final_spacing_y,
00144                        false, false, 0.7, 0.7, 0.2, 0.2, 
00145                        xy_font_name, xy_font_size, x_label, 
00146                        xy_font_name, xy_font_size, y_label, 
00147                        false, final_log_axis, 0, 0, 0, 1, 1.3, final_transpose_axes);
00148   draw_frame_of_graph (grapher_disp, false);
00149   plot_point_array(grapher_disp, p, 4*counter);
00150   delete[] p;
00151   end_polyline_and_flush (grapher_disp);
00152   end_graph(grapher_disp);
00153 }
00154 
00155 template< class T > void Histogram< T >::set_point_attr(Point &point)
00156 {
00157   point.x = 0.0;
00158   point.y = 0.0;
00159   point.symbol = 1;
00160   point.symbol_size = 0.05;
00161   point.symbol_font_name = "ZapfDingbats";
00162   point.linemode = 1;
00163   point.line_width = 0.001;
00164   point.fill_fraction = fill_fraction;
00165   point.use_color = false;
00166   point.have_x_errorbar = false;
00167   point.have_y_errorbar = false;
00168   point.pendown = true;
00169 }
00170 
00171 template< class T > bool Histogram< T >::add_point(double y, double x1, double x2, 
00172                                                    int pos, Point *p)
00173 {
00174   if (x_range_spec && (x1 < final_min_x || x1 > final_max_x))
00175     return false;
00176   else {
00177     double y1, y2;
00178     y1 = y_range_spec ? final_min_y : 0.0;
00179     y2 = (y_range_spec && y > final_max_y) ? final_max_y : y;
00180 
00181     p[pos  ].x = x1; p[pos  ].y = y1;
00182     p[pos+1].x = x1; p[pos+1].y = y2;
00183     p[pos+2].x = (x_range_spec && x2 > final_max_x) ? final_max_x : x2; p[pos+2].y = y2;
00184     p[pos+3].x = (x_range_spec && x2 > final_max_x) ? final_max_x : x2; p[pos+3].y = y1;
00185     return true;
00186   }
00187 }
00188 
00189 template< class T > void Histogram< T >::writeHistogram(char *type, char *file_name)
00190 {
00191   if (strcmp(type, "Gif") * strcmp(type, "PS") *
00192       strcmp(type, "Fig") * strcmp(type, "Bmp") == 0) {
00193     if (grapher_wrt != NULL) {
00194       delete_grapher(grapher_wrt);
00195       grapher_wrt = NULL;
00196     }
00197     FILE* fo = fopen(file_name, "w");
00198 
00199     Point * p = (Point *)xmalloc (4 * bins * sizeof (Point));
00200     for (int i = 0; i < 4 * bins; i++)
00201       set_point_attr(p[i]);
00202    
00203     int counter = 0;
00204     for (int i = 0; i < bins; i++)
00205       if (add_point(hist[i], min_x+i*(max_x-min_x)/bins, 
00206                   min_x+(i+1)*(max_x-min_x)/bins, 4*counter, p))
00207         counter++;
00208     array_bounds (p, 4 * counter, final_transpose_axes, 1,
00209                   &final_min_x, &final_min_y, &final_max_x, &final_max_y,
00210                   x_range_spec, y_range_spec, x_range_spec, y_range_spec);
00211     ostrstream dim; 
00212     dim << Width << "x" << Height << ends;
00213     if (grapher_wrt == NULL) grapher_wrt = new_grapher (type, fo, bg, dim.str(), 
00214                                                         "yes", "500", "yes", 
00215                                                         "A4", "0", false);
00216     begin_graph (grapher_wrt, 1, 0, 0);  
00217     set_graph_parameters (grapher_wrt, .005, "black", top_label, title_font_name, 
00218                         title_font_size, .01, AXES_AND_BOX, final_min_x, final_max_x, 
00219                         final_spacing_x, final_min_y, final_max_y, final_spacing_y, 
00220                         false, false, .7, .7, .2, .2, xy_font_name, xy_font_size, x_label, 
00221                         xy_font_name, xy_font_size, y_label, false, final_log_axis, 
00222                         0, 0, 0, 1, 1.3, final_transpose_axes);
00223     draw_frame_of_graph (grapher_wrt, true); 
00224     plot_point_array (grapher_wrt, p, 4*counter);
00225     free(p);
00226     end_polyline_and_flush (grapher_wrt);
00227     end_graph(grapher_wrt);
00228     delete_grapher (grapher_wrt);
00229     grapher_wrt = NULL;
00230     fclose(fo); 
00231   }
00232   else 
00233     cout << "Format unsupported! Supported formats are: \"Gif\", \"PS\", \"Fig\", and \"Bmp\"." << endl; 
00234 }
00235 
00236 template< class T > void Histogram< T >::closeWindow()
00237 {
00238   if (grapher_disp != NULL) {
00239     delete_grapher(grapher_disp);
00240     grapher_disp = NULL;
00241   }
00242 }
00243 #endif
00244 
00245