SourceXtractorPlusPlus 1.0.3
SourceXtractor++, the next generation SExtractor
Loading...
Searching...
No Matches
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
36namespace SourceXtractor {
37
38// class Lutz
39//
40// Note: this implementation uses an 8-way connection (including corners)
41
42
49
50enum class LutzMarker {
51 ZERO = 0,
56};
57
58
59void 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;
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
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 }
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 }
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
232 m_groups.push_back(pixel_group);
233}
234
235
236}
T at(T... args)
T back(T... args)
T begin(T... args)
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 std::shared_ptr< ImageChunk< T > > getChunk(int x, int y, int width, int height) const =0
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
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)
Image< SeFloat > DetectionImage
Alias for the detection image, to make easier its type modification.
Definition Image.h:80
T pop_back(T... args)
T push_back(T... args)
A pixel coordinate made of two integers m_x and m_y.