SMIL  1.0.4
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''
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
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 {
44  //
45  // ###### # # # # #### ##### ##### ## #### ######
46  // # # # ## # # # # # # # # # #
47  // ##### # # # # # # # ##### ##### # # #### #####
48  // # # # # # # # # # # ###### # #
49  // # # # # ## # # # # # # # # # #
50  // # #### # # #### # ##### # # #### ######
51  //
52  /*
53  *
54  */
55  template <class T, class _retType> struct MeasureFunctionBase {
56  virtual ~MeasureFunctionBase()
57  {
58  }
59  typedef typename Image<T>::lineType lineType;
60  typedef _retType retType;
61  retType retVal;
62 
63  virtual void initialize(const Image<T> & /*imIn*/)
64  {
65  retVal = retType();
66  }
67 
68  virtual void processSequence(lineType /*lineIn*/, size_t /*size*/)
69  {
70  }
71 
72  virtual void finalize(const Image<T> & /*imIn*/)
73  {
74  }
75 
76  virtual RES_T processImage(const Image<T> &imIn, bool onlyNonZero = false)
77  {
78  initialize(imIn);
79  ASSERT(CHECK_ALLOCATED(&imIn), RES_ERR_BAD_ALLOCATION);
80 
81  lineType pixels = imIn.getPixels();
82  size_t pixCount = imIn.getPixelCount();
83 
84  if (!onlyNonZero)
85  processSequence(pixels, pixCount);
86  else {
87  size_t curSize = 0;
88  size_t curStart = 0;
89 
90  for (size_t i = 0; i < pixCount; i++) {
91  if (pixels[i] != T(0)) {
92  if (curSize == 0 && curStart == 0)
93  curStart = i;
94  curSize++;
95  } else if (curSize > 0) {
96  processSequence(pixels + curStart, curSize);
97  curStart = 0;
98  curSize = 0;
99  }
100  }
101  if (curSize > 0)
102  processSequence(pixels + curStart, curSize);
103  }
104  finalize(imIn);
105  return RES_OK;
106  }
107 
108  /*
109  * To be tested - added by Joe in Aug 25, 2020
110  */
111  virtual RES_T processImage(const Image<T> &imIn,
112  SMIL_UNUSED const Image<T> &imMask)
113  {
114  initialize(imIn);
115  ASSERT(CHECK_ALLOCATED(&imIn), RES_ERR_BAD_ALLOCATION);
116 
117  lineType pixels = imIn.getPixels();
118  size_t pixCount = imIn.getPixelCount();
119 
120  processSequence(pixels, pixCount);
121 
122  finalize(imIn);
123  return RES_OK;
124  }
125 
126  virtual retType operator()(const Image<T> &imIn, bool onlyNonZero = false)
127  {
128  processImage(imIn, onlyNonZero);
129  return retVal;
130  }
131 
132  virtual retType processImage(const Image<T> &imIn, const Blob &blob)
133  {
134  initialize(imIn);
135 
136  ASSERT(CHECK_ALLOCATED(&imIn), RES_ERR_BAD_ALLOCATION, retVal);
137 
138  lineType pixels = imIn.getPixels();
139  Blob::sequences_const_iterator it = blob.sequences.begin();
140  Blob::sequences_const_iterator it_end = blob.sequences.end();
141  for (; it != it_end; it++)
142  processSequence(pixels + (*it).offset, (*it).size);
143  finalize(imIn);
144  return retVal;
145  }
146 
147  virtual retType operator()(const Image<T> &imIn, const Blob &blob)
148  {
149  processImage(imIn, blob);
150  return retVal;
151  }
152 
153  /*
154  * To be tested - added by Joe in Aug 25, 2020
155  */
156  virtual retType operator()(const Image<T> &imIn, const Blob &blob,
157  SMIL_UNUSED bool flag)
158  {
159  processImage(imIn, blob);
160  return retVal;
161  }
162  };
163 
164  //
165  // ###### # # # # #### ##### # # ##### #### ####
166  // # # # ## # # # # # # # # # # #
167  // ##### # # # # # # # ##### # # # # # # ####
168  // # # # # # # # # # ## # ##### # # #
169  // # # # # ## # # # ## ## # # # # #
170  // # #### # # #### # # # # #### ####
171  //
172  /*
173  *
174  */
175  template <class T, class _retType>
176  struct MeasureFunctionWithPos : public MeasureFunctionBase<T, _retType> {
177  typedef typename Image<T>::lineType lineType;
178  typedef _retType retType;
179  virtual void processSequence(lineType /*lineIn*/, size_t /*size*/,
180  size_t /*x*/, size_t /*y*/, size_t /*z*/)
181  {
182  }
183  virtual RES_T processImage(const Image<T> &imIn, bool onlyNonZero = false)
184  {
185  this->initialize(imIn);
186  ASSERT(CHECK_ALLOCATED(&imIn), RES_ERR_BAD_ALLOCATION);
187 
188  typename Image<T>::volType slices = imIn.getSlices();
189  typename Image<T>::sliceType lines;
190  typename Image<T>::lineType pixels;
191  size_t dims[3];
192  imIn.getSize(dims);
193 
194  if (!onlyNonZero) {
195  for (size_t z = 0; z < dims[2]; z++) {
196  lines = slices[z];
197  for (size_t y = 0; y < dims[1]; y++)
198  processSequence(lines[y], dims[0], 0, y, z);
199  }
200  } else {
201  for (size_t z = 0; z < dims[2]; z++) {
202  lines = slices[z];
203  for (size_t y = 0; y < dims[1]; y++) {
204  pixels = lines[y];
205  size_t curSize = 0;
206  size_t curStart = 0;
207 
208  for (size_t x = 0; x < dims[0]; x++) {
209  if (pixels[x] != 0) {
210  if (curSize++ == 0)
211  curStart = x;
212  } else if (curSize > 0) {
213  processSequence(pixels + curStart, curSize, curStart, y, z);
214  curSize = 0;
215  }
216  }
217  if (curSize > 0)
218  processSequence(pixels + curStart, curSize, curStart, y, z);
219  }
220  }
221  }
222  this->finalize(imIn);
223  return RES_OK;
224  }
225  virtual retType processImage(const Image<T> &imIn, const Blob &blob)
226  {
227  this->initialize(imIn);
228 
229  ASSERT(CHECK_ALLOCATED(&imIn), RES_ERR_BAD_ALLOCATION, this->retVal);
230 
231  lineType pixels = imIn.getPixels();
232  Blob::sequences_const_iterator it = blob.sequences.begin();
233  Blob::sequences_const_iterator it_end = blob.sequences.end();
234  size_t x, y, z;
235  for (; it != it_end; it++) {
236  imIn.getCoordsFromOffset((*it).offset, x, y, z);
237  this->processSequence(pixels + (*it).offset, (*it).size, x, y, z);
238  }
239  this->finalize(imIn);
240  return this->retVal;
241  }
242 
243  private:
244  virtual void processSequence(lineType /*lineIn*/, size_t /*size*/)
245  {
246  }
247  };
248 
249  //
250  // ##### # #### ##### # # ###### ## ####
251  // # # # # # # # ## ## # # # #
252  // ##### # # # ##### ##### # ## # ##### # # ####
253  // # # # # # # # # # # ###### #
254  // # # # # # # # # # # # # # #
255  // ##### ###### #### ##### # # ###### # # ####
256  //
257  /*
258  *
259  */
260  template <class T, class labelT, class funcT>
261  map<labelT, typename funcT::retType>
262  processBlobMeasure(const Image<T> &imIn, const map<labelT, Blob> &blobs)
263  {
264  typedef typename funcT::retType retType;
265  map<labelT, typename funcT::retType> res;
266 
267  ASSERT(CHECK_ALLOCATED(&imIn), RES_ERR_BAD_ALLOCATION, res);
268 
269  size_t blobNbr = blobs.size();
270  std::vector<labelT> _keys;
271  std::vector<retType> _results(blobNbr);
272 
273  for (typename map<labelT, Blob>::const_iterator it = blobs.begin();
274  it != blobs.end(); it++)
275  _keys.push_back(it->first);
276 
277  labelT *keys = _keys.data();
278  retType *results = _results.data();
279 
280  size_t i;
281 
282 #ifdef USE_OPEN_MP
283  int nthreads = Core::getInstance()->getNumberOfThreads();
284 #pragma omp parallel private(i) num_threads(nthreads)
285 #endif // USE_OPEN_MP
286  {
287 #ifdef USE_OPEN_MP
288 #pragma omp for
289 #endif // USE_OPEN_MP
290  for (i = 0; i < blobNbr; i++) {
291  funcT func;
292  const Blob &blob = blobs.at(keys[i]);
293  results[i] = func(imIn, blob);
294  }
295  }
296  for (i = 0; i < blobNbr; i++)
297  res[keys[i]] = results[i];
298  return res;
299  }
300 
301  /*
302  *
303  */
304  template <class T, class labelT, class funcT>
305  map<labelT, typename funcT::retType>
306  processBlobMeasure(const Image<T> &imIn, bool onlyNonZero = true)
307  {
308  map<labelT, Blob> blobs = computeBlobs(imIn, onlyNonZero);
309  return processBlobMeasure<T, labelT, funcT>(imIn, blobs);
310  }
311 
314 } // namespace smil
315 
316 #endif // _D_BASE_MEASURE_OPERATIONS_HPP
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:291
void getSize(size_t *w, size_t *h, size_t *d) const
Get image size.
Definition: DBaseImage.h:118
size_t getPixelCount() const
Get the number of pixels.
Definition: DBaseImage.h:160
Main Image class.
Definition: DImage.hpp:57
volType getSlices() const
Get an array containing the start offset of each slice.
Definition: DImage.hpp:117
lineType getPixels() const
Get the pixels as a 1D array.
Definition: DImage.hpp:105
map< T, Blob > computeBlobs(const Image< T > &imIn, bool onlyNonZero=true)
Create a map of blobs from a labeled image.
Definition: DBlob.hpp:98
List of offset and size of line contiguous pixels.
Definition: DBlob.hpp:82
Definition: DBaseMeasureOperations.hpp:55
Definition: DBaseMeasureOperations.hpp:176