SourceXtractorPlusPlus  0.16
Please provide a description of the project.
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
65  if (merged.size() == 1) {
66  return { source };
67  } 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 
74  sources.push_back(new_source);
75  }
76  return sources;
77  }
78 }
79 
84 
85  PixelCoordinate offsets[5] {
86  PixelCoordinate( 0, 0),
87  PixelCoordinate(-1, 0),
88  PixelCoordinate( 0, -1),
89  PixelCoordinate( 1, 0),
90  PixelCoordinate( 0, 1)
91  };
92 
93  if (pixels_with_origin.size() == 0) {
94  return;
95  }
96 
98 
99  for (auto& pixel_origin : pixels_with_origin) {
100  auto pixel = pixel_origin.first;
101  auto origin = pixel_origin.second;
102 
103  DetectionImage::PixelType values[5];
104  for (int i=0; i<5; i++) {
105  values[i] = value_function(pixel + offsets[i]);
106  }
107 
108  size_t max = 0;
109  for (int i=1; i<3; i++) {
110  if (values[i] > values[max]) {
111  max = i;
112  }
113  }
114  for (int i=3; i<5; i++) {
115  if (values[i] >= values[max]) {
116  max = i;
117  }
118  }
119 
120  if (max == 0) {
121  // We are at the attractor pixel
122  attractors[pixel].push_back(origin);
123  } else {
124  pixels_to_be_processed.push_back(
125  std::pair<PixelCoordinate, PixelCoordinate>(pixel + offsets[max], origin));
126  }
127  }
128  attractPixels(pixels_to_be_processed, attractors, value_function);
129 }
130 
136 
137  for (auto& attractor : attractors) {
138  auto coord = attractor.first;
139  auto& pixels = attractor.second;
140  bool done = false;
141 
142  for (size_t i=0; i < merged.size(); i++) {
143  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) {
144  bbox_min[i] = PixelCoordinate(std::min(coord.m_x, bbox_min[i].m_x), std::min(coord.m_y, bbox_min[i].m_y));
145  bbox_max[i] = PixelCoordinate(std::max(coord.m_x, bbox_max[i].m_x), std::max(coord.m_y, bbox_max[i].m_y));
146  merged[i].insert(merged[i].begin(), pixels.begin(), pixels.end());
147  done = true;
148  break;
149  }
150  }
151  if (!done) {
152  merged.push_back(pixels);
153  bbox_min.push_back(coord);
154  bbox_max.push_back(coord);
155  }
156  }
157  return merged;
158 }
159 
160 } // SEImplementation namespace
161 
162 
163 
T begin(T... args)
virtual std::vector< std::shared_ptr< SourceInterface > > partition(std::shared_ptr< SourceInterface > source) const override
std::shared_ptr< SourceFactory > m_source_factory
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
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 push_back(T... args)
T reserve(T... args)
T size(T... args)
A pixel coordinate made of two integers m_x and m_y.