[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

multi_histogram.hxx VIGRA

1 /************************************************************************/
2 /* */
3 /* Copyright 2002-2003 by Ullrich Koethe, Hans Meine */
4 /* */
5 /* This file is part of the VIGRA computer vision library. */
6 /* The VIGRA Website is */
7 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
8 /* Please direct questions, bug reports, and contributions to */
9 /* ullrich.koethe@iwr.uni-heidelberg.de or */
10 /* vigra@informatik.uni-hamburg.de */
11 /* */
12 /* Permission is hereby granted, free of charge, to any person */
13 /* obtaining a copy of this software and associated documentation */
14 /* files (the "Software"), to deal in the Software without */
15 /* restriction, including without limitation the rights to use, */
16 /* copy, modify, merge, publish, distribute, sublicense, and/or */
17 /* sell copies of the Software, and to permit persons to whom the */
18 /* Software is furnished to do so, subject to the following */
19 /* conditions: */
20 /* */
21 /* The above copyright notice and this permission notice shall be */
22 /* included in all copies or substantial portions of the */
23 /* Software. */
24 /* */
25 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
26 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
27 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
28 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
29 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
30 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
31 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
32 /* OTHER DEALINGS IN THE SOFTWARE. */
33 /* */
34 /************************************************************************/
35 
36 #ifndef VIGRA_MULTI_HISTOGRAMM_HXX
37 #define VIGRA_MULTI_HISTOGRAMM_HXX
38 
39 #include "multi_array.hxx"
40 #include "tinyvector.hxx"
41 #include "multi_gridgraph.hxx"
42 #include "multi_convolution.hxx"
43 
44 
45 namespace vigra{
46 
47 
48  template< unsigned int DIM , class T_DATA ,unsigned int CHANNELS, class T_HIST >
49  void multi_gaussian_histogram(
50  const MultiArrayView<DIM, TinyVector<T_DATA,CHANNELS> > & image,
51  const TinyVector<T_DATA,CHANNELS> minVals,
52  const TinyVector<T_DATA,CHANNELS> maxVals,
53  const size_t bins,
54  const float sigma,
55  const float sigmaBin,
56  MultiArrayView<DIM+2 , T_HIST> histogram
57  ){
59  typedef typename Graph::NodeIt graph_scanner;
60  typedef typename Graph::Node Node;
61  typedef T_HIST ValueType;
62  typedef TinyVector<ValueType,CHANNELS> ChannelsVals;
63  typedef typename MultiArrayView<DIM+2 , T_HIST>::difference_type HistCoord;
64  const Graph g(image.shape());
65  const ChannelsVals nBins(bins);
66  histogram.init(1.0);
67  // iterate over all nodes (i.e. pixels)
68  for (graph_scanner n(g); n != lemon::INVALID; ++n){
69  const Node node(*n);
70  ChannelsVals binIndex = image[node];
71  binIndex -=minVals;
72  binIndex /=maxVals;
73  binIndex *=nBins;
74  HistCoord histCoord;
75  for(size_t d=0;d<DIM;++d){
76  histCoord[d]=node[d];
77  }
78  for(size_t c=0;c<CHANNELS;++c){
79  const float fi = binIndex[c];
80  const size_t bi = std::floor(fi+0.5);
81  histCoord[DIM]=std::min(bi,static_cast<size_t>(bins-1));
82  histCoord[DIM+1]=c;
83  histogram[histCoord]+=1.0;
84  }
85  }
86 
87  MultiArray<DIM+2 , T_HIST> histogramBuffer(histogram);
88  Kernel1D<float> gauss,gaussBin;
89  gauss.initGaussian(sigma);
90  gaussBin.initGaussian(sigmaBin);
91  for(size_t c=0;c<CHANNELS;++c){
92 
93  // histogram for one channel
94  MultiArrayView<DIM+1,T_HIST> histc = histogram.bindOuter(c);
95  MultiArrayView<DIM+1,T_HIST> histcBuffer = histogram.bindOuter(c);
96 
97  // convolve along all spatial axis and bin axis
98  // - refactor me
99  if(DIM==2){
100  convolveMultiArrayOneDimension(srcMultiArrayRange(histc), destMultiArray(histcBuffer), 0, gauss);
101  convolveMultiArrayOneDimension(srcMultiArrayRange(histcBuffer), destMultiArray(histc), 1, gauss);
102  convolveMultiArrayOneDimension(srcMultiArrayRange(histc), destMultiArray(histcBuffer), 2, gaussBin);
103  histc=histcBuffer;
104  }
105  else if(DIM==3){
106  convolveMultiArrayOneDimension(srcMultiArrayRange(histc), destMultiArray(histcBuffer), 0, gauss);
107  convolveMultiArrayOneDimension(srcMultiArrayRange(histcBuffer), destMultiArray(histc), 1, gauss);
108  convolveMultiArrayOneDimension(srcMultiArrayRange(histc), destMultiArray(histcBuffer), 2, gauss);
109  convolveMultiArrayOneDimension(srcMultiArrayRange(histcBuffer), destMultiArray(histc), 3, gaussBin);
110  histc=histcBuffer;
111  }
112  else if(DIM==4){
113  convolveMultiArrayOneDimension(srcMultiArrayRange(histc), destMultiArray(histcBuffer), 0, gauss);
114  convolveMultiArrayOneDimension(srcMultiArrayRange(histcBuffer), destMultiArray(histc), 1, gauss);
115  convolveMultiArrayOneDimension(srcMultiArrayRange(histc), destMultiArray(histcBuffer), 2, gauss);
116  convolveMultiArrayOneDimension(srcMultiArrayRange(histcBuffer), destMultiArray(histc), 3, gauss);
117  convolveMultiArrayOneDimension(srcMultiArrayRange(histc), destMultiArray(histcBuffer), 4, gaussBin);
118  histc=histcBuffer;
119  }
120  else{
121  throw std::runtime_error("not yet implemented for arbitrary dimension");
122  }
123  }
124 
125 
126  }
127 
128  template< unsigned int DIM , class T_DATA, class T_HIST >
129  void multi_gaussian_co_histogram(
130  const MultiArrayView<DIM, T_DATA > & imageA,
131  const MultiArrayView<DIM, T_DATA > & imageB,
132  const TinyVector<T_DATA,2> & minVals,
133  const TinyVector<T_DATA,2> & maxVals,
134  const TinyVector<int,2> & nBins,
135  const TinyVector<float,3> & sigma,
136  MultiArrayView<DIM+2, T_HIST> histogram
137  ){
139  typedef typename Graph::NodeIt graph_scanner;
140  typedef typename Graph::Node Node;
141  typedef typename MultiArrayView<DIM+2 , T_HIST>::difference_type HistCoord;
142  const Graph g(imageA.shape());
143  histogram.init(0.0);
144  // iterate over all nodes (i.e. pixels)
145  for (graph_scanner n(g); n != lemon::INVALID; ++n){
146 
147  const Node node(*n);
148  T_DATA binIndexA = imageA[node];
149  T_DATA binIndexB = imageA[node];
150 
151  binIndexA -=minVals[0];
152  binIndexA /=maxVals[0];
153  binIndexA *=nBins[0];
154 
155  binIndexB -=minVals[1];
156  binIndexB /=maxVals[1];
157  binIndexB *=nBins[1];
158 
159  HistCoord histCoord;
160  for(size_t d=0;d<DIM;++d)
161  histCoord[d]=node[d];
162 
163  histCoord[DIM]=binIndexA;
164  histCoord[DIM+1]=binIndexB;
165 
166  const float fiA = binIndexA;
167  const unsigned int biA = std::floor(fiA+0.5);
168  const float fiB = binIndexB;
169  const unsigned int biB = std::floor(fiA+0.5);
170  histCoord[DIM]=std::min(biA,static_cast<unsigned int>(nBins[0]-1));
171  histCoord[DIM+1]=std::min(biB,static_cast<unsigned int>(nBins[1]-1));
172  histogram[histCoord]+=1.0;
173 
174  }
175 
176  MultiArray<DIM+2 , T_HIST> histogramBuffer(histogram);
177  Kernel1D<float> gaussS,gaussA,gaussB;
178  gaussS.initGaussian(sigma[0]);
179  gaussA.initGaussian(sigma[1]);
180  gaussB.initGaussian(sigma[2]);
181 
182  if(DIM==2){
183  convolveMultiArrayOneDimension(srcMultiArrayRange(histogram), destMultiArray(histogramBuffer), 0, gaussS);
184  convolveMultiArrayOneDimension(srcMultiArrayRange(histogramBuffer), destMultiArray(histogram), 1, gaussS);
185  convolveMultiArrayOneDimension(srcMultiArrayRange(histogram), destMultiArray(histogramBuffer), 2, gaussA);
186  convolveMultiArrayOneDimension(srcMultiArrayRange(histogramBuffer), destMultiArray(histogram), 3, gaussB);
187  }
188  else if(DIM==3){
189  convolveMultiArrayOneDimension(srcMultiArrayRange(histogram), destMultiArray(histogramBuffer), 0, gaussS);
190  convolveMultiArrayOneDimension(srcMultiArrayRange(histogramBuffer), destMultiArray(histogram), 1, gaussS);
191  convolveMultiArrayOneDimension(srcMultiArrayRange(histogram), destMultiArray(histogramBuffer), 2, gaussS);
192  convolveMultiArrayOneDimension(srcMultiArrayRange(histogramBuffer), destMultiArray(histogram), 3, gaussA);
193  convolveMultiArrayOneDimension(srcMultiArrayRange(histogram), destMultiArray(histogramBuffer), 4, gaussB);
194  histogram=histogramBuffer;
195  }
196  else if(DIM==4){
197  convolveMultiArrayOneDimension(srcMultiArrayRange(histogram), destMultiArray(histogramBuffer), 0, gaussS);
198  convolveMultiArrayOneDimension(srcMultiArrayRange(histogramBuffer), destMultiArray(histogram), 1, gaussS);
199  convolveMultiArrayOneDimension(srcMultiArrayRange(histogram), destMultiArray(histogramBuffer), 2, gaussS);
200  convolveMultiArrayOneDimension(srcMultiArrayRange(histogramBuffer), destMultiArray(histogram), 3, gaussS);
201  convolveMultiArrayOneDimension(srcMultiArrayRange(histogram), destMultiArray(histogramBuffer), 4, gaussA);
202  convolveMultiArrayOneDimension(srcMultiArrayRange(histogramBuffer), destMultiArray(histogram), 5, gaussA);
203  }
204  else{
205  throw std::runtime_error("not yet implemented for arbitrary dimension");
206  }
207 
208 
209 
210  }
211 
212 }
213 //end namespace vigra
214 
215 #endif //VIGRA_MULTI_HISTOGRAMM_HXX

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.10.0 (Thu Jan 8 2015)