SourceXtractorPlusPlus  0.19
SourceXtractor++, the next generation SExtractor
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AttractorsPartitionStep.cpp
Go to the documentation of this file.
1 
22 #include <limits>
23 
27 
32 
33 namespace 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 
102  DetectionImage::PixelType values[5];
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 
std::vector< std::unique_ptr< SourceInterface > > partition(std::unique_ptr< SourceInterface > source) const override
The bounding box of all the pixels in the source. Both min and max coordinate are inclusive...
const DetectionVectorImage & getStamp() const
std::vector< std::vector< PixelCoordinate > > mergeAttractors(const std::unordered_map< PixelCoordinate, std::vector< PixelCoordinate >> &attractors) const
T min(T...args)
T push_back(T...args)
T lowest(T...args)
A copy of the rectangular region of the detection image just large enough to include the whole Source...
T max(T...args)
A pixel coordinate made of two integers m_x and m_y.
T move(T...args)
T insert(T...args)
T size(T...args)
STL class.
STL class.
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
T begin(T...args)
std::shared_ptr< SourceFactory > m_source_factory
T reserve(T...args)
T emplace_back(T...args)