Commit 46b42b66e5053b4108f0c7d195ca8c2fec976f9a

Authored by Pierre Lassalle
1 parent de96e0d9
Exists in master

New criteria

Showing 1 changed file with 0 additions and 465 deletions   Show diff stats
Code/lsrmGraphOperations.txx~
@@ -1,465 +0,0 @@ @@ -1,465 +0,0 @@
1 -#ifndef __LSRM_GRAPH_OPERATIONS_TXX  
2 -#define __LSRM_GRAPH_OPERATIONS_TXX  
3 -#include <otbImageFileReader.h>  
4 -  
5 -namespace lsrm  
6 -{  
7 - template<class TSegmenter>  
8 - void GraphOperations<TSegmenter>::InitNodes(ImageType * inputImg,  
9 - GraphType& graph,  
10 - SegmenterType& seg,  
11 - CONNECTIVITY mask)  
12 - {  
13 - unsigned int width, height;  
14 -  
15 - {  
16 - width = inputImg->GetLargestPossibleRegion().GetSize()[0];  
17 - height = inputImg->GetLargestPossibleRegion().GetSize()[1];  
18 - }  
19 -  
20 - const long unsigned int num_nodes = width * height;  
21 -  
22 - graph.m_Nodes.reserve(num_nodes);  
23 -  
24 - for(long unsigned int i = 0;  
25 - i < num_nodes;  
26 - ++i)  
27 - {  
28 - NodePointerType n(new NodeType);  
29 - n->m_Id = i;  
30 - n->m_Valid = true;  
31 - n->m_Expired = false;  
32 - n->m_IsMerged = true; // force to compute costs for the first iteration  
33 - n->m_Perimeter = 4;  
34 - n->m_Area = 1;  
35 - n->m_Bbox.m_UX = i % width;  
36 - n->m_Bbox.m_UY = i / width;  
37 - n->m_Bbox.m_W = 1;  
38 - n->m_Bbox.m_H = 1;  
39 - n->m_Pixels.push_back(i);  
40 - graph.m_Nodes.push_back(n);  
41 - }  
42 -  
43 - if(mask == FOUR)  
44 - {  
45 - for(auto& r : graph.m_Nodes)  
46 - {  
47 - long int neighborhood[4];  
48 - FOURNeighborhood(neighborhood, r->m_Id, width, height);  
49 - for(short j = 0; j < 4; ++j)  
50 - {  
51 - if(neighborhood[j] > -1)  
52 - r->m_Edges.push_back(EdgeType( graph.m_Nodes[neighborhood[j]], 0, 1));  
53 - }  
54 - }  
55 - }  
56 - else  
57 - {  
58 - for(auto& r : graph.m_Nodes)  
59 - {  
60 - long int neighborhood[8];  
61 - EIGHTNeighborhood(neighborhood, r->m_Id, width, height);  
62 - for(short j = 0; j < 8; ++j)  
63 - {  
64 - if(neighborhood[j] > -1)  
65 - {  
66 - if(j % 2 > 0)  
67 - r->m_Edges.push_back(EdgeType( graph.m_Nodes[neighborhood[j]], 0, 0));  
68 - else  
69 - r->m_Edges.push_back(EdgeType( graph.m_Nodes[neighborhood[j]], 0, 1));  
70 - }  
71 - }  
72 - }  
73 - }  
74 - seg.InitFromImage();  
75 - }  
76 -  
77 - template<class TSegmenter>  
78 - void GraphOperations<TSegmenter>::UpdateMergingCosts(GraphType& graph,  
79 - SegmenterType& seg)  
80 - {  
81 - float min_cost;  
82 - long unsigned int min_id;  
83 - std::size_t idx, min_idx;  
84 -  
85 - for(auto& r : graph.m_Nodes)  
86 - {  
87 - for(auto& edge : r->m_Edges)  
88 - edge.m_CostUpdated = false;  
89 - }  
90 -  
91 - for(auto& r : graph.m_Nodes)  
92 - {  
93 - min_cost = std::numeric_limits<float>::max();  
94 - min_id = 0;  
95 - idx = 0;  
96 - min_idx = 0;  
97 -  
98 - r->m_Expired = false;  
99 - r->m_Valid = true;  
100 -  
101 - for(auto& edge : r->m_Edges)  
102 - {  
103 - auto neighborR = edge.GetRegion();  
104 -  
105 - // Compute the cost if necessary  
106 - if(!edge.m_CostUpdated && (neighborR->m_IsMerged || r->m_IsMerged))  
107 - {  
108 - auto edgeFromNeighborToR = FindEdge(neighborR, r);  
109 - edge.m_Cost = seg.ComputeMergingCost(r, neighborR);  
110 - edgeFromNeighborToR->m_Cost = edge.m_Cost;  
111 - edge.m_CostUpdated = true;  
112 - edgeFromNeighborToR->m_CostUpdated = true;  
113 - }  
114 -  
115 - // Check if the cost of the edge is the minimum  
116 - if(min_cost > edge.m_Cost)  
117 - {  
118 - min_cost = edge.m_Cost;  
119 - min_id = neighborR->m_Id;  
120 - min_idx = idx;  
121 - }  
122 - else if(min_cost == edge.m_Cost)  
123 - {  
124 - if(min_id > neighborR->m_Id)  
125 - {  
126 - min_id = neighborR->m_Id;  
127 - min_idx = idx;  
128 - }  
129 - }  
130 - ++idx;  
131 - }  
132 -  
133 - assert(min_idx < r->m_Edges.size());  
134 - std::swap(r->m_Edges[0], r->m_Edges[min_idx]);  
135 -  
136 - }  
137 -  
138 - // Reset the merge flag for all the regions.  
139 - for(auto& r : graph.m_Nodes)  
140 - r->m_IsMerged = false;  
141 - }  
142 -  
143 - template<class TSegmenter>  
144 - typename GraphOperations<TSegmenter>::NodePointerType  
145 - GraphOperations<TSegmenter>::CheckLMBF(NodePointerType a, float t)  
146 - {  
147 - if(a->m_Valid)  
148 - {  
149 - float cost = a->m_Edges.front().m_Cost;  
150 -  
151 - if(cost < t)  
152 - {  
153 - NodePointerType b = a->m_Edges.front().GetRegion();  
154 -  
155 - if( b->m_Valid)  
156 - {  
157 - NodePointerType best_b = b->m_Edges.front().GetRegion();  
158 -  
159 - if(a == best_b)  
160 - {  
161 - if(a->m_Id < b->m_Id)  
162 - return a;  
163 - else  
164 - return b;  
165 - }  
166 - else  
167 - return NodePointerType();  
168 - }  
169 - else  
170 - return NodePointerType();  
171 - }  
172 - else  
173 - return NodePointerType();  
174 - }  
175 - else  
176 - return NodePointerType();  
177 - }  
178 -  
179 - template<class TSegmenter>  
180 - typename GraphOperations<TSegmenter>::NodePointerType  
181 - GraphOperations<TSegmenter>::CheckBF(NodePointerType a, float t)  
182 - {  
183 - if(a->m_Valid)  
184 - {  
185 - float cost = a->m_Edges.front().m_Cost;  
186 -  
187 - if( cost < t )  
188 - {  
189 - NodePointerType b = a->m_Edges.front().GetRegion();  
190 -  
191 - if(b->m_Valid)  
192 - {  
193 - if( a->m_Id < b->m_Id )  
194 - return a;  
195 - else  
196 - return b;  
197 - }  
198 - else  
199 - return NodePointerType();  
200 - }  
201 - else  
202 - return NodePointerType();  
203 - }  
204 - else  
205 - return NodePointerType();  
206 - }  
207 -  
208 - template<class TSegmenter>  
209 - typename GraphOperations<TSegmenter>::EdgeIterator  
210 - GraphOperations<TSegmenter>::FindEdge(NodePointerType n, NodePointerType target)  
211 - {  
212 - return std::find_if(n->m_Edges.begin(), n->m_Edges.end(),[&](EdgeType& e)->bool{  
213 - return e.GetRegion() == target;  
214 - });  
215 - }  
216 -  
217 - template<class TSegmenter>  
218 - void  
219 - GraphOperations<TSegmenter>::UpdateNeighbors(NodePointerType a, NodePointerType b)  
220 - {  
221 - unsigned int boundary;  
222 -  
223 - /* Explore the neighbors of b */  
224 - for (auto& edge : b->m_Edges)  
225 - {  
226 - // Retrieve the edge targeting node b.  
227 - auto neigh_b = edge.GetRegion();  
228 - auto toB = FindEdge(neigh_b, b);  
229 -  
230 - /* If the edge tageting to node b is the first then  
231 - the corresponding node is not valid anymore. */  
232 - if(toB == neigh_b->m_Edges.begin())  
233 - neigh_b->m_Valid = false;  
234 -  
235 - /* Keep in memory the boundary between node b  
236 - and node neigh_b */  
237 - boundary = edge.m_Boundary;  
238 -  
239 - /*  
240 - We can remove safely the edge from node neigh_b  
241 - targeting to node b  
242 - */  
243 - neigh_b->m_Edges.erase(toB);  
244 -  
245 - if(neigh_b != a)  
246 - {  
247 - /* Retrieve the edge targeting to node a. */  
248 - auto toA = FindEdge(neigh_b, a);  
249 -  
250 - if( toA == neigh_b->m_Edges.end() )  
251 - {  
252 - /* No edge exists between node a and node neigh_b. */  
253 -  
254 - /* Add an edge from node neigh_b targeting node a. */  
255 - neigh_b->m_Edges.push_back(EdgeType(a, 0, boundary));  
256 -  
257 - /* Add an edge from node a targeting node neigh_b. */  
258 - a->m_Edges.push_back(EdgeType(neigh_b, 0, boundary));  
259 - }  
260 - else  
261 - {  
262 - /* An edge exists between node a and node neigh_b. */  
263 -  
264 - /* Increment the boundary of the edge from node neigh_b  
265 - targeting to node a. */  
266 - toA->m_Boundary += boundary;  
267 -  
268 - /* Increment the boundary of the edge from node a  
269 - targeting to node neigh_b. */  
270 - auto toNeighB = FindEdge(a, neigh_b);  
271 - toNeighB->m_Boundary += boundary;  
272 - }  
273 - }  
274 -  
275 - }  
276 -  
277 - }  
278 -  
279 - template<class TSegmenter>  
280 - void  
281 - GraphOperations<TSegmenter>::UpdateInternalAttributes(NodePointerType a,  
282 - NodePointerType b,  
283 - const unsigned int width,  
284 - const unsigned int height)  
285 - {  
286 - /* Step 1: update the bounding box */  
287 - a->m_Bbox = MergeBoundingBoxes(a->m_Bbox, b->m_Bbox);  
288 -  
289 - /* Update the list of pixels */  
290 - auto begin = std::make_move_iterator(b->m_Pixels.begin());  
291 - auto end = std::make_move_iterator(b->m_Pixels.end());  
292 - a->m_Pixels.insert(a->m_Pixels.end(), begin, end);  
293 -  
294 - /* Step 2 : update perimeter and area attributes */  
295 - EdgeIterator toB = FindEdge(a, b);  
296 - a->m_Perimeter += (b->m_Perimeter - 2 * toB->m_Boundary);  
297 - a->m_Area += b->m_Area;  
298 -  
299 - /* Step 2: update the neighborhood */  
300 - UpdateNeighbors(a,b);  
301 -  
302 - /* Step 3: update the node' states */  
303 - a->m_Valid = false;  
304 - b->m_Valid = false;  
305 - b->m_Expired = true;  
306 - a->m_IsMerged = true;  
307 - }  
308 -  
309 - template<class TSegmenter>  
310 - void  
311 - GraphOperations<TSegmenter>::RemoveExpiredNodes(GraphType& graph)  
312 - {  
313 - NodeIterator nit = std::remove_if(graph.m_Nodes.begin(), graph.m_Nodes.end(), [](NodePointerType r)->bool{  
314 - return r->m_Expired;  
315 - });  
316 - graph.m_Nodes.erase(nit, graph.m_Nodes.end());  
317 - }  
318 -  
319 - template<class TSegmenter>  
320 - bool  
321 - GraphOperations<TSegmenter>::PerfomOneIterationWithLMBF(GraphType& graph,  
322 - SegmenterType& seg,  
323 - const float threshold,  
324 - const unsigned int width,  
325 - const unsigned int height)  
326 - {  
327 - bool merged = false;  
328 -  
329 - /* Update the costs of merging between adjacent nodes */  
330 - UpdateMergingCosts(graph, seg);  
331 -  
332 - for(auto& region : graph.m_Nodes)  
333 - {  
334 -  
335 - auto res_node = CheckLMBF(region, threshold);  
336 -  
337 - if(res_node)  
338 - {  
339 - seg.UpdateSpecificAttributes(res_node, res_node->m_Edges.front().GetRegion());  
340 - UpdateInternalAttributes(res_node, res_node->m_Edges.front().GetRegion(),  
341 - width, height);  
342 - merged = true;  
343 - }  
344 - }  
345 -  
346 - RemoveExpiredNodes(graph);  
347 -  
348 - if(graph.m_Nodes.size() < 2)  
349 - return false;  
350 -  
351 - return merged;  
352 - }  
353 -  
354 - template<class TSegmenter>  
355 - bool  
356 - GraphOperations<TSegmenter>::PerfomOneIterationWithBF(GraphType& graph,  
357 - SegmenterType& seg,  
358 - const float threshold,  
359 - const unsigned int width,  
360 - const unsigned int height)  
361 - {  
362 - bool merged = false;  
363 -  
364 - /* Update the costs of merging between adjacent nodes */  
365 - UpdateMergingCosts(graph, seg);  
366 -  
367 - for(auto& region : graph.m_Nodes)  
368 - {  
369 - NodePointerType res_node = CheckBF(region, threshold);  
370 -  
371 - if(res_node)  
372 - {  
373 - seg.UpdateSpecificAttributes(res_node, res_node->m_Edges.front().GetRegion());  
374 - UpdateInternalAttributes(res_node, res_node->m_Edges.front().GetRegion(),  
375 - width, height);  
376 - merged = true;  
377 - }  
378 - }  
379 -  
380 - RemoveExpiredNodes(graph);  
381 -  
382 - if(graph.m_Nodes.size() < 2)  
383 - return false;  
384 -  
385 - return merged;  
386 - }  
387 -  
388 - template<class TSegmenter>  
389 - bool  
390 - GraphOperations<TSegmenter>::PerfomAllIterationsWithLMBFAndConstThreshold(GraphType& graph,  
391 - SegmenterType& seg,  
392 - const float threshold,  
393 - const unsigned int numberOfIterations,  
394 - const unsigned int width,  
395 - const unsigned int height)  
396 - {  
397 - bool merged = true;  
398 - unsigned int iterations = 0;  
399 -  
400 - while(merged &&  
401 - iterations < numberOfIterations &&  
402 - graph.m_Nodes.size() > 1)  
403 - {  
404 - std::cout << "." << std::flush;  
405 - ++iterations;  
406 -  
407 - merged = PerfomOneIterationWithLMBF(graph, seg, threshold,  
408 - width, height);  
409 - }  
410 - std::cout << std::endl;  
411 -  
412 - if(graph.m_Nodes.size() < 2)  
413 - return false;  
414 -  
415 - return merged;  
416 - }  
417 -  
418 - template<class TSegmenter>  
419 - bool  
420 - GraphOperations<TSegmenter>::PerfomAllIterationsWithBFAndConstThreshold(GraphType& graph,  
421 - SegmenterType& seg,  
422 - const float threshold,  
423 - const unsigned int numberOfIterations,  
424 - const unsigned int width,  
425 - const unsigned int height)  
426 - {  
427 - bool merged = true;  
428 - unsigned int maxNumberOfIterations;  
429 - if(numberOfIterations < 1)  
430 - maxNumberOfIterations = 75;  
431 - else  
432 - maxNumberOfIterations = numberOfIterations;  
433 -  
434 - unsigned int iterations = 0;  
435 -  
436 - while(merged &&  
437 - iterations < maxNumberOfIterations &&  
438 - graph.m_Nodes.size() > 1)  
439 - {  
440 - std::cout << "." << std::flush;  
441 - ++iterations;  
442 -  
443 - merged = PerfomOneIterationWithBF(graph, seg, threshold,  
444 - width, height);  
445 - }  
446 - std::cout << std::endl;  
447 -  
448 - if(graph.m_Nodes.size() < 2)  
449 - return false;  
450 -  
451 - return merged;  
452 - }  
453 -  
454 -  
455 -} // end of namespace lsrm  
456 -  
457 -#endif  
458 -  
459 -  
460 -  
461 -  
462 -  
463 -  
464 -  
465 -