SourceXtractorPlusPlus 1.0.3
SourceXtractor++, the next generation SExtractor
Loading...
Searching...
No Matches
AttractorsPartitionStep.cpp
Go to the documentation of this file.
1
22#include <limits>
23
27
32
33namespace SourceXtractor {
34
37 Accessor stamp(source->getProperty<DetectionFrameSourceStamp>().getStamp());
38 auto& detection_frame = source->getProperty<DetectionFrame>();
39 auto& bounds = source->getProperty<PixelBoundaries>();
40
41 auto bbox_min = bounds.getMin();
42 auto bbox_max = bounds.getMax();
43
44 auto value_function = [bbox_min, bbox_max, &stamp](PixelCoordinate coord) {
45 if (coord.m_x < bbox_min.m_x || coord.m_x > bbox_max.m_x || coord.m_y < bbox_min.m_y || coord.m_y > bbox_max.m_y) {
47 }
48 auto offset_coord = coord - bbox_min;
49 return stamp.getValue(offset_coord.m_x, offset_coord.m_y);
50 };
51
53 auto& pixel_list = source->getProperty<PixelCoordinateList>().getCoordinateList();
54 pixel_coordinates.reserve(pixel_list.size());
55 for (auto& pixel : pixel_list) {
56 pixel_coordinates.emplace_back(pixel, pixel);
57 }
58
60
61 attractPixels(pixel_coordinates, attractors, value_function);
62 auto merged = mergeAttractors(attractors);
63
64 // If we end up with a single group use the original group
66 if (merged.size() == 1) {
67 sources.emplace_back(std::move(source));
68 } else {
69 for (auto& source_pixels : merged) {
70 auto new_source = m_source_factory->createSource();
71 new_source->setProperty<PixelCoordinateList>(source_pixels);
72 new_source->setProperty<DetectionFrame>(detection_frame.getEncapsulatedFrame());
73 sources.emplace_back(std::move(new_source));
74 }
75 }
76 return sources;
77}
78
83
84 PixelCoordinate offsets[5] {
85 PixelCoordinate( 0, 0),
86 PixelCoordinate(-1, 0),
87 PixelCoordinate( 0, -1),
88 PixelCoordinate( 1, 0),
89 PixelCoordinate( 0, 1)
90 };
91
92 if (pixels_with_origin.size() == 0) {
93 return;
94 }
95
97
98 for (auto& pixel_origin : pixels_with_origin) {
99 auto pixel = pixel_origin.first;
100 auto origin = pixel_origin.second;
101
103 for (int i=0; i<5; i++) {
104 values[i] = value_function(pixel + offsets[i]);
105 }
106
107 size_t max = 0;
108 for (int i=1; i<3; i++) {
109 if (values[i] > values[max]) {
110 max = i;
111 }
112 }
113 for (int i=3; i<5; i++) {
114 if (values[i] >= values[max]) {
115 max = i;
116 }
117 }
118
119 if (max == 0) {
120 // We are at the attractor pixel
121 attractors[pixel].push_back(origin);
122 } else {
123 pixels_to_be_processed.push_back(
124 std::pair<PixelCoordinate, PixelCoordinate>(pixel + offsets[max], origin));
125 }
126 }
127 attractPixels(pixels_to_be_processed, attractors, value_function);
128}
129
135
136 for (auto& attractor : attractors) {
137 auto coord = attractor.first;
138 auto& pixels = attractor.second;
139 bool done = false;
140
141 for (size_t i=0; i < merged.size(); i++) {
142 if (coord.m_x >= bbox_min[i].m_x-1 && coord.m_x <= bbox_max[i].m_x+1 && coord.m_y >= bbox_min[i].m_y-1 && coord.m_y <= bbox_max[i].m_y+1) {
143 bbox_min[i] = PixelCoordinate(std::min(coord.m_x, bbox_min[i].m_x), std::min(coord.m_y, bbox_min[i].m_y));
144 bbox_max[i] = PixelCoordinate(std::max(coord.m_x, bbox_max[i].m_x), std::max(coord.m_y, bbox_max[i].m_y));
145 merged[i].insert(merged[i].begin(), pixels.begin(), pixels.end());
146 done = true;
147 break;
148 }
149 }
150 if (!done) {
151 merged.push_back(pixels);
152 bbox_min.push_back(coord);
153 bbox_max.push_back(coord);
154 }
155 }
156 return merged;
157}
158
159} // SEImplementation namespace
160
161
162
T begin(T... args)
std::vector< std::vector< PixelCoordinate > > mergeAttractors(const std::unordered_map< PixelCoordinate, std::vector< PixelCoordinate > > &attractors) const
void attractPixels(const std::vector< std::pair< PixelCoordinate, PixelCoordinate > > &pixels_with_origin, std::unordered_map< PixelCoordinate, std::vector< PixelCoordinate > > &attractors, std::function< DetectionImage::PixelType(PixelCoordinate)> value_function) const
std::vector< std::unique_ptr< SourceInterface > > partition(std::unique_ptr< SourceInterface > source) const override
std::shared_ptr< SourceFactory > m_source_factory
A copy of the rectangular region of the detection image just large enough to include the whole Source...
const DetectionVectorImage & getStamp() const
The bounding box of all the pixels in the source. Both min and max coordinate are inclusive.
T emplace_back(T... args)
T insert(T... args)
T lowest(T... args)
T max(T... args)
T min(T... args)
T move(T... args)
T push_back(T... args)
T reserve(T... args)
T size(T... args)
A pixel coordinate made of two integers m_x and m_y.