SourceXtractorPlusPlus 1.0.3
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 // Creates a SourceInfo to contain the unique_ptr to the source, coordinates and group_id
66 auto source_info = std::make_shared<SourceInfo>();
67 source_info->m_source = std::move(source);
68 source_info->m_x = centroid.getCentroidX();
69 source_info->m_y = centroid.getCentroidY();
70 source_info->m_group_id = m_group_counter++;
71
72 // Make a group containing only the source
73 auto group = std::make_shared<Group>();
74 group->push_back(source_info);
75 m_groups[source_info->m_group_id] = group;
76
77 // Find sources within range
78 auto sources = m_tree.getPointsWithinRange({source_info->m_x, source_info->m_y}, m_max_range);
79
80 std::set<size_t> matching_groups;
81 for (auto& s : sources) {
82 // check only sources that belong to a group we don't match with
83 if (matching_groups.find(s->m_group_id) == matching_groups.end() &&
84 m_grouping_criteria->shouldGroup(*source_info->m_source, *s->m_source)) {
85 matching_groups.insert(s->m_group_id);
86 }
87 }
88
89 // merge groups and keep the new group
90 for (auto group_id : matching_groups) {
91 if (m_hard_limit > 0 && m_groups.at(group_id)->size() + group->size() > m_hard_limit) {
92 // if we have a hard limit and the group is too large to merge, just process it
93 processGroup(group_id);
94 } else {
95 // merge group
96 group->insert(group->end(), m_groups.at(group_id)->begin(), m_groups.at(group_id)->end());
97 m_groups.erase(group_id);
98 }
99 }
100
101 for (auto& s : *group) {
102 s->m_group_id = source_info->m_group_id;
103 }
104
105 // Add source to the Quad Tree
106 m_tree.add(source_info);
107}
108
111 std::vector<size_t> groups_to_process;
112
113 // We iterate through all the SourceGroups we have
114 for (auto const& it : m_groups) {
115 // We look at its Sources and if we find at least one that needs to be processed
116 for (auto& source : *it.second) {
117 if (event.m_selection_criteria->mustBeProcessed(*source->m_source)) {
118 groups_to_process.push_back(it.first);
119 break;
120 }
121 }
122 }
123
124 // For each SourceGroup that we put in groups_to_process,
125 for (auto group_id : groups_to_process) {
126 processGroup(group_id);
127 }
128}
129
130void MoffatGrouping::processGroup(unsigned int group_id) {
131 // we remove it from our list of stored SourceGroups and notify our observers
132 auto new_group = m_group_factory->createSourceGroup();
133
134 for (auto& source_info : *m_groups.at(group_id)) {
135 new_group->addSource(std::move(source_info->m_source));
136 m_tree.remove(source_info);
137 }
138
139 sendSource(std::move(new_group));
140 m_groups.erase(group_id);
141}
142
143} // SourceXtractor namespace
144
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)