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   -#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   -