Go to the documentation of this file.00001
00002 #include "bsta_int_histogram_1d.h"
00003
00004
00005
00006 #include "bsta_gauss.h"
00007 #include <vcl_iostream.h>
00008
00009
00010 bsta_int_histogram_1d::bsta_int_histogram_1d(unsigned int bins)
00011 {
00012 nbins_ = bins;
00013 counts_.resize(nbins_, 0);
00014 }
00015
00016
00017 bsta_int_histogram_1d::~bsta_int_histogram_1d() {}
00018
00019
00020
00021
00022 unsigned int bsta_int_histogram_1d::get_min_bin()
00023 {
00024 unsigned int i = 0;
00025 while (i<(nbins_-1) && !counts_[i])
00026 i++;
00027 if (i >= nbins_)
00028 return 0;
00029 return i;
00030 }
00031
00032 unsigned int bsta_int_histogram_1d::get_max_bin()
00033 {
00034 unsigned int i = nbins_;
00035 while (i>0 && counts_[--i] == 0)
00036 ;
00037 return i;
00038 }
00039
00040
00041 unsigned long int bsta_int_histogram_1d::get_area()
00042 {
00043 long int area = 0;
00044 for (unsigned int i=0; i<nbins_; i++)
00045 { area = area + counts_[i]; }
00046 return area;
00047 }
00048
00049
00050 long int bsta_int_histogram_1d::get_count(unsigned int bin)
00051 {
00052 if (bin < nbins_)
00053 return counts_[bin];
00054 else
00055 return 0;
00056 }
00057
00058
00059 void bsta_int_histogram_1d::set_count(unsigned int bin, long int val)
00060 {
00061 if (bin<nbins_) counts_[bin] = val;
00062 }
00063
00064
00065 unsigned long int bsta_int_histogram_1d::get_max_val(unsigned int &imax)
00066 {
00067 register long int max = 0;
00068 for (unsigned int i=0; i<nbins_; i++)
00069 if ( counts_[i] > max ) {
00070 max = counts_[i];
00071 imax = i;
00072 }
00073 return max;
00074 }
00075
00076
00077
00078 void bsta_int_histogram_1d::trim(float low_fract, float high_fract)
00079 {
00080 long int total = this->get_area();
00081 long int low_count = static_cast<long int>(((float)total * low_fract) + 0.5);
00082 long int high_count = static_cast<long int>(((float)total * high_fract) + 0.5);
00083
00084
00085 int i = 0;
00086 while (i<(int)nbins_ && low_count > 0)
00087 {
00088 if (counts_[i] > 0) {
00089 if (low_count >= counts_[i]) {
00090 low_count = low_count - counts_[i];
00091 counts_[i] = 0;
00092 ++i;
00093 }
00094 else {
00095 counts_[i] = counts_[i] - low_count;
00096 low_count = 0;
00097 ++i;
00098 }
00099 }
00100 }
00101
00102
00103 i = nbins_ - 1;
00104 while (i>=0 && high_count > 0)
00105 {
00106 if (counts_[i] > 0) {
00107 if (high_count >= counts_[i]) {
00108 high_count = high_count - counts_[i];
00109 counts_[i] = 0;
00110 --i;
00111 }
00112 else {
00113 counts_[i] = counts_[i] - high_count;
00114 high_count = 0;
00115 --i;
00116 }
00117 }
00118 }
00119 return;
00120 }
00121
00122
00123
00124 void bsta_int_histogram_1d::zero_low(unsigned int n)
00125 {
00126 for (unsigned int i=0; i<n; i++) counts_[i] = 0;
00127 }
00128
00129
00130
00131 void bsta_int_histogram_1d::zero_high(unsigned int n)
00132 {
00133 for (unsigned int i=nbins_-1; i>nbins_-n; i--) counts_[i] = 0;
00134 }
00135
00136
00137 void bsta_int_histogram_1d::parzen(const float sigma)
00138 {
00139 if (sigma<=0)
00140 return;
00141 double sd = (double)sigma;
00142 vcl_vector<double> in(nbins_), out(nbins_);
00143 for (unsigned int i=0; i<nbins_; i++)
00144 in[i] = counts_[i];
00145 bsta_gauss::bsta_1d_gaussian(sd, in, out);
00146 for (unsigned int i=0; i<nbins_; i++)
00147 counts_[i] = static_cast<long int>(out[i] +0.5);
00148 }
00149
00150
00151
00152 bool bsta_int_histogram_1d::find_peaks( float perct, int &n_peaks, vcl_vector<unsigned int> &peaks)
00153 {
00154 bool success = false;
00155
00156 unsigned int peak_index = 0;
00157 long int ymax = get_max_val(peak_index);
00158 long int hysteresis = static_cast<long int>(ymax*perct);
00159 n_peaks = 0;
00160
00161
00162 if (counts_[0] > 0)
00163 vcl_cerr << "Warning, counts_[0] in diagonal hist != 0, Major Error!!\n";
00164 if (counts_[0] > hysteresis)
00165 return success;
00166
00167
00168 bool direction = true;
00169 #if 0 // unused variables ?!
00170 bool past_p_thresh = false;
00171 bool past_v_thresh = false;
00172 #endif // 0
00173 long int last_p_val = 0;
00174 unsigned int last_p_index = 0;
00175 long int last_v_val = 0;
00176 unsigned int last_v_index = 0;
00177
00178
00179
00180
00181 unsigned int j = 0;
00182 unsigned int istart = 0;
00183 for (unsigned int i=1; i<nbins_; i++)
00184 {
00185 if (counts_[i] > 0)
00186 {
00187 peaks[j] = i-1;
00188 n_peaks = 1;
00189 last_v_index = i-1;
00190 istart = i;
00191 j = 1;
00192 break;
00193 }
00194 }
00195
00196
00197 for (unsigned int i=istart; i<nbins_; i++)
00198 {
00199 long int delta = counts_[i] - counts_[i-1];
00200 if (delta > 0) direction = true;
00201 if (delta < 0) direction = false;
00202
00203
00204 if (direction)
00205 {
00206 if (counts_[i] - last_v_val > hysteresis)
00207 {
00208
00209
00210
00211 if (j>1 && last_v_index > peaks[j-1])
00212 {
00213 peaks[j] = last_v_index;
00214 n_peaks++;
00215 j++;
00216
00217
00218
00219 last_p_val = last_v_val;
00220 }
00221
00222
00223 if (counts_[i] > last_p_val)
00224 {
00225 last_p_val = counts_[i];
00226 last_p_index = i;
00227 }
00228 }
00229 }
00230 else
00231 {
00232
00233 if (last_p_val - counts_[i] > hysteresis)
00234 {
00235
00236
00237 if (last_p_index > peaks[j-1])
00238 {
00239 peaks[j] = last_p_index;
00240 n_peaks++;
00241 j++;
00242
00243 last_v_val = last_p_val;
00244 }
00245
00246
00247 if (counts_[i] < last_v_val)
00248 {
00249 last_v_val = counts_[i];
00250 last_v_index = i;
00251 }
00252 }
00253 }
00254 }
00255
00256
00257 if (last_v_index > peaks[j-1])
00258 {
00259 peaks[j] = last_v_index;
00260 n_peaks++;
00261 }
00262
00263 success = true;
00264 return success;
00265 }