vigra - vigra/multi_histogram.hxx Source File

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

multi_histogram.hxx |

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 ){
58 typedef vigra::GridGraph< DIM , boost::undirected_tag> Graph;
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 ){
138 typedef vigra::GridGraph< DIM , boost::undirected_tag> Graph;
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)