Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ColorHistogram.cpp
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 
26 #include "ColorHistogram.hh"
27 #include <Base/ImageUtils/BresenhamCircle.hh>
28 #include <Base/Image/ImageBase.hh>
29 #include <Base/Image/ImageConvert.hh>
30 
31 #include <Base/Common/BIASpragma.hh>
32 
33 using namespace BIAS;
34 using namespace std;
35 
36 namespace BIAS {
37 
38 const float maxShutter = 0.034f;
39 const float minShutter = 0.01f;
40 const float maxGain = 29.0f;
41 const float minGain = 0.1f;
42 
43 
44 
45 /**
46  This class creates a Histogram in the HSL color space.
47  @author ingo schiller
48  @date feb 2004
49  */
50 template<class StorageType>
52 {
53  image_=NULL;
54  histCount_ = 0;
55  binCount_ = 0;
56  expDist_=true;
57  minSat_=10;
58  lambda_=20;
59  binSize_=32;
60  binSizeSat_=64;
61  ux_=uy_=lx_=ly_=0;
62  SetBinSize(binSize_,binSizeSat_);
63 
64 }
65 
66 template<class StorageType>
68 {
69 
70 }
71 
72 
73 //set the region of interest
74 template<class StorageType>
75 int ColorHistogram<StorageType>::SetROI(int ux, int uy, int lx, int ly){
76 
77  ux_=ux;
78  uy_=uy;
79  lx_=lx;
80  ly_=ly;
81 
82  circle_=false;
83 
84  return 0;
85 }
86 
87 //set the region of interest
88 template<class StorageType>
89 int ColorHistogram<StorageType>::SetROI(int x, int y, int r){
90 
91  mx_=x;
92  my_=y;
93  r_=r;
94 
95  circle_=true;
96 
97  return 0;
98 }
99 
100 template<class StorageType>
102  binSize_ = binsize;
103  binSizeSat_=binsize;
104  unsigned int nBins = (unsigned int)(256/binSize_);
105  hist_.resize(nBins);
106  for(unsigned int k=0;k<nBins;k++){
107  hist_[k].resize(nBins);
108  }
109  histl_.resize(nBins);
110 #ifdef BIAS_DEBUG
111  if (binSize_!=4 && binSize_!=8 && binSize_!=16 && binSize_!=32 && binSize_!=64 && binSize_!=128){
112  BIASERR("slow, not supported");
113  BIASABORT
114  }
115 #endif
116  int tmp = binSize_;
117  shift_=-1;
118  while (tmp!=0) {
119  tmp=tmp>>1; shift_++;
120  }
121 
122  shiftSat_ = shift_;
123  //cerr << "binSize_: "<<binSize_<<" shift: "<<shift_<<endl;
124 
125  luminance_.resize(8); // declare fixed binsize for luminace of 32 -> 8 bins
126  shiftLum_=5;
127  return 0;
128 }
129 
130 
131 template<class StorageType>
133  int binSizeSat)
134 {
135  binSize_ = binSizeHue;
136  binSizeSat_ = binSizeSat;
137  unsigned int nBinsHue = (unsigned int)(256/binSize_);
138  unsigned int nBinsSat = (unsigned int)(256/binSizeSat_);
139 
140  hist_.resize(nBinsHue);
141  for(unsigned int k=0;k<nBinsHue;k++){
142  hist_[k].resize(nBinsSat);
143  }
144  histl_.resize(nBinsHue);
145 #ifdef BIAS_DEBUG
146  if (binSize_!=4 && binSize_!=8 && binSize_!=16 && binSize_!=32 && binSize_!=64 && binSize_!=128){
147  BIASERR("slow, not supported");
148  BIASABORT;
149  }
150 #endif
151  int tmp = binSize_;
152  shift_=-1;
153  while (tmp!=0) {
154  tmp=tmp>>1; shift_++;
155  }
156  //set shift for the sat binsize
157  tmp = binSizeSat_;
158  shiftSat_ = -1;
159  while (tmp!=0) {
160  tmp=tmp>>1; shiftSat_++;
161  }
162 
163  //cerr << "binSize_: "<<binSize_<<" binSizeSat: "<<binSizeSat_<<endl;
164  //cerr << "Shift: "<<shift_<<" shiftSat: "<<shiftSat_<<endl;
165 
166  luminance_.resize(8); // declare fixed binsize for luminace of 32 -> 8 bins
167  shiftLum_=5;
168 
169  return 0;
170 
171 }
172 
173 
174 template<class StorageType>
175 std::vector<std::vector<double> > ColorHistogram<StorageType>::GetHist() const
176 {
177  return hist_;
178 }
179 
180 
181 template<class StorageType>
182 std::vector<double> ColorHistogram<StorageType>::GetHistL() const
183 {
184  return histl_;
185 }
186 
187 template<class StorageType>
189 
190  return ly_-uy_;
191 }
192 
193 template<class StorageType>
195 
196  return lx_-ux_;
197 }
198 
199 
200 template<class StorageType>
201 void ColorHistogram<StorageType>::GetROI(std::vector<int>& roi) const
202 {
203  roi.clear();
204  if(circle_){
205  roi.push_back(mx_);
206  roi.push_back(my_);
207  roi.push_back(r_);
208  }else{
209  roi.push_back(ux_);
210  roi.push_back(uy_);
211  roi.push_back(lx_);
212  roi.push_back(ly_);
213  }
214 }
215 
216 
217 
218 
219 template<class StorageType>
221 {
222  expDist_=true;
223  normalised_=false;
224  binCount_=0;
225  histCount_=0;
226  ux_=0;
227  uy_=0;
228  lx_=0;
229  ly_=0;
230  mx_=0;
231  my_=0;
232  r_=0;
233  circle_=false;
234 
235  return 0;
236 }
237 
238 template<class StorageType>
239 int
241  int ux, int uy, int lx, int ly)
242 {
243  ux_=ux;
244  uy_=uy;
245  lx_=lx;
246  ly_=ly;
247 
248  circle_=false;
249 
250  GenerateHist(image);
251  return 0;
252 }
253 
254 template<class StorageType>
255 int
257  int x, int y, int r){
258  mx_=x;
259  my_=y;
260  r_=r;
261 
262  circle_ = true;
263 
264  GenerateCircleHist(image);
265  return 0;
266 }
267 
268 
269 
270 template<class StorageType>
271 int
273 {
274 
275  StorageType *data;
276 
277  if ( (abs(ux_- lx_)==0) | (abs(uy_-ly_)==0) )
278  return 1;
279 
280  //at first test if image is in HSL
281  if (img.GetColorModel()==ImageBase::CM_HSL){
282  image_=&img;
283  } else {
284  BIASERR("GenerateHist() needs an image with HSL Colormodel!");
285  return -1;
286  }
287 
288  DeleteHist_();
289 
290 
291  //go through the picturearray and collect the value and saturation
292  //and set the l-values that are missing
293 
294  StorageType hue=0, sat=0, light=0;
295  StorageType lum=0;
296  data = image_->GetImageData();
297 
298  //go through imagedata and collect infos on colors and lightness
299  int width = image_->GetWidth(); //width of image
300  int step = 3*width-3*lx_+3*ux_; //right part left of image
301  StorageType *p = data+3*ux_+3*width*uy_; //pointer to beginning of ROI
302  StorageType *e = data+3*lx_+3*width*(ly_-1); //pointer to end of ROI
303  StorageType *le = data+3*lx_+3*width*uy_; //pointer to line end
304 
305 
306  //go through the picturearray and collect the value and saturation
307  //and set the l-values that are missing
308 
309  double invbin=1.0/(double)binSize_;
310  double invbinSat=1.0/(double)binSizeSat_;
311  while(p<e){
312  //cerr<<"ALERT!!! IN WHILE p<e!!"<<endl;
313  while(p<le){
314  hue = *p++; //get values and increase pointers
315  sat = *p++;
316 
317  lum = *p;//take the lum but don't increase
318  lum = lum*float(1.0/(double)32);//and then sort into luminacne vector
319  luminance_[(int)floor((float)lum)]+=1;
320 
321  if(sat>minSat_)
322  {
323  //if SAT is >minSat_ put value in hist_
324  sat = sat*float(invbinSat);
325  hue = hue*float(invbin);
326  hist_[(int)floor((float)hue)][(int)floor((float)sat)]+=1;
327  binCount_++;//increase bincount for the normalisation
328  p++;//increase pointer because it's not done in else case
329  }
330  else {
331  //build the array for the L-values here
332  light = *p++; //get value
333  light = light*float(invbin);
334  histl_[(int)floor((float)light)]+=1;
335  //also increase bincount if in histl_
336  binCount_++;
337 
338  }
339  }
340  le+=3*width;
341  p+=step;
342  }
343 
344  Normalise_();
345 
346  return 0;
347 }
348 
349 template<>
350 int
352 {
353  unsigned char *data;
354  // cout<<"ColorHistogram GenerateHist binsizeHue :"<<binSize_<<endl;
355  // cout<<"ColorHistogram GenerateHist binsizeSat :"<<binSizeSat_<<endl;
356 
357  if ( (abs(ux_- lx_)==0) | (abs(uy_-ly_)==0) )
358  return 1;
359 
360  //at first test if image is in HSL
361  if (img.GetColorModel()==ImageBase::CM_HSL){
362  image_=&img;
363  } else {
364  BIASERR("GenerateHist() needs an image with HSL Colormodel!");
365  return -1;
366  }
367 
368  DeleteHist_();
369 
370  data = image_->GetImageData();
371 
372  //go through imagedata and collect infos on colors and lightness
373  int width = image_->GetWidth(); //width of image
374  int step = 3*width-3*lx_+3*ux_; //right part left of image
375  unsigned char *p = data+3*ux_+3*width*uy_; //pointer to beginning of ROI
376  unsigned char *e = data+3*lx_+3*width*(ly_-1); //pointer to end of ROI
377  unsigned char *le = data+3*lx_+3*width*uy_; //pointer to line end
378 
379 
380  //go through the picturearray and collect the value and saturation
381  //and set the l-values that are missing
382 
383  unsigned char hue=0, sat=0, light=0;
384  unsigned char lum=0;
385 
386  while(p<e){
387  //cerr<<"ALERT!!! IN WHILE p<e!!"<<endl;
388  while(p<le){
389  hue = *p++; //get values and increase pointers
390  sat = *p++;
391  lum = *p;//take the lum but don't increase
392  lum = lum>>shiftLum_;;//and then sort into luminacne vector
393  luminance_[lum]+=1;
394 
395  if(sat>minSat_)
396  {
397  //if SAT is >minSat_ put value in hist_
398  sat = sat>>shiftSat_;
399  hue = hue>>shift_;
400  hist_[hue][sat]+=1;
401  binCount_++;//increase bincount for the normalisation
402  p++;//increase pointer because it's not done in else case
403  }
404  else {
405  //build the array for the L-values here
406  light = *p++; //get value
407  light = light>>shift_;
408  histl_[light]+=1;
409  //also increase bincount if in histl_
410  binCount_++;
411 
412  }
413  }
414  le+=3*width;
415  p+=step;
416  }
417 
418  Normalise_();
419 
420  return 0;
421 }
422 
423 template<class StorageType>
424 int
426  // Clear the histogram
427  DeleteHist_();
428 
429 
430  // Initialize the Bresenham Algorithm
431  int height, width;
432  int mp[2] = {mx_,my_};
433  int next[2] = {0,0};
434  BresenhamCircle circle = BresenhamCircle(mp,r_);
435 
436  //at first test if image is in HSL
437  if (img.GetColorModel()==ImageBase::CM_HSL){
438  image_=&img;
439  } else {
440  BIASERR("GenerateHist() needs an image with HSL Colormodel!");
441  return -1;
442  }
443 
444  // Initialize field for setting the histogram
445  StorageType hue=0, sat=0, light=0;
446  StorageType lum=0;
447  StorageType **data = image_->GetImageDataArray();
448  unsigned int cc = image_->GetChannelCount();
449  height = image_->GetHeight();
450  width = image_->GetWidth();
451 
452 
453  // check, if the range of the circle is completly in the image area
454  if( (mx_-r_<0) && (my_-r_<0) && (mx_+r_>width) && (my_+r_>height)){
455  BIASERR ("The range of the circle needs to be completly in the image.");
456  return -1;
457  }
458 
459 
460 
461  //go through the picturearray and collect the value and saturation
462  //and set the l-values that are missing
463 
464  double invbin=1.0/(double)binSize_;
465  double invbinSat=1.0/(double)binSizeSat_;
466 
467  while (circle.GetNext(next)){
468  lum = data[next[1]][next[0]*cc+2];
469  lum = lum*float(1.0/(double)32);//and then sort into luminacne vector
470  luminance_[(int)floor((float)lum)]+=1;
471  if (sat>minSat_){
472  hue = data[next[1]][next[0]*cc+0];
473  sat = data[next[1]][next[0]*cc+1];
474  hue = hue*float(invbin);
475  sat = sat*float(invbinSat);
476  hist_[(int)floor((float)hue)][(int)floor((float)sat)]+=1;
477  binCount_++;//increase bincount for the normalisation
478  }else{
479  //build the array for the L-values here
480  light = data[next[1]][next[0]*cc+2]; //get value
481  light = light*float(invbin);
482  histl_[(int)floor((float)light)]+=1;
483  binCount_++;//also increase bincount if in histl_
484  }
485  }
486 
487  Normalise_();
488 
489  return 0;
490 }
491 
492 template<>
493 int
495  // Clear the histogram
496  DeleteHist_();
497 
498  // Initialize the Bresenham Algorithm
499  int height, width;
500  int mp[2] = {mx_,my_};
501  int next[2] = {0,0};
502  BresenhamCircle circle = BresenhamCircle(mp,r_);
503 
504  //at first test if image is in HSL
505  if (img.GetColorModel()==ImageBase::CM_HSL){
506  image_=&img;
507  } else {
508  BIASERR("GenerateHist() needs an image with HSL Colormodel!");
509  return -1;
510  }
511 
512  // Initialize field for setting the histogram
513  unsigned char hue=0, sat=0, light=0;
514  unsigned char lum=0;
515  unsigned char **data = image_->GetImageDataArray();
516  unsigned int cc = image_->GetChannelCount();
517  height = image_->GetHeight();
518  width = image_->GetWidth();
519 
520 
521  // check, if the range of the circle is completly in the image area
522  if( (mx_-r_<0) && (my_-r_<0) && (mx_+r_>width) && (my_+r_>height)){
523  BIASERR ("The range of the circle needs to be completly in the image.");
524  return -1;
525  }
526 
527  //go through the picturearray and collect the value and saturation
528  //and set the l-values that are missing
529 
530  double invbin=1.0/(double)binSize_;
531  double invbinSat=1.0/(double)binSizeSat_;
532 
533  while (circle.GetNext(next)){
534  lum = data[next[1]][next[0]*cc+2];
535  //and then sort into luminacne vector
536  lum = (unsigned char)(float(lum)*(1.0f/32.0f));
537  luminance_[(int)floor((float)lum)]+=1;
538  if (sat>minSat_){
539  hue = data[next[1]][next[0]*cc+0];
540  sat = data[next[1]][next[0]*cc+1];
541  hue = (unsigned char)(double(hue)*invbin);
542  sat = (unsigned char)(double(sat)*invbinSat);
543  hist_[(int)floor((float)hue)][(int)floor((float)sat)]+=1;
544  binCount_++;//increase bincount for the normalisation
545  }else{
546  //build the array for the L-values here
547  light = data[next[1]][next[0]*cc+2]; //get value
548  light = (unsigned char)(double(light)*invbin);
549  histl_[(int)floor((float)light)]+=1;
550  binCount_++;//also increase bincount if in histl_
551  }
552  }
553 
554  Normalise_();
555 
556  return 0;
557 }
558 
559 
560 template<class StorageType>
562 {
563  double dist=0; //indicator for similarity
564  int nBins = 256/binSize_;
565  int nBinsSat = 256/binSizeSat_;
566  //sum up the sqrt of the product of q*(n)and q(n;x) over all bins
567  for(int i=0;i<nBins;i++){
568  dist += sqrt(histl_[i]*chist.histl_[i]);
569  for(int j=0;j<nBinsSat;j++){
570  dist += sqrt(hist_[i][j]*chist.hist_[i][j]);
571  }
572  }
573  //new
574  if(!expDist_)
575  dist = sqrt(1-dist);
576  else
577  dist = exp(-lambda_*(1-dist));
578 
579  /* old
580  if(expDist_)
581  dist = exp(-lambda_*(1-dist));
582  */
583  // cout<<"CalcSimilarity, dist: "<<dist<<endl;
584  return dist;
585 }
586 
587 template<class StorageType>
589 {
590  double dist=0; //indicator for similarity
591  weight=0;
592  int nBins = 256/binSize_;
593  int nBinsSat = 256/binSizeSat_;
594  //sum up the sqrt of the product of q*(n)and q(n;x) over all bins
595  for(int i=0;i<nBins;i++){
596  if (histl_[i]!=0) {
597  weight++;
598  if (chist.histl_[i]!=0)
599  dist += sqrt(histl_[i]*chist.histl_[i]);
600  }
601  for(int j=0;j<nBinsSat;j++){
602  if (hist_[i][j]!=0) {
603  weight++;
604  if (chist.hist_[i][j]!=0)
605  dist += sqrt(hist_[i][j]*chist.hist_[i][j]);
606  }
607  }
608  }
609 
610  //new
611  if(!expDist_)
612  dist = sqrt(1-dist);
613  else
614  dist = exp(-lambda_*(1-dist));
615 
616  /* old
617  if(expDist_)
618  dist = exp(-lambda_*(1-dist));
619  */
620 
621 
622  weight /= (256.0/(double)binSize_) * (256.0/(double)binSize_);
623  return dist;
624 }
625 
626 template<class StorageType>
627 int
629  double factor)
630 {
631 #ifdef BIAS_DEBUG
632  if (hist.binSize_!=binSize_) {
633  BIASERR("can't update , beause histogramms have different binSize");
634  return -1;
635  }
636 #endif
637 
638  //update the size
639  ux_= int((double)ux_*(1.0-factor)+factor*(double)hist.ux_ + 0.5);
640  uy_= int((double)uy_*(1.0-factor)+factor*(double)hist.uy_ + 0.5);
641  lx_= int((double)lx_*(1.0-factor)+factor*(double)hist.lx_ + 0.5);
642  ly_= int((double)ly_*(1.0-factor)+factor*(double)hist.ly_ + 0.5);
643 
644  int nBins = 256/binSize_;
645  int nBinsSat = 256/binSizeSat_;
646 
647  // update bins
648  for(int i=0;i<nBins;i++){
649  histl_[i]= histl_[i]*(1.0-factor) + factor * hist.histl_[i];
650  for(int j=0;j<nBinsSat;j++){
651  hist_[i][j] = hist_[i][j]*(1.0-factor) + factor * hist.hist_[i][j];
652  }
653  }
654  return 0;
655 }
656 
657 
658 template<class StorageType> int ColorHistogram<StorageType>::
660  float percent,
661  float &shutter,
662  float &gain)
663 {
664  int ret =0;
665  float shutterstep = 0.001f;
666  float gainstep = 0.1f;
667  double lowerLum =luminance_[0]+luminance_[1];
668  double higherLum = luminance_[6]+luminance_[7];
669 
670  double lowerLumRef = cHist.luminance_[0]+cHist.luminance_[1];
671  double higherLumRef = cHist.luminance_[6]+cHist.luminance_[7];
672  // cout<<"LowerLum :"<<lowerLum<<" LowerLumRef :"<<lowerLumRef<<endl;
673  // cout<<"HigherLum :"<<higherLum<<" HigherLumRef :"<<higherLumRef<<endl;
674 
675  if((lowerLum - lowerLumRef) > percent)
676  {
677  if(shutter + shutterstep < maxShutter)
678  {
679  shutter += shutterstep;
680  // cout<<"Increasing shutter, lum too low"<<endl;
681  }
682  else
683  {
684  if(gain + gainstep < maxGain )
685  {
686  gain += gainstep;
687  // cout<<"Increasing gain, lum too low and shutter already max"<<endl;
688  }
689  else{}
690  //cout<<"All max it is to dark to play outside"<<endl;
691  }
692  ret = 1;
693  }
694  else if((higherLum - higherLumRef) > percent)
695  {
696  if(gain - gainstep > minGain + gainstep)
697  {
698  gain -= gainstep;
699  //cout<<"Decreasing gain, lum too high and gain not min"<<endl;
700  }
701  else if(shutter - shutterstep > minShutter)
702  {
703  shutter -= shutterstep;
704  // cout<<"Decreasing shutter, lum too high"<<endl;
705  }
706  else
707  {
708  //cout<<"All min, high risk of sunburn"<<endl;
709  }
710  ret = -1;
711  }
712  else {
713  // cout<<"Light is good, no need to change"<<endl;
714  }
715 
716  return ret;
717 }
718 
719 
720 
721 
722 template<class StorageType>
724  float &shutter,
725  float &gain)
726 {
727  double lowerLum =luminance_[0]+luminance_[1];
728  double higherLum = luminance_[6]+luminance_[7];
729  int ret =0;
730  if(lowerLum > percent)
731  {
732  //cout<<"Luminance is low: increase!"<<endl;
733  shutter = 1;
734  ret = 1;
735  }
736  else if(higherLum > percent)
737  {
738  //cout<<"Luminance is high: decrease!"<<endl;
739  shutter = -1;
740  ret = -1;
741  }
742  else
743  {
744  //cout<<"Luminace is good, no need to modify"<<endl;
745  }
746  return ret;
747 }
748 
749 
750 template<class StorageType>
752  float &shutter,
753  float &gain)
754 {
755  std::vector<double> vHistL = GetHistL();
756 
757  if(GetBinSize() == 32)
758  {
759 
760  double lowerLum =vHistL[0]+vHistL[1]+vHistL[2]+vHistL[3];
761  double higherLum = vHistL[5]+vHistL[6]+vHistL[7];
762 
763  if(lowerLum > percent)
764  {
765  cout<<"Luminance is low: increase!"<<endl;
766  shutter = 1;
767  return 1;
768  }
769  else if(higherLum > percent)
770  {
771  cout<<"Luminance is high: decrease!"<<endl;
772  shutter = -1;
773  return -1;
774  }
775  else
776  {
777  cout<<"Luminace is good, no need to modify"<<endl;
778  return 0;
779  }
780  }
781  else
782  {
783  BIASERR("Only implemented for binSizeHue==8");
784  return -1;
785  }
786 
787  //return 0;
788 }//end CheckImageQuality
789 
790 /**
791  dumps information on histogram to ostream
792  format:
793  binsize tab ux tab uy tab lx tab ly
794  hs histogram, as a matrix with binsize x binsize (tab separated)
795  l values as a line with lenght binsize (tab separated)
796 */
797 template<class StorageType>
799 {
800  int nBins = 256/binSize_;
801  int nBinsSat = 256/binSizeSat_;
802 
803  for(int i=0;i<nBins;i++){
804  for(int j=0;j<nBinsSat;j++){
805  os <<hist_[i][j]<<",";
806  }
807  os <<endl;
808  }
809  os<<endl; //create empty line
810  //luminance
811  for(int i=0;i<nBins;i++){
812  os <<histl_[i]<<",";
813  }
814 
815  //complete luminance
816  os <<endl<<endl;
817  for(int i=0;i<8;i++){
818  os <<luminance_[i]<<",";
819  }
820 }
821 
822 /**
823  dumps information on histogram to ostream
824  format:
825  binsize tab ux tab uy tab lx tab ly
826  hs histogram, as a matrix with binsize x binsize (tab separated)
827  l values as a line with lenght binsize (tab separated)
828 */
829 template<class StorageType>
830 void ColorHistogram<StorageType>::Dump(std::ostream& os)
831 {
832  int nBins = 256/binSize_;
833  int nBinsSat = 256/binSizeSat_;
834 
835  if(circle_){
836  os<<binSize_<<"\t"<<binSizeSat_<<"\t"<<mx_<<
837  "\t"<<my_<<"\t"<<r_<<"\t"<<(-1)<<endl;
838  }else{
839  os<<binSize_<<"\t"<<binSizeSat_<<"\t"<<ux_<<
840  "\t"<<uy_<<"\t"<<lx_<<"\t"<<ly_<<endl;
841  }
842 
843  for(int i=0;i<nBins;i++){
844  for(int j=0;j<nBinsSat;j++){
845  os <<hist_[i][j]<<"\t";
846  }
847  os <<endl;
848  }
849  os<<endl; //create empty line
850 
851  for(int i=0;i<nBins;i++){
852  os <<histl_[i]<<"\t";
853  }
854  //create empty line
855  os <<endl<<endl;
856  for(int i=0;i<8;i++){
857  os <<luminance_[i]<<"\t";
858  }
859 
860  os <<endl<<endl;
861  os <<binCount_<<endl;
862 }
863 
864 template<class StorageType>
866 {
867 
868  return 6 + (256/binSize_)*(256/binSizeSat_) + 2*(256/binSize_) +1;
869 }
870 
871 
872 
873 
874 //reads the information of a histogram from disk
875 template<class StorageType>
876 int ColorHistogram<StorageType>::Read(const char *filename)
877 {
878  cout<<"Reading the histogram"<<endl;
879  ifstream histofile(filename);
880  if (!histofile){
881  cerr << "unable to open " << filename<< endl;
882  perror("");
883  return -1;
884  }
885  int binSize,binSizeSat,ux,uy,lx,ly;
886 
887  histofile >> binSize;
888  histofile >> binSizeSat;
889  histofile >> ux >> uy >> lx >> ly;
890  SetBinSize(binSize,binSizeSat);
891  if(ly <0){
892  SetROI(ux,uy,lx);
893  }else{
894  SetROI(ux,uy,lx,ly);
895  }
896  int nBins = 256/binSize_;
897  int nBinsSat = 256/binSizeSat_;
898  for(int i=0;i<nBins;i++){
899  for(int j=0;j<nBinsSat;j++){
900  histofile >> hist_[i][j];
901  }
902  }
903 
904  //And now the L-vector
905  for(int i=0;i<nBins;i++){
906  histofile >> histl_[i];
907 
908  }
909 
910  for(int i=0;i<8;i++){
911  histofile >> luminance_[i];
912 
913  }
914 
915 
916  return 0;
917 }
918 
919 
920 template<class StorageType>
922 {
923  //go through whole vector and divide by binCount_
924  const int end=256>>shift_;
925  const int endSat=256>>shiftSat_;
926  const int endLum=256>>shiftLum_;
927 
928 
929  for(int i=0;i<end;i++){
930  histl_[i]/=binCount_;
931  for(int j=0;j<endSat;j++){
932  hist_[i][j] /=binCount_;
933  }
934  }
935  //normalise luminance as well
936  for(int k=0;k<endLum;k++)
937  {
938  luminance_[k]/=binCount_;
939  }
940 
941  normalised_=true;
942 }
943 
944 
945 template<class StorageType>
947 {
948  binCount_=0;
949  histCount_=0;
950  histl_.assign(histl_.size(),0);
951  for (unsigned int i=0;i<hist_.size();i++) {
952  hist_[i].assign(hist_.size(),0);
953  }
954 
955  return 0;
956 }
957 
958 template<class StorageType>
960 {
961  const int end=256>>shift_;
962  const int endSat=256>>shiftSat_;
963  float count=0;
964  for(int i=0;i<end;i++){
965  for(int j=0;j<endSat;j++){
966  if (hist_[i][j]!=0) count++;
967  }
968  }
969  count/=float(end*endSat);
970  return count;
971 }
972 
973 
974 template<class StorageType>
976  int dataLength= sizeof(double) * (hist_.size()*hist_[0].size() + histl_.size()*2)
977  + 7*sizeof(int);
978 
979  char *ptr = new char[dataLength];
980  int *tmp_int_ptr=(int *)ptr;
981  *tmp_int_ptr++ = binSize_;
982  *tmp_int_ptr++ = binSizeSat_;
983  *tmp_int_ptr++ = ux_;
984  *tmp_int_ptr++ = uy_;
985  *tmp_int_ptr++ = lx_;
986  *tmp_int_ptr++ = ly_;
987  *tmp_int_ptr++ = binCount_;
988 
989  length += 7*sizeof(int);
990  int numSat = 256/binSizeSat_;
991  int numHue = 256/binSize_;
992 
993 
994  double *tmp_ptr=(double*)tmp_int_ptr;
995  for (int h=0; h<numHue; h++) {
996  for (int s=0; s<numSat; s++){
997  *tmp_ptr++ = hist_[h][s];
998  length+=sizeof(double);
999  }
1000  }
1001  for(int l=0;l<numHue;l++){
1002  *tmp_ptr++ = histl_[l]; length+=sizeof(double);}
1003 
1004 
1005  for(int t=0;t<numHue;t++){
1006  *tmp_ptr++ = luminance_[t]; length+=sizeof(double);}
1007 
1008  return ptr;
1009 }
1010 
1011 template<class StorageType>
1013 {
1014 
1015  int *tmp_int_ptr =(int *)data;
1016  binSize_ = *tmp_int_ptr++;
1017  binSizeSat_ = *tmp_int_ptr++;
1018  ux_ = *tmp_int_ptr++;
1019  uy_ = *tmp_int_ptr++;
1020  lx_ = *tmp_int_ptr++;
1021  ly_ = *tmp_int_ptr++;
1022  binCount_ = *tmp_int_ptr++;
1023 
1024  double *tmp_ptr=(double*)tmp_int_ptr;
1025 
1026  SetBinSize(binSize_,binSizeSat_);
1027  SetROI(ux_,uy_,lx_,ly_);
1028  int nBins = 256/binSize_;
1029  int nBinsSat = 256/binSizeSat_;
1030  for(int i=0;i<nBins;i++){
1031  for(int j=0;j<nBinsSat;j++){
1032  hist_[i][j] = *tmp_ptr++;
1033  }
1034  }
1035 
1036  //And now the L-vector
1037  for(int i=0;i<nBins;i++){
1038  histl_[i] = *tmp_ptr++;
1039  }
1040 
1041  for(int i=0;i<nBins;i++){
1042  luminance_[i] = *tmp_ptr++;
1043  }
1044 
1045 }
1046 
1047 
1048 #define INST(type) template class ColorHistogram<type>;
1049 
1050 INST(float)
1051 INST(unsigned char)
1052 
1053  // disabled untested instances, myriards of warnings
1054 
1055 // #ifdef BUILD_IMAGE_INT
1056 // INST(int);
1057 // #endif
1058 // #ifdef BUILD_IMAGE_CHAR
1059 // INST(char);
1060 // #endif
1061 // #ifdef BUILD_IMAGE_SHORT
1062 // INST(short);
1063 // #endif
1064 // #ifdef BUILD_IMAGE_USHORT
1065 // INST(unsigned short);
1066 // #endif
1067 // #ifdef BUILD_IMAGE_USHORT
1068 // INST(unsigned int);
1069 // #endif
1070 // #ifdef BUILD_IMAGE_DOUBLE
1071 // INST(double);
1072 // #endif
1073 
1074 } // namespace BIAS
std::vector< std::vector< double > > GetHist() const
return the histogram with H&amp;S values
int Update(const BIAS::ColorHistogram< StorageType > &hist, double factor=0.5)
Updates the histogramm with values from hist, where the factor gives the weighting of the new value...
int GenerateCircleHist(BIAS::Image< StorageType > &image, int x, int y, int r)
calcluates the cirlce formed histogram from data and adds them to the internal data structures ...
This Class handels Histogram matters on Images.
char * GetBinaryData(int &length)
int CheckImageQualityRef(ColorHistogram< StorageType > &cHist, float percent, float &shutter, float &gain)
same as above but checks similarity of luminance to a given reference histogram
HSL, similar to HSV but space is a double tipped cone.
Definition: ImageBase.hh:147
std::vector< double > luminance_
int CheckImageQuality(float percent, float &shutter, float &gain)
checks the image quality depending on the given Histogram and increases ,decreases shutter and gain ...
Scans a circle using Bresenham&#39;s integer arithmetic algorithm.
std::vector< double > histl_
int SetROI(int ux, int uy, int lx, int ly)
set the coords for the ROI
void ReadBinaryData(char *data)
void GetROI(std::vector< int > &roi) const
std::vector< double > GetHistL() const
return the L-values of the HSLcolorspace that are &lt;MINSAT in the ROI
double CalcSimilarity(const BIAS::ColorHistogram< StorageType > chist) const
Calculates the Bhattacharyya similarity Coeiffient^2 which is the distance or difference of 2 colorhi...
float GetSaturatedBins() const
returns the percentage [0..1] of HS-bins in the histogram that have values unequal to zero ...
void Dump(std::ostream &os=std::cout)
dumps information on histogram
int DeleteHist_()
deletes hist_, histl_...
int GenerateHist(BIAS::Image< StorageType > &image, int ux, int uy, int lx, int ly)
calcluates the histogram from data and adds them to the internal data structures
int Clear()
Deletes current Histogram information.
int CheckImageQualityComplete(float percent, float &shutter, float &gain)
same as above but luminance vector is created form all pixels in histogram
int GetNumberOfEntries()
this calculates of binsize, binsizesat (1 each) coords (4) the matrix (nrofbinssat * nrofbins) lvecto...
int SetBinSize(int binsize)
set the binsize (must be divideable by 2pown)
bool GetNext(int next[2])
Returns the coordinate of the next point on the circle.
const float minShutter
INST(unsigned char)
The image template class for specific storage types.
Definition: Image.hh:78
const float minGain
ColorHistogram()
std Con-/Destructor
enum EColorModel GetColorModel() const
Definition: ImageBase.hh:407
const float maxGain
const float maxShutter
std::vector< std::vector< double > > hist_
int Read(const char *filename)
reads a histogram from instream and fills the internal data structures
void DumpCSV(std::ostream &os=std::cout)
dumps information on histogram to ostream format: binsize tab ux tab uy tab lx tab ly hs histogram...
void Normalise_()
Normalizes the histogram to be able to use it in the Bhattacharyya...