SourceXtractorPlusPlus 0.22
SourceXtractor++, the next generation SExtractor
Loading...
Searching...
No Matches
MoffatGrouping.cpp
Go to the documentation of this file.
1
17
18#include "SEUtils/QuadTree.h"
19
20#include <set>
21
24
29
30namespace SourceXtractor {
31
32template <>
33struct QuadTreeTraits<std::shared_ptr<MoffatGrouping::SourceInfo>> {
35 if (index == 0) {
36 return t->m_x;
37 } else {
38 return t->m_y;
39 }
40 }
41};
42
43
45 std::shared_ptr<GroupingCriteria> grouping_criteria, std::shared_ptr<SourceGroupFactory> group_factory, unsigned int hard_limit, float max_range)
46 : m_grouping_criteria(grouping_criteria), m_group_factory(group_factory), m_hard_limit(hard_limit), m_max_range(max_range), m_group_counter(0)
47
48{
49}
50
58
61
62 // Encapsulates the source unique_ptr
63 auto& centroid = source->getProperty<PixelCentroid>();
64
65 auto source_info = std::make_shared<SourceInfo>();
66 source_info->m_source = std::move(source);
67 source_info->m_x = centroid.getCentroidX();
68 source_info->m_y = centroid.getCentroidY();
69 source_info->m_group_id = m_group_counter++;
70
71 auto group = std::make_shared<Group>();
72 group->push_back(source_info);
73 m_groups[source_info->m_group_id] = group;
74
75 // Find sources within range
76 auto sources = m_tree.getPointsWithinRange({source_info->m_x, source_info->m_y}, m_max_range);
77
78 std::set<size_t> matching_groups;
79 for (auto& s : sources) {
80 // check only sources that belong to a group we don't match with
81 if (matching_groups.find(s->m_group_id) == matching_groups.end() &&
82 m_grouping_criteria->shouldGroup(*source_info->m_source, *s->m_source)) {
83 matching_groups.insert(s->m_group_id);
84 }
85 }
86
87 // merge groups and keep the new group
88 for (auto group_id : matching_groups) {
89 if (m_hard_limit > 0 && m_groups.at(group_id)->size() + group->size() > m_hard_limit) {
90 // if we have a hard limit and the group is too large to merge, just process it
91 processGroup(group_id);
92 } else {
93 // merge group
94 group->insert(group->end(), m_groups.at(group_id)->begin(), m_groups.at(group_id)->end());
95 m_groups.erase(group_id);
96 }
97 }
98
99 for (auto& s : *group) {
100 s->m_group_id = source_info->m_group_id;
101 }
102
103 // Add source to the Quad Tree
104 m_tree.add(source_info);
105}
106
109 std::vector<size_t> groups_to_process;
110
111 // We iterate through all the SourceGroups we have
112 for (auto const& it : m_groups) {
113 // We look at its Sources and if we find at least one that needs to be processed
114 for (auto& source : *it.second) {
115 if (event.m_selection_criteria->mustBeProcessed(*source->m_source)) {
116 groups_to_process.push_back(it.first);
117 break;
118 }
119 }
120 }
121
122 // For each SourceGroup that we put in groups_to_process,
123 for (auto group_id : groups_to_process) {
124 processGroup(group_id);
125 }
126}
127
128void MoffatGrouping::processGroup(unsigned int group_id) {
129 // we remove it from our list of stored SourceGroups and notify our observers
130 auto new_group = m_group_factory->createSourceGroup();
131
132 for (auto& source_info : *m_groups.at(group_id)) {
133 new_group->addSource(std::move(source_info->m_source));
134 m_tree.remove(source_info);
135 }
136
137 sendSource(std::move(new_group));
138 m_groups.erase(group_id);
139}
140
141} // SourceXtractor namespace
142
void receiveProcessSignal(const ProcessSourcesEvent &event) override
Handles a ProcessSourcesEvent to trigger the processing of some of the Sources stored in SourceGroupi...
MoffatGrouping(std::shared_ptr< GroupingCriteria > grouping_criteria, std::shared_ptr< SourceGroupFactory > group_factory, unsigned int hard_limit, float max_range)
std::set< PropertyId > requiredProperties() const override
Returns the set of required properties to compute the grouping.
QuadTree< std::shared_ptr< SourceInfo > > m_tree
std::shared_ptr< SourceGroupFactory > m_group_factory
void processGroup(unsigned int group_id)
std::shared_ptr< GroupingCriteria > m_grouping_criteria
void receiveSource(std::unique_ptr< SourceInterface > source) override
Handles a new Source.
std::map< unsigned int, std::shared_ptr< Group > > m_groups
void sendSource(std::unique_ptr< SourceGroupInterface > source) const
The centroid of all the pixels in the source, weighted by their DetectionImage pixel values.
SeFloat getCentroidX() const
X coordinate of centroid.
SeFloat getCentroidY() const
Y coordinate of centroid.
static PropertyId create(unsigned int index=0)
Definition PropertyId.h:45
T end(T... args)
T find(T... args)
T insert(T... args)
T make_shared(T... args)
T move(T... args)
STL namespace.
T push_back(T... args)
Event received by SourceGrouping to request the processing of some of the Sources stored.
const std::shared_ptr< SelectionCriteria > m_selection_criteria
static double getCoord(std::shared_ptr< MoffatGrouping::SourceInfo > t, size_t index)