segment-graph.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /*
  2. Copyright (C) 2006 Pedro Felzenszwalb
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  14. */
  15. #ifndef SEGMENT_GRAPH
  16. #define SEGMENT_GRAPH
  17. #include <algorithm>
  18. #include <cmath>
  19. #include "disjoint-set.h"
  20. // threshold function
  21. #define THRESHOLD(size, c) (c/size)
  22. typedef struct {
  23. float w;
  24. int a, b;
  25. } edge;
  26. bool operator<(const edge &a, const edge &b) {
  27. return a.w < b.w;
  28. }
  29. /**
  30. * @brief Segment a graph, a disjoint-set forest representing the segmentation
  31. * @author Pedro Felzenszwalb, Alexander Freytag
  32. * @date 27-03-2014 ( dd-mm-yyyy, last updated)
  33. *
  34. * @param[in] i_numVertices: number of vertices in graph
  35. * @param[in] i_numEdges: number of edges in graph
  36. * @param[in] edges: array of edges
  37. * @param[in] c: constant for treshold function
  38. *
  39. * @param[out] u universe (disjoint-set forest representing the segmentation)
  40. */
  41. universe *segment_graph( const int i_numVertices,
  42. const int i_numEdges,
  43. edge *edges,
  44. const float c
  45. )
  46. {
  47. // sort edges by weight
  48. // note: if weights occure more then once, this might lead to non-deterministic (non-reproducable) behaviour, since
  49. // "Equivalent elements are not guaranteed to keep their original relative order"
  50. // std::sort(edges, edges + i_numEdges);
  51. // adaptation: use stable_sort instead, which will keep the relative position of equal elements :)
  52. std::stable_sort(edges, edges + i_numEdges);
  53. // make a disjoint-set forest
  54. universe *u = new universe(i_numVertices);
  55. // init thresholds
  56. float *threshold = new float[i_numVertices];
  57. for (int i = 0; i < i_numVertices; i++)
  58. {
  59. threshold[i] = THRESHOLD(1,c);
  60. }
  61. // for each edge, in non-decreasing weight order...
  62. for (int i = 0; i < i_numEdges; i++)
  63. {
  64. edge *pedge = &edges[i];
  65. // components conected by this edge
  66. int a = u->find(pedge->a);
  67. int b = u->find(pedge->b);
  68. if (a != b)
  69. {
  70. if ( (pedge->w <= threshold[a]) && (pedge->w <= threshold[b]) )
  71. {
  72. u->join(a, b);
  73. a = u->find(a);
  74. threshold[a] = pedge->w + THRESHOLD(u->size(a), c);
  75. }
  76. }
  77. }
  78. // free up
  79. delete threshold;
  80. return u;
  81. }
  82. #endif