46 namespace imageProcessing
51 template<
typename dtype>
55 STATIC_ASSERT_ARITHMETIC(dtype);
74 intensities_(inIntensityArrayPtr)
76 if (xcds_->
shape() != intensities_->shape())
81 shape_ = xcds_->
shape();
88 if (xcds_->operator()(row, col))
90 const Pixel<dtype> thePixel(row, col, intensities_->operator()(row, col));
91 xcdsVec_.push_back(thePixel);
98 for (
uint8 i = 0; i < inBorderWidth; ++i)
113 return static_cast<uint32>(clusters_.size());
128 return clusters_[inIndex];
143 if (inIndex >= clusters_.size())
147 return clusters_[inIndex];
159 return clusters_.cbegin();
171 return clusters_.cend();
178 std::vector<Pixel<dtype> > xcdsVec_{};
182 std::vector<Cluster<dtype> > clusters_{};
194 Pixel<dtype> makePixel(
int32 inRow,
int32 inCol) noexcept
200 const dtype intensity = intensities_->operator()(row, col);
202 return Pixel<dtype>(row, col, intensity);
214 void findNeighbors(
const Pixel<dtype>& inPixel, std::set<Pixel<dtype> >& outNeighbors)
219 const auto row =
static_cast<int32>(inPixel.row);
220 const auto col =
static_cast<int32>(inPixel.col);
222 outNeighbors.insert(outNeighbors.end(), makePixel(row - 1, col - 1));
223 outNeighbors.insert(outNeighbors.end(), makePixel(row - 1, col));
224 outNeighbors.insert(outNeighbors.end(), makePixel(row - 1, col + 1));
225 outNeighbors.insert(outNeighbors.end(), makePixel(row, col - 1));
226 outNeighbors.insert(outNeighbors.end(), makePixel(row, col + 1));
227 outNeighbors.insert(outNeighbors.end(), makePixel(row + 1, col - 1));
228 outNeighbors.insert(outNeighbors.end(), makePixel(row + 1, col));
229 outNeighbors.insert(outNeighbors.end(), makePixel(row + 1, col + 1));
242 void findNeighborNotXcds(
const Pixel<dtype>& inPixel, std::vector<Pixel<dtype> >& outNeighbors)
244 std::set<Pixel<dtype> > neighbors;
245 findNeighbors(inPixel, neighbors);
248 for (
auto& pixel : neighbors)
250 if (!xcds_->operator()(pixel.row, pixel.col))
252 outNeighbors.push_back(pixel);
267 void findNeighborXcds(
const Pixel<dtype>& inPixel, std::vector<uint32>& outNeighbors)
269 std::set<Pixel<dtype> > neighbors;
270 findNeighbors(inPixel, neighbors);
271 std::vector<Pixel<dtype> > neighborXcds;
274 for (
auto& pixel : neighbors)
276 if (xcds_->operator()(pixel.row, pixel.col))
278 neighborXcds.push_back(pixel);
283 for (
auto& pixel : neighborXcds)
285 auto theExceedanceIter =
std::find(xcdsVec_.begin(), xcdsVec_.end(), pixel);
286 outNeighbors.push_back(
static_cast<uint32>(theExceedanceIter - xcdsVec_.begin()));
294 void runClusterMaker()
298 for (
auto& currentPixel : xcdsVec_)
301 if (currentPixel.clusterId == -1)
303 Cluster<dtype> newCluster(clusterId);
304 currentPixel.clusterId = clusterId;
305 newCluster.addPixel(currentPixel);
308 std::vector<uint32> neighborIds;
309 findNeighborXcds(currentPixel, neighborIds);
310 if (neighborIds.empty())
312 clusters_.push_back(newCluster);
318 for (
uint32 neighborsIdx = 0; neighborsIdx < neighborIds.size(); ++neighborsIdx)
320 Pixel<dtype>& currentNeighborPixel = xcdsVec_[neighborIds[neighborsIdx]];
323 std::vector<uint32> newNeighborIds;
324 findNeighborXcds(currentNeighborPixel, newNeighborIds);
327 for (
auto newNeighborId : newNeighborIds)
330 if (
std::find(neighborIds.begin(), neighborIds.end(), newNeighborId) == neighborIds.end())
332 neighborIds.push_back(newNeighborId);
337 if (currentNeighborPixel.clusterId == -1)
339 currentNeighborPixel.clusterId = clusterId;
340 newCluster.addPixel(currentNeighborPixel);
344 clusters_.push_back(std::move(newCluster));
354 void expandClusters()
357 for (
auto& theCluster : clusters_)
360 for (
auto& thePixel : theCluster)
362 std::vector<Pixel<dtype> > neighborsNotXcds;
363 findNeighborNotXcds(thePixel, neighborsNotXcds);
366 for (
auto& newPixel : neighborsNotXcds)
368 if (
std::find(theCluster.begin(), theCluster.end(), newPixel) == theCluster.end())
370 theCluster.addPixel(newPixel);
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition: Error.hpp:36
Shape shape() const noexcept
Definition: NdArrayCore.hpp:4483
A Shape Class for NdArrays.
Definition: Core/Shape.hpp:41
uint32 rows
Definition: Core/Shape.hpp:44
uint32 cols
Definition: Core/Shape.hpp:45
Holds the information for a cluster of pixels.
Definition: Cluster.hpp:54
Clusters exceedance data into contiguous groups.
Definition: ClusterMaker.hpp:53
ClusterMaker(const NdArray< bool > *const inXcdArrayPtr, const NdArray< dtype > *const inIntensityArrayPtr, uint8 inBorderWidth=0)
Definition: ClusterMaker.hpp:72
const_iterator begin() const noexcept
Definition: ClusterMaker.hpp:157
const Cluster< dtype > & at(uint32 inIndex) const
Definition: ClusterMaker.hpp:141
const_iterator end() const noexcept
Definition: ClusterMaker.hpp:169
typename std::vector< Cluster< dtype > >::const_iterator const_iterator
Definition: ClusterMaker.hpp:59
uint32 size() noexcept
Definition: ClusterMaker.hpp:111
const Cluster< dtype > & operator[](uint32 inIndex) const noexcept
Definition: ClusterMaker.hpp:126
Holds the information for a single pixel.
Definition: Pixel.hpp:47
InputIt find(InputIt first, InputIt last, const T &value) noexcept
Definition: StlAlgorithms.hpp:195
Definition: Coordinate.hpp:45
NdArray< dtype > min(const NdArray< dtype > &inArray, Axis inAxis=Axis::NONE)
Definition: min.hpp:45
std::int32_t int32
Definition: Types.hpp:36
std::uint8_t uint8
Definition: Types.hpp:42
std::uint32_t uint32
Definition: Types.hpp:40