NumCpp  2.12.1
A Templatized Header Only C++ Implementation of the Python NumPy Library
Cluster.hpp
Go to the documentation of this file.
1
28
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"
45
46namespace nc::imageProcessing
47{
48 //================================================================================
49 // Class Description:
51 template<typename dtype>
52 class Cluster
53 {
54 private:
55 STATIC_ASSERT_ARITHMETIC(dtype);
56
57 public:
58 //================================Typedefs===============================
59 using const_iterator = typename std::vector<Pixel<dtype>>::const_iterator;
60 using accumulator_t = typename std::conditional<std::is_integral<dtype>::value, int64, double>::type;
61
62 //=============================================================================
63 // Description:
66 Cluster() = default;
67
68 //=============================================================================
69 // Description:
74 explicit Cluster(uint32 inClusterId) noexcept :
75 clusterId_(inClusterId)
76 {
77 }
78
79 //=============================================================================
80 // Description:
87 bool operator==(const Cluster<dtype>& rhs) const noexcept
88 {
89 if (pixels_.size() != rhs.pixels_.size())
90 {
91 return false;
92 }
93
94 return stl_algorithms::equal(begin(), end(), rhs.begin());
95 }
96
97 //=============================================================================
98 // Description:
105 bool operator!=(const Cluster<dtype>& rhs) const noexcept
106 {
107 return !(*this == rhs);
108 }
109
110 //=============================================================================
111 // Description:
118 const Pixel<dtype>& operator[](uint32 inIndex) const noexcept
119 {
120 return pixels_[inIndex];
121 }
122
123 //=============================================================================
124 // Description:
131 [[nodiscard]] const Pixel<dtype>& at(uint32 inIndex) const
132 {
133 if (inIndex >= pixels_.size())
134 {
135 THROW_INVALID_ARGUMENT_ERROR("index exceeds cluster size.");
136 }
137 return pixels_[inIndex];
138 }
139
140 //=============================================================================
141 // Description:
146 [[nodiscard]] const_iterator begin() const noexcept
147 {
148 return pixels_.cbegin();
149 }
150
151 //=============================================================================
152 // Description:
157 [[nodiscard]] const_iterator end() const noexcept
158 {
159 return pixels_.cend();
160 }
161
162 //=============================================================================
163 // Description:
168 [[nodiscard]] uint32 size() const noexcept
169 {
170 return static_cast<uint32>(pixels_.size());
171 }
172
173 //=============================================================================
174 // Description:
179 [[nodiscard]] uint32 clusterId() const noexcept
180 {
181 return clusterId_;
182 }
183
184 //=============================================================================
185 // Description:
190 [[nodiscard]] uint32 rowMin() const noexcept
191 {
192 return rowMin_;
193 }
194
195 //=============================================================================
196 // Description:
201 [[nodiscard]] uint32 rowMax() const noexcept
202 {
203 return rowMax_;
204 }
205
206 //=============================================================================
207 // Description:
212 [[nodiscard]] uint32 colMin() const noexcept
213 {
214 return colMin_;
215 }
216
217 //=============================================================================
218 // Description:
223 [[nodiscard]] uint32 colMax() const noexcept
224 {
225 return colMax_;
226 }
227
228 //=============================================================================
229 // Description:
234 [[nodiscard]] uint32 height() const noexcept
235 {
236 return rowMax_ - rowMin_ + 1;
237 }
238
239 //=============================================================================
240 // Description:
245 [[nodiscard]] uint32 width() const noexcept
246 {
247 return colMax_ - colMin_ + 1;
248 }
249
250 //=============================================================================
251 // Description:
256 [[nodiscard]] accumulator_t intensity() const noexcept
257 {
258 return intensity_;
259 }
260
261 //=============================================================================
262 // Description:
267 [[nodiscard]] dtype peakPixelIntensity() const noexcept
268 {
269 return peakPixelIntensity_;
270 }
271
272 //=============================================================================
273 // Description:
278 [[nodiscard]] double eod() const noexcept
279 {
280 return eod_;
281 }
282
283 //=============================================================================
284 // Description:
289 void addPixel(const Pixel<dtype>& inPixel)
290 {
291 pixels_.push_back(inPixel);
292 intensity_ += static_cast<accumulator_t>(inPixel.intensity);
293
294 // adjust the cluster bounds
295 rowMin_ = std::min(rowMin_, inPixel.row);
296 rowMax_ = std::max(rowMax_, inPixel.row);
297 colMin_ = std::min(colMin_, inPixel.col);
298 colMax_ = std::max(colMax_, inPixel.col);
299 peakPixelIntensity_ = std::max(peakPixelIntensity_, inPixel.intensity);
300
301 // calculate the energy on detector estimate
302 eod_ = static_cast<double>(peakPixelIntensity_) / static_cast<double>(intensity_);
303 }
304
305 //=============================================================================
306 // Description:
311 [[nodiscard]] std::string str() const
312 {
313 std::string out;
314 uint32 counter = 0;
316 end(),
317 [&](const Pixel<dtype>& pixel)
318 { out += "Pixel " + utils::num2str(counter++) + ":" + pixel.str(); });
319
320 return out;
321 }
322
323 //============================================================================
327 void print() const
328 {
329 std::cout << *this;
330 }
331
332 //=============================================================================
333 // Description:
340 friend std::ostream& operator<<(std::ostream& inStream, const Cluster<dtype>& inCluster)
341 {
342 inStream << inCluster.str();
343 return inStream;
344 }
345
346 private:
347 //================================Attributes===============================
349 int32 clusterId_{ -1 };
351 std::vector<Pixel<dtype>> pixels_{};
353 uint32 rowMin_{ std::numeric_limits<uint32>::max() }; // largest possible number
355 uint32 rowMax_{ 0 };
357 uint32 colMin_{ std::numeric_limits<uint32>::max() }; // largest possible number
359 uint32 colMax_{ 0 };
361 accumulator_t intensity_{ 0 };
363 dtype peakPixelIntensity_{ 0 };
365 dtype minPixel{};
367 dtype maxPixel{};
369 double eod_{ 1. };
370 };
371} // namespace nc::imageProcessing
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition: Error.hpp:37
Holds the information for a cluster of pixels.
Definition: Cluster.hpp:53
typename std::conditional< std::is_integral< dtype >::value, int64, double >::type accumulator_t
Definition: Cluster.hpp:60
uint32 colMin() const noexcept
Definition: Cluster.hpp:212
typename std::vector< Pixel< dtype > >::const_iterator const_iterator
Definition: Cluster.hpp:59
double eod() const noexcept
Definition: Cluster.hpp:278
uint32 rowMax() const noexcept
Definition: Cluster.hpp:201
const_iterator begin() const noexcept
Definition: Cluster.hpp:146
uint32 height() const noexcept
Definition: Cluster.hpp:234
Cluster(uint32 inClusterId) noexcept
Definition: Cluster.hpp:74
bool operator==(const Cluster< dtype > &rhs) const noexcept
Definition: Cluster.hpp:87
friend std::ostream & operator<<(std::ostream &inStream, const Cluster< dtype > &inCluster)
Definition: Cluster.hpp:340
uint32 colMax() const noexcept
Definition: Cluster.hpp:223
void addPixel(const Pixel< dtype > &inPixel)
Definition: Cluster.hpp:289
bool operator!=(const Cluster< dtype > &rhs) const noexcept
Definition: Cluster.hpp:105
std::string str() const
Definition: Cluster.hpp:311
dtype peakPixelIntensity() const noexcept
Definition: Cluster.hpp:267
uint32 clusterId() const noexcept
Definition: Cluster.hpp:179
accumulator_t intensity() const noexcept
Definition: Cluster.hpp:256
uint32 rowMin() const noexcept
Definition: Cluster.hpp:190
const Pixel< dtype > & at(uint32 inIndex) const
Definition: Cluster.hpp:131
uint32 width() const noexcept
Definition: Cluster.hpp:245
uint32 size() const noexcept
Definition: Cluster.hpp:168
const Pixel< dtype > & operator[](uint32 inIndex) const noexcept
Definition: Cluster.hpp:118
const_iterator end() const noexcept
Definition: Cluster.hpp:157
void print() const
Definition: Cluster.hpp:327
Holds the information for a single pixel.
Definition: Pixel.hpp:46
dtype intensity
Definition: Pixel.hpp:55
uint32 col
Definition: Pixel.hpp:54
uint32 row
Definition: Pixel.hpp:53
std::string str() const
Definition: Pixel.hpp:136
Definition: applyThreshold.hpp:34
void for_each(InputIt first, InputIt last, UnaryFunction f)
Definition: StlAlgorithms.hpp:225
bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2) noexcept
Definition: StlAlgorithms.hpp:140
std::string num2str(dtype inNumber)
Definition: num2str.hpp:44
NdArray< dtype > min(const NdArray< dtype > &inArray, Axis inAxis=Axis::NONE)
Definition: min.hpp:44
std::int64_t int64
Definition: Types.hpp:35
std::int32_t int32
Definition: Types.hpp:36
std::uint32_t uint32
Definition: Types.hpp:40
NdArray< dtype > max(const NdArray< dtype > &inArray, Axis inAxis=Axis::NONE)
Definition: max.hpp:44