00001
00002 #include <vifa/vifa_histogram.h>
00003
00004
00005 #include <vcl_algorithm.h>
00006 #include <vcl_cmath.h>
00007 #include <vcl_iostream.h>
00008 #include <vcl_fstream.h>
00009 #include <vcl_cstdio.h>
00010
00011 static int MEAN_FLAG = 1;
00012 static int SD_FLAG = 2;
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 vifa_histogram::vifa_histogram()
00023 {
00024 vals = new float [1];
00025 vals[0] = 0.0f;
00026 counts = new float [1];
00027 counts[0] = 0.0f;
00028 num = 0;
00029 vmin = 0;
00030 vmax = 0;
00031 delta = 0.0f;
00032 mean = 0.0f;
00033 standard_dev = 0.0f;
00034 stats_consistent = 0;
00035 stats_consistent |= (MEAN_FLAG | SD_FLAG);
00036 delimiter = ' ';
00037 }
00038
00039 vifa_histogram::vifa_histogram(int xres, float val1, float val2)
00040 {
00041 vals = new float [xres];
00042 counts = new float [xres];
00043 num = xres;
00044
00045
00046
00047 vmax = vcl_max(val2, val1);
00048 vmin = vcl_min(val2, val1);
00049
00050 delta = (vmax - vmin) / xres;
00051 mean = (vmax + vmin) / 2.0f;
00052 standard_dev = (vmax - vmin) / float(2 * vcl_sqrt(3.0));
00053 stats_consistent = 0;
00054 stats_consistent |= (MEAN_FLAG | SD_FLAG);
00055 delimiter = ' ';
00056
00057 if (vals == NULL || counts == NULL)
00058 {
00059 vcl_cerr << "vifa_histogram : Ran out of array memory.\n\n";
00060 vals = NULL;
00061 counts = NULL;
00062 num = 0;
00063 vmin = 0;
00064 vmax = 0;
00065 delta = 0.0f;
00066 }
00067 else
00068 {
00069 for (int i = 0; i < xres; i++)
00070 {
00071 vals[i] = vmin + (delta * (i + 0.5f));
00072 counts[i] = 0.0f;
00073 }
00074 }
00075 }
00076
00077 vifa_histogram::vifa_histogram(float* uvals, float* ucounts, int xres)
00078 {
00079 stats_consistent = 0;
00080 vals = uvals;
00081 counts = ucounts;
00082 num = xres;
00083 delta = vals[1] - vals[0];
00084
00085
00086
00087
00088 vmin = uvals[0] - 0.5f * delta;
00089 vmax = uvals[num-1] + 0.5f * delta;
00090
00091 mean = GetMean();
00092 standard_dev = GetStandardDev();
00093 stats_consistent |= (MEAN_FLAG | SD_FLAG);
00094
00095 delimiter = ' ';
00096 }
00097
00098
00099 vifa_histogram::vifa_histogram(const vifa_histogram& h)
00100 : vul_timestamp(), vbl_ref_count()
00101 {
00102
00103
00104 stats_consistent = 0;
00105 vifa_histogram& his = (vifa_histogram&)h;
00106
00107 num = his.GetRes();
00108
00109 vals = new float[num];
00110 float* his_vals = his.GetVals();
00111
00112 counts = new float[num];
00113 float* his_counts = his.GetCounts();
00114
00115 if (vals == NULL || counts == NULL)
00116 {
00117 vcl_cerr << "vifa_histogram : Ran out of array memory.\n\n";
00118 vals = NULL;
00119 counts = NULL;
00120 num = 0;
00121 vmin = 0;
00122 vmax = 0;
00123 delta = 0.0f;
00124 stats_consistent = 0;
00125 return;
00126 }
00127
00128 mean = his.GetMean();
00129 standard_dev = his.GetStandardDev();
00130
00131 for (int i = 0; i < num; i++)
00132 {
00133 vals[i] = his_vals[i];
00134 counts[i] = his_counts[i];
00135 }
00136
00137
00138
00139
00140 vmax = his.GetMaxVal();
00141 vmin = his.GetMinVal();
00142
00143 delta = his.GetBucketSize();
00144 stats_consistent |= (MEAN_FLAG | SD_FLAG);
00145 delimiter = h.delimiter;
00146 }
00147
00148
00149
00150 vifa_histogram::~vifa_histogram()
00151 {
00152 if (vals)
00153 delete [] vals;
00154 if (counts)
00155 delete [] counts;
00156 }
00157
00158
00159
00160
00161 vifa_histogram::vifa_histogram(vifa_histogram const* his, float width, bool preserveCounts)
00162 {
00163 stats_consistent = 0;
00164
00165
00166
00167 float org_delta = his->GetBucketSize();
00168
00169
00170 int max_index = his->GetRes() - 1;
00171
00172
00173 float minvalue = his->GetVals()[0] - (org_delta * 0.5f);
00174
00175
00176 float maxvalue = his->GetVals()[max_index] + (org_delta * 0.5f);
00177
00178
00179 if (width == org_delta)
00180 {
00181 num = his->GetRes();
00182 }
00183 else if (!(width == 0.0f))
00184 {
00185
00186 num = (int)vcl_ceil((maxvalue - minvalue) / width);
00187 }
00188 else
00189 {
00190
00191 num = 1;
00192 }
00193
00194 vals = new float [num];
00195 counts = new float [num];
00196 delta = width;
00197
00198
00199 float mean_val = (maxvalue + minvalue) * 0.5f;
00200 float half_range = (num * delta) * 0.5f;
00201
00202
00203 vmax = mean_val + half_range;
00204 vmin = mean_val - half_range;
00205
00206 if (vals == NULL || counts == NULL)
00207 {
00208 vcl_cerr << "vifa_histogram : Ran out of array memory.\n\n";
00209 vals = NULL;
00210 counts = NULL;
00211 num = 0;
00212 vmin = 0;
00213 vmax = 0;
00214 delta = 0.0f;
00215 mean = 0.0f;
00216 standard_dev = 0.0f;
00217 stats_consistent |= (MEAN_FLAG | SD_FLAG);
00218 return;
00219 }
00220 else
00221 {
00222 for (int i = 0; i < num; i++)
00223 {
00224
00225 vals[i] = vmin + (delta * (i + 0.5f));
00226 counts[i] = 0.0f;
00227 }
00228 }
00229
00230
00231
00232 if (delta == org_delta)
00233 {
00234 float* his_counts = his->GetCounts();
00235 for (int i = 0; i < num; i++)
00236 counts[i] = his_counts[i];
00237 mean = GetMean();
00238 standard_dev = GetStandardDev();
00239 stats_consistent |= (MEAN_FLAG | SD_FLAG);
00240 return;
00241 }
00242
00243 if (org_delta > delta)
00244 {
00245
00246
00247
00248
00249 float his_start = minvalue + (0.5f * org_delta);
00250
00251
00252 float start = vmin + (0.5f * delta);
00253
00254
00255 float c0 = his->GetCount(his_start);
00256
00257
00258 float c1 = his->GetCount(his_start + org_delta);
00259
00260
00261 float s0 = (c1 - c0) / org_delta;
00262
00263
00264
00265 for (float x = start; x <= (his_start + org_delta + delta);)
00266 {
00267 float x_diff = x - his_start;
00268 float interp = c0 + (s0 * x_diff);
00269
00270
00271
00272 if (interp < 0)
00273 interp = 0;
00274
00275 SetCount(x, interp);
00276 x += delta;
00277 }
00278
00279
00280
00281 float his_end = maxvalue - (0.5f * org_delta);
00282
00283
00284 float end = vmax - (0.5f * delta);
00285
00286
00287 float cn = his->GetCount(his_end);
00288
00289
00290 float cn_1 = his->GetCount(his_end - org_delta);
00291
00292
00293 float sn = (cn_1 - cn) / org_delta;
00294
00295
00296
00297 for (float y = end; y >= (his_end - org_delta + delta);)
00298 {
00299 float x_diff = his_end - y;
00300 float interp = cn + (sn * x_diff);
00301 if (interp < 0)
00302 interp = 0;
00303
00304 SetCount(y, interp);
00305 y -= delta;
00306 }
00307
00308
00309 for (float z = his_start + org_delta; z <= (his_end - org_delta);)
00310 {
00311
00312 float ci = his->GetCount(z);
00313 float ci_1 = his->GetCount(z - org_delta);
00314 float cip1 = his->GetCount(z + org_delta);
00315
00316
00317 float deriv = (cip1 - ci_1)/(2.0f * org_delta);
00318
00319
00320 float second_drv =
00321 (((cip1 + ci_1) / 2.0f) - ci) / (org_delta * org_delta);
00322
00323
00324 int fine_x_index = GetIndex(z);
00325
00326
00327 if (fine_x_index < 0)
00328 {
00329 if (z < vmin)
00330 fine_x_index = 0;
00331 else
00332 fine_x_index = num - 1;
00333 }
00334
00335
00336 float fine_x = vals[fine_x_index];
00337
00338
00339
00340 for (float xfine = fine_x; xfine < z + org_delta;)
00341 {
00342 float interp = ci + (deriv * (xfine - z)) +
00343 second_drv * (xfine - z) * (xfine - z);
00344 if (interp < 0)
00345 interp = 0;
00346
00347 SetCount(xfine, interp);
00348 xfine += delta;
00349 }
00350
00351 z += org_delta;
00352 }
00353
00354
00355
00356
00357 if (preserveCounts)
00358 {
00359 float scaleFactor = delta / org_delta;
00360 for (int i = 0; i < num; i++)
00361 counts[i] *= scaleFactor;
00362 }
00363 }
00364
00365
00366 if (org_delta < delta)
00367 {
00368
00369 if (org_delta != 0.0f)
00370 {
00371 float his_start = minvalue + (0.5f * org_delta);
00372 float his_end = maxvalue - (0.5f * org_delta);
00373 for (float x = his_start; x <= his_end;)
00374 {
00375 SetCount(x, GetCount(x) + his->GetCount(x));
00376 x += org_delta;
00377 }
00378 }
00379 }
00380
00381 mean = GetMean();
00382 standard_dev = GetStandardDev();
00383 stats_consistent = (MEAN_FLAG | SD_FLAG);
00384 delimiter = his->delimiter;
00385 }
00386
00387
00388
00389
00390
00391 vifa_histogram* vifa_histogram::Scale(float scale_factor)
00392 {
00393 stats_consistent = 0;
00394
00395
00396
00397 float highvalue = vals[num-1];
00398
00399
00400
00401 vifa_histogram* scaled_his = new vifa_histogram(this, delta);
00402 float* new_counts = scaled_his->GetCounts();
00403 for (int i = 0; i < num; i++)
00404 new_counts[i] = 0.0f;
00405
00406
00407
00408
00409 float scale = scale_factor;
00410 if (scale_factor > 1.0f)
00411 scale = 1.0f;
00412
00413 for (float x = highvalue; x > vmin;)
00414 {
00415 float trans_x = (x - vmin) * scale + vmin;
00416 int index = GetIndex(trans_x);
00417 if (index < 0)
00418 {
00419 if (trans_x < vmin)
00420 index = 0;
00421 else
00422 index = num - 1;
00423 }
00424
00425 float fraction = (trans_x - vals[index])/delta;
00426 float abs_fraction = (float)vcl_fabs(fraction);
00427 int x_index = GetIndex(x);
00428 if (x_index < 0)
00429 {
00430 if (x < vmin)
00431 x_index = 0;
00432 else
00433 x_index = num - 1;
00434 }
00435
00436
00437
00438 new_counts[index] += (1.0f - abs_fraction) * counts[x_index];
00439 if (fraction > 0)
00440 {
00441 if (index < (num - 1))
00442 new_counts[index + 1] += abs_fraction * counts[x_index];
00443 else
00444 new_counts[index] += abs_fraction * counts[x_index];
00445 }
00446 else
00447 {
00448 if (index > 0)
00449 new_counts[index - 1] += abs_fraction * counts[x_index];
00450 else
00451 new_counts[index] += abs_fraction * counts[x_index];
00452 }
00453
00454 x -= delta;
00455 }
00456
00457
00458
00459 mean = scaled_his->GetMean();
00460 standard_dev = scaled_his->GetStandardDev();
00461 stats_consistent |= (MEAN_FLAG | SD_FLAG);
00462 return scaled_his;
00463 }
00464
00465
00466
00467
00468
00469
00470
00471 vifa_histogram* vifa_histogram::Cumulative()
00472 {
00473 vifa_histogram* cum_his = new vifa_histogram(*this);
00474 float* density_counts = this->GetCounts();
00475 int res = this->GetRes();
00476
00477
00478 float* cum_counts = cum_his->GetCounts();
00479 for (int j=0; j < res; j++)
00480 cum_counts[j] = 0;
00481
00482
00483 for (int i = (res - 1); i >= 0; i--)
00484 for (int j = i; j >= 0; j--)
00485 cum_counts[j] += density_counts[i];
00486
00487
00488
00489
00490
00491
00492 cum_his->vmin = cum_his->GetMinVal() - 0.5f * cum_his->GetBucketSize();
00493 cum_his->vmax = cum_his->GetMaxVal() + 0.5f * cum_his->GetBucketSize();
00494
00495 return cum_his;
00496 }
00497
00498
00499
00500
00501
00502
00503
00504 inline float GetExtendedCount(int bin, int n_bins, float* cnts, bool cyclic)
00505 {
00506 int nbm = n_bins-1;
00507 if (!cyclic)
00508 {
00509 if (bin < 0)
00510 return cnts[0];
00511 if (bin >= n_bins)
00512 return cnts[nbm];
00513 }
00514 else
00515 {
00516 if (bin<0)
00517 return cnts[nbm+bin];
00518 if (bin >= n_bins)
00519 return cnts[bin-n_bins];
00520 }
00521 return cnts[bin];
00522 }
00523
00524
00525
00526
00527
00528 void vifa_histogram::RemoveFlatPeaks(int nbins, float* cnts, bool cyclic)
00529 {
00530 int nbm = nbins-1;
00531
00532
00533
00534 float init=GetExtendedCount(0, nbins, cnts, cyclic);
00535 int init_end =0;
00536
00537
00538 bool start=false;
00539 int start_index=0;
00540
00541
00542 for (int i = 0; i < nbins; i++)
00543 {
00544 float v = GetExtendedCount(i, nbins, cnts, cyclic);
00545
00546
00547 if (init&&v!=0)
00548 continue;
00549
00550 if (init&&v==0)
00551 {
00552 init_end = i;
00553
00554
00555
00556 init = 0;
00557 continue;
00558 }
00559
00560
00561 if (!start&&v==0)
00562 continue;
00563
00564
00565 if (!start&&v!=0)
00566 {
00567 start_index = i;
00568 start = true;
00569 continue;
00570 }
00571
00572 if (start&&v==0)
00573 {
00574 int peak_location = (start_index+i-1)/2;
00575 for (int k = start_index; k<=(i-1); k++)
00576 if (k!=peak_location)
00577 cnts[k] = 0;
00578 start = false;
00579 }
00580 }
00581
00582
00583 if (!cyclic)
00584 {
00585 if (init_end!=0)
00586 {
00587 int init_location = (init_end-1)/2;
00588 for (int k = 0; k<init_end; k++)
00589 if (k!=init_location)
00590 cnts[k] = 0;
00591 }
00592 if (start)
00593 {
00594 int end_location = (start_index + nbm)/2;
00595 for (int k = start_index; k<nbins; k++)
00596 if (k!=end_location)
00597 cnts[k] = 0;
00598 }
00599 }
00600 else
00601 {
00602 if (init_end!=0)
00603 if (start)
00604 {
00605 int peak_location = (start_index + init_end - nbm -1)/2;
00606 int k;
00607 if (peak_location < 0)
00608 {
00609 peak_location += nbm;
00610 for ( k = 0; k< init_end; k++)
00611 cnts[k]=0;
00612 for ( k= start_index; k <nbins; k++)
00613 if (k!=peak_location)
00614 cnts[k] = 0;
00615 }
00616 else
00617 {
00618 for ( k = start_index; k< nbins; k++)
00619 cnts[k]=0;
00620 for ( k= 0; k < init_end; k++)
00621 if (k!=peak_location)
00622 cnts[k] = 0;
00623 }
00624 }
00625 else
00626 {
00627 int init_location = (init_end-1)/2;
00628 for (int k = 0; k<=init_end; k++)
00629 if (k!=init_location)
00630 cnts[k] = 0;
00631 }
00632 }
00633 }
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643 vifa_histogram* vifa_histogram::NonMaximumSupress(int radius, bool cyclic)
00644 {
00645 if ((2*radius +1)> num/2)
00646 {
00647 vcl_cerr << "In vifa_histogram::NonMaximumSupress(): radius is too large\n";
00648 return NULL;
00649 }
00650
00651 vifa_histogram* h_new = new vifa_histogram(*this);
00652 int n_buckets = h_new->GetRes();
00653 float* counts_old = this->GetCounts();
00654
00655
00656 float* counts_new = h_new->GetCounts();
00657 int i;
00658 for ( i =0; i < n_buckets; i++)
00659 counts_new[i] = 0;
00660
00661
00662 for ( i = 0; i< n_buckets; i++)
00663 {
00664
00665 float max_count = counts_old[i];
00666 for (int k = -radius; k <= radius ;k++)
00667 {
00668 int index = i+k;
00669 float c = GetExtendedCount(index, n_buckets, counts_old, cyclic);
00670 if ( c > max_count)
00671 max_count = c;
00672 }
00673
00674 if (max_count == counts_old[i])
00675 counts_new[i] = max_count;
00676 }
00677 RemoveFlatPeaks(n_buckets, counts_new, cyclic);
00678 return h_new;
00679 }
00680
00681
00682
00683
00684 float vifa_histogram::GetMean() const
00685 {
00686 float xsum = 0.0f;
00687 float minv = this->GetMinVal();
00688 float maxv = this->GetMaxVal();
00689 float bucket_size = this->GetBucketSize();
00690
00691 if (MEAN_FLAG & stats_consistent)
00692 return mean;
00693 else
00694 {
00695 if (bucket_size > 0.0f)
00696 {
00697 for (float x=minv; x<=maxv; x+=bucket_size)
00698 xsum += x*GetCount(x);
00699 }
00700 else
00701 {
00702 stats_consistent |= MEAN_FLAG;
00703 mean = (maxv+minv)/2.0f;
00704 return mean;
00705 }
00706
00707 float area = ComputeArea(vmin, vmax);
00708 if (area <= 0.0f)
00709 {
00710 #ifdef DEBUG
00711 vcl_cerr << "vifa_histogram::GetMean() : Area <= 0.0\n\n";
00712 #endif
00713 return 0.0f;
00714 }
00715 else
00716 {
00717 stats_consistent |= MEAN_FLAG;
00718 mean = xsum/area;
00719 return mean;
00720 }
00721 }
00722 }
00723
00724 float vifa_histogram::GetStandardDev() const
00725 {
00726 float sum = 0.0f;
00727 float bucket_size = this->GetBucketSize();
00728
00729 if (SD_FLAG & stats_consistent)
00730 return standard_dev;
00731 else
00732 {
00733 float xm = this -> GetMean();
00734
00735 if ( this->GetBucketSize() > 0.0f)
00736 {
00737 for (float x=this->GetMinVal(); x<= this->GetMaxVal(); x += bucket_size)
00738 sum += (x-xm)*(x-xm)*GetCount(x);
00739 }
00740 else
00741 {
00742 stats_consistent |= SD_FLAG;
00743 standard_dev = 0.0f;
00744 return standard_dev;
00745 }
00746
00747 float area = ComputeArea(vmin, vmax);
00748 if (area <= 0.0f)
00749 {
00750 #ifdef DEBUG
00751 vcl_cerr << "vifa_histogram::GetStandardDev() : Area <= 0.0\n\n";
00752 #endif
00753 return 0.0f;
00754 }
00755 else
00756 {
00757 stats_consistent |= SD_FLAG;
00758 standard_dev = (float)vcl_sqrt(sum/area);
00759 return standard_dev;
00760 }
00761 }
00762 }
00763
00764 float vifa_histogram::GetMedian() const
00765 {
00766
00767 int i = 0;
00768 float num_samps_2 = 0.5f * GetNumSamples();
00769 float num_so_far = 0;
00770 while (num_so_far < num_samps_2)
00771 {
00772 num_so_far += counts[i];
00773 i++;
00774 }
00775
00776 return vals[i];
00777 }
00778
00779 int vifa_histogram::GetIndex(float pixelval) const
00780 {
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791 if ((pixelval > vmax) || (pixelval < vmin))
00792 return -1;
00793
00794
00795
00796 int high = num-1;
00797 int low = 0;
00798
00799 while (high > low)
00800 {
00801
00802 int mid = (high + low - 1) / 2;
00803
00804 if (pixelval <= vals[mid] + 0.5f*delta)
00805 {
00806
00807 high = mid;
00808 }
00809 else
00810 {
00811
00812 low = mid + 1;
00813 }
00814 }
00815
00816
00817 return low;
00818 }
00819
00820 int vifa_histogram::GetValIndex(float pixelval) const
00821 {
00822 if ((pixelval > vmax) || (pixelval < vmin))
00823 return -1;
00824
00825 int idx = 0;
00826
00827 for (int i = 0; i < num; i++)
00828 {
00829 if ((pixelval > (vals[i] - 0.5f * delta)) &&
00830 (pixelval <= (vals[i] + 0.5f * delta)))
00831 {
00832 idx = i;
00833 break;
00834 }
00835 }
00836
00837 return idx;
00838 }
00839
00840 float vifa_histogram::GetCount(float pixelval) const
00841 {
00842 int index = GetIndex(pixelval);
00843 if (index < 0)
00844 return -1;
00845 else
00846 return counts[index];
00847 }
00848
00849 float vifa_histogram::GetMinVal() const
00850 {
00851 register int i=0;
00852 while (i<num-1 && !counts[i])
00853 i++;
00854 return vals[i];
00855 }
00856
00857 float vifa_histogram::GetMaxVal() const
00858 {
00859 register int i=num-1;
00860 while (i>0 && !counts[i])
00861 i--;
00862 if (i < 0)
00863 return 0.0f;
00864 return vals[i];
00865 }
00866
00867 float vifa_histogram::GetMaxCount() const
00868 {
00869 register int i;
00870 float max = 0.0f;
00871
00872 for (i=0; i < num; i++)
00873 {
00874 if (counts[i] > max)
00875 {
00876 max = counts[i];
00877 }
00878 }
00879
00880 return max;
00881 }
00882
00883 float vifa_histogram::SetCount(float pixelval, float count)
00884 {
00885 stats_consistent = 0;
00886
00887 int index = GetIndex(pixelval);
00888
00889 if (index < 0)
00890 return -1;
00891 else
00892 {
00893 counts[index] = count;
00894 return count;
00895 }
00896 }
00897
00898 void vifa_histogram::UpCount(float pixelval, bool useNewIndexMethod)
00899 {
00900 stats_consistent = 0;
00901 int index = -1;
00902 if (useNewIndexMethod)
00903 index = GetValIndex(pixelval);
00904 else
00905 UpCount(pixelval);
00906
00907 if (index >= 0)
00908 counts[index] += 1.0f;
00909 }
00910
00911 void vifa_histogram::UpCount(float pixelval)
00912 {
00913 stats_consistent = 0;
00914 int index = GetIndex(pixelval);
00915 if (index >= 0)
00916 {
00917 counts[index] += 1.0f;
00918 }
00919 }
00920
00921 int vifa_histogram::GetNumSamples() const
00922 {
00923 float num_samps = 0;
00924 for (int i=0; i < num; i++)
00925 {
00926 num_samps += counts[i];
00927 }
00928
00929 return (int)num_samps;
00930 }
00931
00932 float vifa_histogram::ComputeArea(float low, float high) const
00933 {
00934 float maxval = GetMaxVal();
00935 float minval = GetMinVal();
00936
00937 if (low < minval)
00938 low = minval;
00939 if (high > maxval)
00940 high = maxval;
00941
00942 if (low <= high)
00943 {
00944 int indexlow, indexhigh;
00945 indexlow = (int) GetIndex(low);
00946 if (indexlow < 0)
00947 {
00948 if (low < vmin)
00949 indexlow = 0;
00950 else
00951 indexlow = num-1;
00952 }
00953
00954 indexhigh = (int) GetIndex(high);
00955 if (indexhigh < 0)
00956 {
00957 if (high < vmin)
00958 indexhigh = 0;
00959 else
00960 indexhigh = num-1;
00961 }
00962
00963 register int i=indexlow;
00964 float sum = 0.0f;
00965 while (i <= indexhigh)
00966 {
00967 sum += counts[i];
00968 i++;
00969 }
00970
00971 return sum;
00972 }
00973 else
00974 {
00975 return 0.0f;
00976 }
00977 }
00978
00979
00980
00981 float vifa_histogram::ComputeArea() const
00982 {
00983 float vmin = this->GetMinVal();
00984 float vmax = this->GetMaxVal();
00985
00986 if (vmin>vmax)
00987 {
00988 float temp = vmin;
00989 vmin = vmax;
00990 vmax = temp;
00991 }
00992
00993 return this->ComputeArea(vmin, vmax);
00994 }
00995
00996
00997
00998 float vifa_histogram::LowClipVal(float clip_fraction)
00999 {
01000 if (clip_fraction < 0)
01001 clip_fraction = 0.0f;
01002 if (clip_fraction > 1.0f)
01003 clip_fraction = 1.0f;
01004
01005 float area = this->ComputeArea();
01006 if (area == 0.0f)
01007 return this->GetMinVal();
01008
01009 if (clip_fraction == 0.0f)
01010 return this->GetMinVal();
01011 if (clip_fraction == 1.0f)
01012 return this->GetMaxVal();
01013
01014 float clip_area = area*clip_fraction;
01015 float* counts = this->GetCounts();
01016 float* vals = this->GetVals();
01017 int res = this->GetRes();
01018 float sum = 0;
01019 int i=0;
01020 for (; i < res; i++)
01021 {
01022 sum += counts[i];
01023 if (sum >= clip_area)
01024 break;
01025 }
01026
01027 return vals[i];
01028 }
01029
01030
01031
01032 float vifa_histogram::HighClipVal(float clip_fraction)
01033 {
01034 if (clip_fraction < 0)
01035 clip_fraction = 0.0f;
01036 if (clip_fraction > 1.0f)
01037 clip_fraction = 1.0f;
01038
01039 float area = this->ComputeArea();
01040 if (area==0.0f)
01041 return this->GetMaxVal();
01042
01043 if (clip_fraction == 0.0f)
01044 return this->GetMaxVal();
01045 if (clip_fraction == 1.0f)
01046 return this->GetMinVal();
01047
01048 float clip_area = area * clip_fraction;
01049 float* counts = this->GetCounts();
01050 float* vals = this->GetVals();
01051 int res = this->GetRes();
01052 float sum = 0;
01053 int i = (res - 1);
01054 for (; i >= 0; i--)
01055 {
01056 sum += counts[i];
01057 if (sum >= clip_area)
01058 break;
01059 }
01060
01061 return vals[i];
01062 }
01063
01064
01065 void vifa_histogram::Print()
01066 {
01067 float* vals = this->GetVals();
01068 float* counts = this->GetCounts();
01069 int res = this->GetRes();
01070 int width = 0;
01071 for (int j = 0; j < res; j++)
01072 {
01073 if (width >= 5)
01074 {
01075 width = 0;
01076 vcl_cout << vcl_endl;
01077 }
01078 vcl_printf("%6.1f %5.0f |", vals[j], counts[j]);
01079 width++;
01080 }
01081
01082 vcl_cout << vcl_endl << " MaxVal " << this->GetMaxVal() << vcl_endl
01083 << " MinVal " << this->GetMinVal() << vcl_endl
01084 << " BucketSize " << this->GetBucketSize() << vcl_endl
01085 << " Resolution " << this->GetRes() << vcl_endl
01086 << " Area " << this->ComputeArea(this->GetMinVal(),this->GetMaxVal()) << vcl_endl
01087 << "------------------------------------------------\n\n";
01088 }
01089
01090
01091
01092 void vifa_histogram::Dump(char *dumpfile)
01093 {
01094 vcl_ofstream dumpfp(dumpfile, vcl_ios::out);
01095
01096 if (!dumpfp)
01097 {
01098 vcl_cerr << "Error opening histogram data file.\n";
01099 return;
01100 }
01101
01102 for (int i = 0; i < num; i++)
01103 dumpfp << vals[i] << ' ' << counts[i] << vcl_endl;
01104 }
01105
01106
01107
01108 int vifa_histogram::WritePlot(const char *fname)
01109 {
01110 vcl_ofstream fp(fname, vcl_ios::out);
01111
01112 if (!fp)
01113 {
01114 vcl_cerr << "Error opening histogram plot file.\n";
01115 return 0;
01116 }
01117
01118 int stat_res = this->GetRes();
01119
01120 float * x = new float[2*stat_res];
01121 float * y = new float[2*stat_res];
01122
01123 float * temp_x = this->GetVals();
01124 float * temp_y = this->GetCounts();
01125 float delt = this->GetBucketSize();
01126
01127 for (register int i=0; i < stat_res ;i++)
01128 {
01129 x[2*i] = temp_x[i] - 0.5f * delt;
01130 x[2*i+1] = temp_x[i] + 0.5f * delt;
01131 y[2*i] = temp_y[i];
01132 y[2*i+1] = temp_y[i];
01133 }
01134
01135 for (register int j = 0; j < 2*stat_res; j++)
01136 fp << x[j] << delimiter << y[j] << vcl_endl;
01137
01138 delete [] x;
01139 delete [] y;
01140 fp.close();
01141
01142 return 1;
01143 }
01144
01145
01146
01147
01148 float vifa_histogram::CompareToHistogram(vifa_histogram* h)
01149 {
01150
01151 float m1 = this->GetMean();
01152 float m2 = h->GetMean();
01153
01154 float v1 = this->GetStandardDev();
01155 float v2 = h->GetStandardDev();
01156
01157
01158 if ( vcl_fabs(v1) < 1e-6 || vcl_fabs(v2) < 1e-6 ) return 0.0f;
01159 if (m1==0||m2==0) return 0.0f;
01160
01161
01162 return (float)vcl_exp(- vcl_fabs( 0.693 * (m1 - m2) * vcl_sqrt(1.0/(v1*v1) + 1.0/(v2*v2))));
01163 }