SourceXtractorPlusPlus  0.15
Please provide a description of the project.
Lutz.cpp
Go to the documentation of this file.
1 
17 /*
18  * Lutz.cpp
19  *
20  * Created on: Jan 17, 2017
21  * Author: mschefer
22  */
23 
24 
29 
33 
35 
36 namespace SourceXtractor {
37 
38 // class Lutz
39 //
40 // Note: this implementation uses an 8-way connection (including corners)
41 
42 
43 enum class LutzStatus {
44  COMPLETE = 0,
45  INCOMPLETE,
46  NONOBJECT,
47  OBJECT
48 };
49 
50 enum class LutzMarker {
51  ZERO = 0,
52  S,
53  S0,
54  F,
55  F0
56 };
57 
58 
59 void Lutz::labelImage(LutzListener& listener, const DetectionImage& image, PixelCoordinate offset) {
60  int width = image.getWidth() + 1; // one extra pixel
61 
62  std::vector<LutzMarker> marker(image.getWidth()+1);
63  std::fill(marker.begin(), marker.end(), LutzMarker::ZERO);
64 
65  std::vector<PixelGroup> group_stack;
66  std::vector<LutzStatus> ps_stack;
67 
69  //std::shared_ptr<VectorImage<unsigned int>> check_image=VectorImage<unsigned int>::create(image.getWidth(), image.getHeight());
70 
71  int lines = image.getHeight();
72  int chunk_height = TileManager::getInstance()->getTileHeight();
74 
75  for (int y = 0; y < lines; y++) {
78 
79  if (y % chunk_height == 0) {
80  chunk = image.getChunk(0, y, image.getWidth(), std::min(chunk_height, lines - y));
81  }
82 
83  int dy = y % chunk_height;
84  for (int x=0; x < width; x++) {
85  DetectionImage::PixelType value = (x == width - 1) ? 0.0 : chunk->getValue(x, dy);
86 
87  LutzMarker last_marker = marker[x];
88  marker[x] = LutzMarker::ZERO;
89 
90  bool in_object = value > 0.0;
91  if (in_object) {
92  // We have an object pixel
93  //check_image->setValue(x, y, 1);
94  if (cs != LutzStatus::OBJECT) {
95  // Previous pixel not object, start new segment
96 
97  cs = LutzStatus::OBJECT;
98 
99  if (ps == LutzStatus::OBJECT) {
100  // Pixel touches segment on preceding scan
101 
102  if (group_stack.back().start == -1) {
103  // First pixel of object on current scan
104  marker[x] = LutzMarker::S;
105  group_stack.back().start = x;
106  } else {
107  marker[x] = LutzMarker::S0;
108  }
109  } else {
110  // Start of completely new pixel group
111  ps_stack.push_back(ps);
113  group_stack.emplace_back();
114  marker[x] = LutzMarker::S;
115  group_stack.back().start = x;
116  }
117  }
118  }
119 
120  if (last_marker != LutzMarker::ZERO) {
121  // There is a marker from the previous scan to process
122  // This is done for both object and non-object pixels
123 
124  if (last_marker == LutzMarker::S) {
125  // Start of pixel group on preceding scan
126  ps_stack.push_back(ps);
127  if (cs == LutzStatus::NONOBJECT) {
128  // The S marker is the first encounter with this group
130 
131  group_stack.emplace_back(std::move(inc_group_map.at(x)));
132  inc_group_map.erase(x);
133 
134  group_stack.back().start = -1;
135  } else {
136  // Add group to current group
137  auto prev_group = inc_group_map.at(x);
138  inc_group_map.erase(x);
139 
140  group_stack.back().merge_pixel_list(prev_group);
141  }
142  ps = LutzStatus::OBJECT;
143  }
144 
145  if (last_marker == LutzMarker::S0) {
146  // Start of secondary segment of group on preceding scan
147 
148  if (cs == LutzStatus::OBJECT && ps == LutzStatus::COMPLETE) {
149  // Current group is joined to preceding group
150  ps_stack.pop_back();
151  auto old_group = std::move(group_stack.back());
152  group_stack.pop_back();
153  group_stack.back().merge_pixel_list(old_group);
154 
155  if (group_stack.back().start == -1) {
156  group_stack.back().start = old_group.start;
157  } else {
158  marker[old_group.start] = LutzMarker::S0;
159  }
160  }
161  ps = LutzStatus::OBJECT;
162  }
163 
164  if (last_marker == LutzMarker::F0) {
166  }
167 
168  if (last_marker == LutzMarker::F) {
169 
170 
171  ps = ps_stack.back();
172  ps_stack.pop_back();
173 
174  if (cs == LutzStatus::NONOBJECT && ps == LutzStatus::COMPLETE) {
175  // If no more of current group to come then finish it
176  auto old_group = std::move(group_stack.back());
177  group_stack.pop_back();
178  if (old_group.start == -1) {
179  // Pixel group completed
180  listener.publishGroup(old_group);
181  } else {
182  marker[old_group.end] = LutzMarker::F;
183  inc_group_map[old_group.start] = old_group;
184  }
185  ps = ps_stack.back();
186  ps_stack.pop_back();
187  }
188  }
189  }
190 
191  if (in_object) {
192  // Update current group by current pixel
193  group_stack.back().pixel_list.push_back(PixelCoordinate(x, y) + offset);
194 
195  } else {
196  // The current pixel is not object
197 
198  if (cs == LutzStatus::OBJECT) {
199  // Previous pixel was object. Finish segment
201 
202  if (ps != LutzStatus::COMPLETE) {
203  // End of segment but not necessarily of section
204  marker[x] = LutzMarker::F0;
205  group_stack.back().end = x;
206  } else {
207  // End of final segment of group section
208  ps = ps_stack.back();
209  ps_stack.pop_back();
210 
211  marker[x] = LutzMarker::F;
212 
213  auto old_group = group_stack.back();
214  group_stack.pop_back();
215 
216  inc_group_map[old_group.start] = old_group;
217  }
218  }
219  }
220  }
221  listener.notifyProgress(y + 1, lines);
222  }
223 
224  //FitsWriter::writeFile<unsigned int>(*check_image, "segCheck.fits");
225  // Process the pixel groups left in the inc_group_map
226  for (auto& group : inc_group_map) {
227  listener.publishGroup(group.second);
228  }
229 }
230 
231 void LutzList::publishGroup(PixelGroup& pixel_group) {
232  m_groups.push_back(pixel_group);
233 }
234 
235 
236 }
std::shared_ptr< DependentParameter< std::shared_ptr< EngineParameter > > > x
std::shared_ptr< DependentParameter< std::shared_ptr< EngineParameter > > > y
std::shared_ptr< EngineParameter > dy
T at(T... args)
T back(T... args)
T begin(T... args)
Interface representing an image.
Definition: Image.h:43
virtual std::shared_ptr< ImageChunk< T > > getChunk(int x, int y, int width, int height) const =0
virtual int getHeight() const =0
Returns the height of the image in pixels.
virtual int getWidth() const =0
Returns the width of the image in pixels.
virtual void publishGroup(PixelGroup &pixel_group) override
Definition: Lutz.cpp:231
std::vector< PixelGroup > m_groups
Definition: Lutz.h:83
virtual void notifyProgress(int, int)
Definition: Lutz.h:56
virtual void publishGroup(PixelGroup &pixel_group)=0
std::vector< PixelCoordinate > pixel_list
Definition: Lutz.h:44
void merge_pixel_list(PixelGroup &other)
Definition: Lutz.h:48
void labelImage(LutzListener &listener, const DetectionImage &image, PixelCoordinate offset=PixelCoordinate(0, 0))
Definition: Lutz.cpp:59
static std::shared_ptr< TileManager > getInstance()
T emplace_back(T... args)
T end(T... args)
T erase(T... args)
T fill(T... args)
T min(T... args)
T move(T... args)
T pop_back(T... args)
T push_back(T... args)
A pixel coordinate made of two integers m_x and m_y.