NumCpp  2.9.0
A Templatized Header Only C++ Implementation of the Python NumPy Library
Cluster.hpp
Go to the documentation of this file.
1 
29 #pragma once
30 
31 #include <algorithm>
32 #include <iostream>
33 #include <limits>
34 #include <string>
35 #include <type_traits>
36 #include <utility>
37 #include <vector>
38 
42 #include "NumCpp/Core/Types.hpp"
44 #include "NumCpp/Utils/num2str.hpp"
45 
46 namespace nc
47 {
48  namespace imageProcessing
49  {
50  //================================================================================
51  // Class Description:
53  template<typename dtype>
54  class Cluster
55  {
56  private:
57  STATIC_ASSERT_ARITHMETIC(dtype);
58 
59  public:
60  //================================Typedefs===============================
61  using const_iterator = typename std::vector<Pixel<dtype>>::const_iterator;
62  using accumulator_t = typename std::conditional<std::is_integral<dtype>::value, int64, double>::type;
63 
64  //=============================================================================
65  // Description:
68  Cluster() = default;
69 
70  //=============================================================================
71  // Description:
76  explicit Cluster(uint32 inClusterId) noexcept :
77  clusterId_(inClusterId)
78  {
79  }
80 
81  //=============================================================================
82  // Description:
89  bool operator==(const Cluster<dtype>& rhs) const noexcept
90  {
91  if (pixels_.size() != rhs.pixels_.size())
92  {
93  return false;
94  }
95 
96  return stl_algorithms::equal(begin(), end(), rhs.begin());
97  }
98 
99  //=============================================================================
100  // Description:
107  bool operator!=(const Cluster<dtype>& rhs) const noexcept
108  {
109  return !(*this == rhs);
110  }
111 
112  //=============================================================================
113  // Description:
120  const Pixel<dtype>& operator[](uint32 inIndex) const noexcept
121  {
122  return pixels_[inIndex];
123  }
124 
125  //=============================================================================
126  // Description:
133  const Pixel<dtype>& at(uint32 inIndex) const
134  {
135  if (inIndex >= pixels_.size())
136  {
137  THROW_INVALID_ARGUMENT_ERROR("index exceeds cluster size.");
138  }
139  return pixels_[inIndex];
140  }
141 
142  //=============================================================================
143  // Description:
148  const_iterator begin() const noexcept
149  {
150  return pixels_.cbegin();
151  }
152 
153  //=============================================================================
154  // Description:
159  const_iterator end() const noexcept
160  {
161  return pixels_.cend();
162  }
163 
164  //=============================================================================
165  // Description:
170  uint32 size() const noexcept
171  {
172  return static_cast<uint32>(pixels_.size());
173  }
174 
175  //=============================================================================
176  // Description:
181  uint32 clusterId() const noexcept
182  {
183  return clusterId_;
184  }
185 
186  //=============================================================================
187  // Description:
192  uint32 rowMin() const noexcept
193  {
194  return rowMin_;
195  }
196 
197  //=============================================================================
198  // Description:
203  uint32 rowMax() const noexcept
204  {
205  return rowMax_;
206  }
207 
208  //=============================================================================
209  // Description:
214  uint32 colMin() const noexcept
215  {
216  return colMin_;
217  }
218 
219  //=============================================================================
220  // Description:
225  uint32 colMax() const noexcept
226  {
227  return colMax_;
228  }
229 
230  //=============================================================================
231  // Description:
236  uint32 height() const noexcept
237  {
238  return rowMax_ - rowMin_ + 1;
239  }
240 
241  //=============================================================================
242  // Description:
247  uint32 width() const noexcept
248  {
249  return colMax_ - colMin_ + 1;
250  }
251 
252  //=============================================================================
253  // Description:
258  accumulator_t intensity() const noexcept
259  {
260  return intensity_;
261  }
262 
263  //=============================================================================
264  // Description:
269  dtype peakPixelIntensity() const noexcept
270  {
271  return peakPixelIntensity_;
272  }
273 
274  //=============================================================================
275  // Description:
280  double eod() const noexcept
281  {
282  return eod_;
283  }
284 
285  //=============================================================================
286  // Description:
291  void addPixel(const Pixel<dtype>& inPixel)
292  {
293  pixels_.push_back(inPixel);
294  intensity_ += static_cast<accumulator_t>(inPixel.intensity);
295 
296  // adjust the cluster bounds
297  rowMin_ = std::min(rowMin_, inPixel.row);
298  rowMax_ = std::max(rowMax_, inPixel.row);
299  colMin_ = std::min(colMin_, inPixel.col);
300  colMax_ = std::max(colMax_, inPixel.col);
301  peakPixelIntensity_ = std::max(peakPixelIntensity_, inPixel.intensity);
302 
303  // calculate the energy on detector estimate
304  eod_ = static_cast<double>(peakPixelIntensity_) / static_cast<double>(intensity_);
305  }
306 
307  //=============================================================================
308  // Description:
313  std::string str() const
314  {
315  std::string out;
316  uint32 counter = 0;
318  end(),
319  [&](const Pixel<dtype>& pixel)
320  { out += "Pixel " + utils::num2str(counter++) + ":" + pixel.str(); });
321 
322  return out;
323  }
324 
325  //============================================================================
329  void print() const
330  {
331  std::cout << *this;
332  }
333 
334  //=============================================================================
335  // Description:
342  friend std::ostream& operator<<(std::ostream& inStream, const Cluster<dtype>& inCluster)
343  {
344  inStream << inCluster.str();
345  return inStream;
346  }
347 
348  private:
349  //================================Attributes===============================
351  int32 clusterId_{ -1 };
353  std::vector<Pixel<dtype>> pixels_{};
355  uint32 rowMin_{ std::numeric_limits<uint32>::max() }; // largest possible number
357  uint32 rowMax_{ 0 };
359  uint32 colMin_{ std::numeric_limits<uint32>::max() }; // largest possible number
361  uint32 colMax_{ 0 };
363  accumulator_t intensity_{ 0 };
365  dtype peakPixelIntensity_{ 0 };
367  dtype minPixel;
369  dtype maxPixel;
371  double eod_{ 1. };
372  };
373  } // namespace imageProcessing
374 } // namespace nc
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition: Error.hpp:36
Holds the information for a cluster of pixels.
Definition: Cluster.hpp:55
friend std::ostream & operator<<(std::ostream &inStream, const Cluster< dtype > &inCluster)
Definition: Cluster.hpp:342
typename std::conditional< std::is_integral< dtype >::value, int64, double >::type accumulator_t
Definition: Cluster.hpp:62
uint32 colMin() const noexcept
Definition: Cluster.hpp:214
const Pixel< dtype > & operator[](uint32 inIndex) const noexcept
Definition: Cluster.hpp:120
typename std::vector< Pixel< dtype > >::const_iterator const_iterator
Definition: Cluster.hpp:61
double eod() const noexcept
Definition: Cluster.hpp:280
uint32 rowMax() const noexcept
Definition: Cluster.hpp:203
const Pixel< dtype > & at(uint32 inIndex) const
Definition: Cluster.hpp:133
const_iterator begin() const noexcept
Definition: Cluster.hpp:148
uint32 height() const noexcept
Definition: Cluster.hpp:236
Cluster(uint32 inClusterId) noexcept
Definition: Cluster.hpp:76
bool operator==(const Cluster< dtype > &rhs) const noexcept
Definition: Cluster.hpp:89
uint32 colMax() const noexcept
Definition: Cluster.hpp:225
void addPixel(const Pixel< dtype > &inPixel)
Definition: Cluster.hpp:291
bool operator!=(const Cluster< dtype > &rhs) const noexcept
Definition: Cluster.hpp:107
std::string str() const
Definition: Cluster.hpp:313
dtype peakPixelIntensity() const noexcept
Definition: Cluster.hpp:269
uint32 clusterId() const noexcept
Definition: Cluster.hpp:181
accumulator_t intensity() const noexcept
Definition: Cluster.hpp:258
uint32 rowMin() const noexcept
Definition: Cluster.hpp:192
uint32 width() const noexcept
Definition: Cluster.hpp:247
uint32 size() const noexcept
Definition: Cluster.hpp:170
const_iterator end() const noexcept
Definition: Cluster.hpp:159
void print() const
Definition: Cluster.hpp:329
Holds the information for a single pixel.
Definition: Pixel.hpp:47
dtype intensity
Definition: Pixel.hpp:56
uint32 col
Definition: Pixel.hpp:55
uint32 row
Definition: Pixel.hpp:54
std::string str() const
Definition: Pixel.hpp:136
void for_each(InputIt first, InputIt last, UnaryFunction f)
Definition: StlAlgorithms.hpp:227
bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2) noexcept
Definition: StlAlgorithms.hpp:142
std::string num2str(dtype inNumber)
Definition: num2str.hpp:46
Definition: Coordinate.hpp:45
NdArray< dtype > max(const NdArray< dtype > &inArray, Axis inAxis=Axis::NONE)
Definition: max.hpp:44
std::int64_t int64
Definition: Types.hpp:35
NdArray< dtype > min(const NdArray< dtype > &inArray, Axis inAxis=Axis::NONE)
Definition: min.hpp:44
std::int32_t int32
Definition: Types.hpp:36
std::uint32_t uint32
Definition: Types.hpp:40