36#ifndef VIGRA_MULTI_HISTOGRAMM_HXX
37#define VIGRA_MULTI_HISTOGRAMM_HXX
39#include "multi_array.hxx"
40#include "tinyvector.hxx"
41#include "multi_gridgraph.hxx"
42#include "multi_convolution.hxx"
48 template<
unsigned int DIM ,
class T_DATA ,
unsigned int CHANNELS,
class T_HIST >
49 void multiGaussianHistogram(
58 typedef vigra::GridGraph< DIM , undirected_tag> Graph;
59 typedef typename Graph::NodeIt graph_scanner;
60 typedef typename Graph::Node Node;
61 typedef T_HIST ValueType;
64 const Graph g(image.shape());
65 const ChannelsVals nBins(bins);
68 for (graph_scanner n(g); n != lemon::INVALID; ++n){
70 ChannelsVals binIndex = image[node];
75 for(
size_t d=0;d<DIM;++d){
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));
83 histogram[histCoord]+=1.0;
90 gaussBin.initGaussian(sigmaBin);
91 for(
size_t c=0;c<CHANNELS;++c){
99 sigmaVec[DIM] = sigmaBin;
100 opts.stdDev(sigmaVec);
109 template<
unsigned int DIM ,
class T_DATA,
class T_HIST >
110 void multiGaussianCoHistogram(
119 typedef vigra::GridGraph< DIM , undirected_tag> Graph;
120 typedef typename Graph::NodeIt graph_scanner;
121 typedef typename Graph::Node Node;
123 const Graph g(imageA.shape());
126 for (graph_scanner n(g); n != lemon::INVALID; ++n){
129 T_DATA binIndexA = imageA[node];
130 T_DATA binIndexB = imageA[node];
132 binIndexA -=minVals[0];
133 binIndexA /=maxVals[0];
134 binIndexA *=nBins[0];
136 binIndexB -=minVals[1];
137 binIndexB /=maxVals[1];
138 binIndexB *=nBins[1];
141 for(
size_t d=0;d<DIM;++d)
142 histCoord[d]=node[d];
144 histCoord[DIM]=binIndexA;
145 histCoord[DIM+1]=binIndexB;
147 const float fiA = binIndexA;
148 const unsigned int biA = std::floor(fiA+0.5);
149 const unsigned int biB = std::floor(fiA+0.5);
150 histCoord[DIM]=std::min(biA,
static_cast<unsigned int>(nBins[0]-1));
151 histCoord[DIM+1]=std::min(biB,
static_cast<unsigned int>(nBins[1]-1));
152 histogram[histCoord]+=1.0;
159 gaussA.initGaussian(sigma[1]);
160 gaussB.initGaussian(sigma[2]);
174 histogram=histogramBuffer;
185 throw std::runtime_error(
"not yet implemented for arbitrary dimension");
193 template<
unsigned int DIM ,
class T,
class V,
class U>
194 void multiGaussianRankOrder(
204 typedef typename ImgType::difference_type ImgCoord;
207 typedef typename HistType::difference_type HistCoord;
210 typedef typename OutType::difference_type OutCoord;
215 std::copy(image.shape().begin(), image.shape().end(), histShape.begin());
216 histShape[DIM] = bins;
217 HistType histA(histShape);
222 HistCoord histCoord,nextHistCoord;
225 for(std::ptrdiff_t i=0 ;i<image.size(); ++i, ++iter){
226 const ImgCoord imgCoord(*iter);
227 std::copy(imgCoord.begin(),imgCoord.end(),histCoord.begin() );
229 const T value = image[imgCoord];
230 const T fbinIndex = ((value-minVal)/(maxVal-minVal))*bins;
231 const T fFloorBin = std::floor(fbinIndex);
232 const int floorBin =
static_cast<int>(fFloorBin);
233 const int ceilBin =
static_cast<int>(std::ceil(fbinIndex));
235 if(floorBin==ceilBin){
236 histCoord[DIM] = floorBin;
237 histA[histCoord] += 1.0;
240 const T floorBin = std::floor(fbinIndex);
241 const T ceilBin = std::ceil(fbinIndex);
242 const double ceilW = (fbinIndex - fFloorBin);
243 const double floorW = 1.0 - ceilW;
244 histCoord[DIM] = floorBin;
245 histA[histCoord] += floorW;
246 histCoord[DIM] = ceilBin;
247 histA[histCoord] += ceilW;
262 std::vector<float> histBuffer(bins);
266 for(std::ptrdiff_t i=0 ;i<image.size(); ++i, ++iter){
269 const ImgCoord imgCoord(*iter);
272 std::copy(imgCoord.begin(),imgCoord.end(),histCoord.begin() );
273 nextHistCoord = histCoord;
274 std::copy(imgCoord.begin(),imgCoord.end(),outCoord.begin() );
276 for(
size_t bi=0; bi<bins; ++bi){
278 sum += histA[histCoord];
280 for(
size_t bi=0; bi<bins; ++bi){
282 histA[histCoord] /=
sum;
285 histBuffer[0] = histA[histCoord];
286 for(
size_t bi=1; bi<bins; ++bi){
288 double prevVal = histA[histCoord];
290 histA[histCoord] +=prevVal;
291 histBuffer[bi] = histA[histCoord];
297 for(std::ptrdiff_t r=0; r<ranks.size(); ++r){
299 const V rank = ranks[r];
301 nextHistCoord[DIM] = bi +1;
304 if(rank < histA[histCoord] ||
305 std::abs(rank-histA[histCoord])< 0.0000001 ||
308 out[outCoord] =
static_cast<U
>((maxVal-minVal)*bi*bins + minVal);
313 const size_t upperBinIndex =
314 std::distance(histBuffer.begin(),std::lower_bound(histBuffer.begin()+bi, histBuffer.end(),
float(rank)));
315 bi = upperBinIndex - 1;
317 nextHistCoord[DIM] = upperBinIndex;
318 const double rankVal0 =
static_cast<U
>((maxVal-minVal)*bi*bins + minVal);
319 const double rankVal1 =
static_cast<U
>((maxVal-minVal)*(bi+1)*bins + minVal);
320 const double dd = histA[nextHistCoord] - histA[histCoord];
321 const double relD0 = (rank - histA[histCoord])/dd;
322 out[outCoord] = rankVal1 * relD0 + (1.0 - relD0)*rankVal0;
Options class template for convolutions.
Definition multi_convolution.hxx:336
ConvolutionOptions< dim > & stdDev(...)
Generic 1 dimensional convolution kernel.
Definition separableconvolution.hxx:1367
void initGaussian(double std_dev, value_type norm, double windowRatio=0.0)
Definition separableconvolution.hxx:2253
Base class for, and view to, MultiArray.
Definition multi_array.hxx:705
MultiArrayView< N-M, T, StrideTag > bindOuter(const TinyVector< Index, M > &d) const
Definition multi_array.hxx:2186
MultiArrayShape< actual_dimension >::type difference_type
Definition multi_array.hxx:739
Main MultiArray class containing the memory management.
Definition multi_array.hxx:2479
Iterate over a virtual array where each element contains its coordinate.
Definition multi_iterator.hxx:89
Class for fixed size vectors.
Definition tinyvector.hxx:1008
void gaussianSmoothMultiArray(...)
Isotropic Gaussian smoothing of a multi-dimensional arrays.
NumericTraits< V >::Promote sum(TinyVectorBase< V, SIZE, D1, D2 > const &l)
sum of the vector's elements
Definition tinyvector.hxx:2073
void convolveMultiArrayOneDimension(...)
Convolution along a single dimension of a multi-dimensional arrays.