46 namespace imageProcessing
51 template<
typename dtype>
55 STATIC_ASSERT_ARITHMETIC(dtype);
73 intensities_(inIntensityArrayPtr)
75 if (xcds_->
shape() != intensities_->shape())
80 shape_ = xcds_->
shape();
87 if (xcds_->operator()(row, col))
89 const Pixel<dtype> thePixel(row, col, intensities_->operator()(row, col));
90 xcdsVec_.push_back(thePixel);
97 for (
uint8 i = 0; i < inBorderWidth; ++i)
111 return static_cast<uint32>(clusters_.size());
124 return clusters_[inIndex];
137 if (inIndex >= clusters_.size())
141 return clusters_[inIndex];
152 return clusters_.cbegin();
163 return clusters_.cend();
170 std::vector<Pixel<dtype> > xcdsVec_{};
174 std::vector<Cluster<dtype> > clusters_{};
185 Pixel<dtype> makePixel(
int32 inRow,
int32 inCol) noexcept
191 const dtype intensity = intensities_->operator()(row, col);
193 return Pixel<dtype>(row, col, intensity);
204 void findNeighbors(
const Pixel<dtype>& inPixel, std::set<Pixel<dtype> >& outNeighbors)
209 const auto row =
static_cast<int32>(inPixel.row);
210 const auto col =
static_cast<int32>(inPixel.col);
212 outNeighbors.insert(outNeighbors.end(), makePixel(row - 1, col - 1));
213 outNeighbors.insert(outNeighbors.end(), makePixel(row - 1, col));
214 outNeighbors.insert(outNeighbors.end(), makePixel(row - 1, col + 1));
215 outNeighbors.insert(outNeighbors.end(), makePixel(row, col - 1));
216 outNeighbors.insert(outNeighbors.end(), makePixel(row, col + 1));
217 outNeighbors.insert(outNeighbors.end(), makePixel(row + 1, col - 1));
218 outNeighbors.insert(outNeighbors.end(), makePixel(row + 1, col));
219 outNeighbors.insert(outNeighbors.end(), makePixel(row + 1, col + 1));
231 void findNeighborNotXcds(
const Pixel<dtype>& inPixel, std::vector<Pixel<dtype> >& outNeighbors)
233 std::set<Pixel<dtype> > neighbors;
234 findNeighbors(inPixel, neighbors);
237 for (
auto& pixel : neighbors)
239 if (!xcds_->operator()(pixel.row, pixel.col))
241 outNeighbors.push_back(pixel);
255 void findNeighborXcds(
const Pixel<dtype>& inPixel, std::vector<uint32>& outNeighbors)
257 std::set<Pixel<dtype> > neighbors;
258 findNeighbors(inPixel, neighbors);
259 std::vector<Pixel<dtype> > neighborXcds;
262 for (
auto& pixel : neighbors)
264 if (xcds_->operator()(pixel.row, pixel.col))
266 neighborXcds.push_back(pixel);
271 for (
auto& pixel : neighborXcds)
273 auto theExceedanceIter =
std::find(xcdsVec_.begin(), xcdsVec_.end(), pixel);
274 outNeighbors.push_back(
static_cast<uint32>(theExceedanceIter - xcdsVec_.begin()));
282 void runClusterMaker()
286 for (
auto& currentPixel : xcdsVec_)
289 if (currentPixel.clusterId == -1)
291 Cluster<dtype> newCluster(clusterId);
292 currentPixel.clusterId = clusterId;
293 newCluster.addPixel(currentPixel);
296 std::vector<uint32> neighborIds;
297 findNeighborXcds(currentPixel, neighborIds);
298 if (neighborIds.empty())
300 clusters_.push_back(newCluster);
306 for (
uint32 neighborsIdx = 0; neighborsIdx < neighborIds.size(); ++neighborsIdx)
308 Pixel<dtype>& currentNeighborPixel = xcdsVec_[neighborIds[neighborsIdx]];
311 std::vector<uint32> newNeighborIds;
312 findNeighborXcds(currentNeighborPixel, newNeighborIds);
315 for (
auto newNeighborId : newNeighborIds)
318 if (
std::find(neighborIds.begin(), neighborIds.end(), newNeighborId) == neighborIds.end())
320 neighborIds.push_back(newNeighborId);
325 if (currentNeighborPixel.clusterId == -1)
327 currentNeighborPixel.clusterId = clusterId;
328 newCluster.addPixel(currentNeighborPixel);
332 clusters_.push_back(std::move(newCluster));
342 void expandClusters()
345 for (
auto& theCluster : clusters_)
348 for (
auto& thePixel : theCluster)
350 std::vector<Pixel<dtype> > neighborsNotXcds;
351 findNeighborNotXcds(thePixel, neighborsNotXcds);
354 for (
auto& newPixel : neighborsNotXcds)
356 if (
std::find(theCluster.begin(), theCluster.end(), newPixel) == theCluster.end())
358 theCluster.addPixel(newPixel);
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition: Error.hpp:36
Shape shape() const noexcept
Definition: NdArrayCore.hpp:4283
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:71
const_iterator begin() const noexcept
Definition: ClusterMaker.hpp:150
const Cluster< dtype > & at(uint32 inIndex) const
Definition: ClusterMaker.hpp:135
const_iterator end() const noexcept
Definition: ClusterMaker.hpp:161
typename std::vector< Cluster< dtype > >::const_iterator const_iterator
Definition: ClusterMaker.hpp:59
uint32 size() noexcept
Definition: ClusterMaker.hpp:109
const Cluster< dtype > & operator[](uint32 inIndex) const noexcept
Definition: ClusterMaker.hpp:122
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:44
std::int32_t int32
Definition: Types.hpp:36
std::uint8_t uint8
Definition: Types.hpp:42
std::uint32_t uint32
Definition: Types.hpp:40