SMIL  0.9.1
DBaseMeasureOperations.hpp
1 /*
2  * Copyright (c) 2011-2016, Matthieu FAESSEL and ARMINES
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of Matthieu FAESSEL, or ARMINES nor the
14  * names of its contributors may be used to endorse or promote products
15  * derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 
30 #ifndef _D_BASE_MEASURE_OPERATIONS_HPP
31 #define _D_BASE_MEASURE_OPERATIONS_HPP
32 
33 #include "Core/include/private/DImage.hpp"
34 #include "Base/include/private/DBlob.hpp"
35 
36 namespace smil
37 {
38 
45  template <class T, class _retType>
47  {
48  virtual ~MeasureFunctionBase() {}
49  typedef typename Image<T>::lineType lineType;
50  typedef _retType retType;
51  retType retVal;
52 
53  virtual void initialize(const Image<T> &/*imIn*/)
54  {
55  retVal = retType();
56  }
57  virtual void processSequence(lineType /*lineIn*/, size_t /*size*/) {}
58  virtual void finalize(const Image<T> &/*imIn*/) {}
59 
60  virtual RES_T processImage(const Image<T> &imIn, bool onlyNonZero=false)
61  {
62  initialize(imIn);
63  ASSERT(CHECK_ALLOCATED(&imIn), RES_ERR_BAD_ALLOCATION);
64 
65  lineType pixels = imIn.getPixels();
66  size_t pixCount = imIn.getPixelCount();
67 
68  if (!onlyNonZero)
69  processSequence(pixels, pixCount);
70  else
71  {
72  size_t curSize = 0;
73  size_t curStart = 0;
74 
75  for (size_t i=0;i<pixCount;i++)
76  {
77  if (pixels[i]!=T(0))
78  {
79  if (curSize==0 && curStart==0)
80  curStart = i;
81  curSize++;
82  }
83  else if (curSize>0)
84  {
85  processSequence(pixels + curStart, curSize);
86  curStart = 0;
87  curSize = 0;
88  }
89  }
90  if (curSize>0)
91  processSequence(pixels + curStart, curSize);
92  }
93  finalize(imIn);
94  return RES_OK;
95  }
96  virtual retType operator()(const Image<T> &imIn, bool onlyNonZero=false)
97  {
98  processImage(imIn, onlyNonZero);
99  return retVal;
100  }
101 
102  virtual retType processImage(const Image<T> &imIn, const Blob &blob)
103  {
104  initialize(imIn);
105 
106  ASSERT(CHECK_ALLOCATED(&imIn), RES_ERR_BAD_ALLOCATION, retVal);
107 
108  lineType pixels = imIn.getPixels();
109  Blob::sequences_const_iterator it = blob.sequences.begin();
110  Blob::sequences_const_iterator it_end = blob.sequences.end();
111  for (;it!=it_end;it++)
112  processSequence(pixels + (*it).offset, (*it).size);
113  finalize(imIn);
114  return retVal;
115  }
116  virtual retType operator()(const Image<T> &imIn, const Blob &blob)
117  {
118  processImage(imIn, blob);
119  return retVal;
120  }
121 
122  };
123 
124  template <class T, class _retType>
125  struct MeasureFunctionWithPos : public MeasureFunctionBase<T, _retType>
126  {
127  typedef typename Image<T>::lineType lineType;
128  typedef _retType retType;
129  virtual void processSequence(lineType /*lineIn*/, size_t /*size*/, size_t /*x*/, size_t /*y*/, size_t /*z*/) {}
130  virtual RES_T processImage(const Image<T> &imIn, bool onlyNonZero=false)
131  {
132  this->initialize(imIn);
133  ASSERT(CHECK_ALLOCATED(&imIn), RES_ERR_BAD_ALLOCATION);
134 
135  typename Image<T>::volType slices = imIn.getSlices();
136  typename Image<T>::sliceType lines;
137  typename Image<T>::lineType pixels;
138  size_t dims[3];
139  imIn.getSize(dims);
140 
141  if (!onlyNonZero)
142  {
143  for (size_t z=0;z<dims[2];z++)
144  {
145  lines = slices[z];
146  for (size_t y=0;y<dims[1];y++)
147  processSequence(lines[y], dims[0], 0, y, z);
148  }
149  }
150  else
151  {
152  for (size_t z=0;z<dims[2];z++)
153  {
154  lines = slices[z];
155  for (size_t y=0;y<dims[1];y++)
156  {
157  pixels = lines[y];
158  size_t curSize = 0;
159  size_t curStart = 0;
160 
161  for (size_t x=0;x<dims[0];x++)
162  {
163  if (pixels[x]!=0)
164  {
165  if (curSize++==0)
166  curStart = x;
167  }
168  else if (curSize>0)
169  {
170  processSequence(pixels+curStart, curSize, curStart, y, z);
171  curSize = 0;
172  }
173  }
174  if (curSize>0)
175  processSequence(pixels+curStart, curSize, curStart, y, z);
176  }
177  }
178 
179  }
180  this->finalize(imIn);
181  return RES_OK;
182  }
183  virtual retType processImage(const Image<T> &imIn, const Blob &blob)
184  {
185  this->initialize(imIn);
186 
187  ASSERT(CHECK_ALLOCATED(&imIn), RES_ERR_BAD_ALLOCATION, this->retVal);
188 
189  lineType pixels = imIn.getPixels();
190  Blob::sequences_const_iterator it = blob.sequences.begin();
191  Blob::sequences_const_iterator it_end = blob.sequences.end();
192  size_t x, y, z;
193  for (;it!=it_end;it++)
194  {
195  imIn.getCoordsFromOffset((*it).offset, x, y, z);
196  this->processSequence(pixels + (*it).offset, (*it).size, x, y, z);
197  }
198  this->finalize(imIn);
199  return this->retVal;
200  }
201  private:
202  virtual void processSequence(lineType /*lineIn*/, size_t /*size*/) {}
203  };
204 
205 
206 
207  template <class T, class labelT, class funcT>
208  map<labelT, typename funcT::retType> processBlobMeasure(const Image<T> &imIn, const map<labelT, Blob> &blobs)
209  {
210  typedef typename funcT::retType retType;
211  map<labelT, typename funcT::retType> res;
212 
213  ASSERT(CHECK_ALLOCATED(&imIn), RES_ERR_BAD_ALLOCATION, res);
214 
215  size_t blobNbr = blobs.size();
216  std::vector<labelT> _keys;
217  std::vector<retType> _results(blobNbr);
218 
219  for (typename map<labelT, Blob>::const_iterator it=blobs.begin();it!=blobs.end();it++)
220  _keys.push_back(it->first);
221 
222  labelT *keys = _keys.data();
223  retType *results = _results.data();
224 
225  size_t i;
226 
227  #ifdef USE_OPEN_MP
228  int nthreads = Core::getInstance()->getNumberOfThreads();
229  #pragma omp parallel private(i) num_threads(nthreads)
230  #endif // USE_OPEN_MP
231  {
232  #ifdef USE_OPEN_MP
233  #pragma omp for
234  #endif // USE_OPEN_MP
235  for (i=0;i<blobNbr;i++)
236  {
237  funcT func;
238  const Blob &blob = blobs.at(keys[i]);
239  results[i] = func(imIn, blob);
240  }
241  }
242  for (i=0;i<blobNbr;i++)
243  res[keys[i]] = results[i];
244  return res;
245  }
246 
247  template <class T, class labelT, class funcT>
248  map<labelT, typename funcT::retType> processBlobMeasure(const Image<T> &imIn, bool onlyNonZero=true)
249  {
250  map<labelT, Blob> blobs = computeBlobs(imIn, onlyNonZero);
251  return processBlobMeasure<T,labelT,funcT>(imIn, blobs);
252  }
253 
254 
257 } // namespace smil
258 
259 
260 #endif // _D_BASE_MEASURE_OPERATIONS_HPP
261 
Definition: DColorConvert.h:38
map< T, Blob > computeBlobs(const Image< T > &imIn, bool onlyNonZero=true)
Create a map of Blob from a labelized image.
Definition: DBlob.hpp:75
lineType getPixels() const
Get the pixels as a 1D array.
Definition: DImage.hpp:110
List of offset and size of line contiguous pixels.
Definition: DBlob.hpp:62
Definition: DBaseMeasureOperations.hpp:46
size_t getPixelCount() const
Get the number of pixels.
Definition: DBaseImage.h:150
Definition: DBaseMeasureOperations.hpp:125
Main Image class.
Definition: DQVtkViewer.hpp:44
void getCoordsFromOffset(size_t off, size_t &x, size_t &y, size_t &z) const
Get x,y(,z) coordinates for a given offset.
Definition: DBaseImage.h:182
volType getSlices() const
Get an array containing the start offset of each slice.
Definition: DImage.hpp:118