ExtendedSegment.py
Go to the documentation of this file.
1 # this class is the same as Line except for the fact that the segment has a start and an end
2 # due to the Border box of image (offset)
3 
4 from __future__ import division
5 import numpy as np
6 import math
7 
8 
9 class ExtendedSegment(object):
10  def __init__(self, point1, point2, angular_cluster, spatial_cluster):
11  self.x1 = point1[0]
12  self.y1 = point1[1]
13  self.x2 = point2[0]
14  self.y2 = point2[1]
15  self.angular_cluster = angular_cluster
16  self.spatial_cluster = spatial_cluster
17  self.weight = None
18  self.rooms_coverage = None
19 
20  def set_weight(self, weight):
21  self.weight = weight
22 
23  # number of rooms that touch
24  def set_coverage(self, number_of_rooms):
25  self.rooms_coverage = number_of_rooms
26 
27 
28 def create_extended_segments(x_min, x_max, y_min, y_max, extended_lines):
29  # create an extended_segment for each extended_line, as intersection between extended_line and bounding box
30  extended_seg = []
31  for line in extended_lines:
32  # horizontal
33  if line.angular_cluster == 0:
34  point2 = np.array([x_max, line.point[1]])
35  seg = ExtendedSegment(line.point, point2, line.angular_cluster, line.spatial_cluster)
36  extended_seg.append(seg)
37  # vertical
38  elif line.angular_cluster == math.radians(90):
39  point2 = np.array([line.point[0], y_max])
40  seg = ExtendedSegment(line.point, point2, line.angular_cluster, line.spatial_cluster)
41  extended_seg.append(seg)
42  # oblique
43  else:
44  m = math.tan(line.angular_cluster)
45  q = line.point[1] - (m*line.point[0])
46  y_for_x_min = m * x_min + q
47  y_for_x_max = m * x_max + q
48  x_for_y_min = (y_min - q) / m
49  x_for_y_max = (y_max - q) / m
50  if line.angular_cluster < 0 or line.angular_cluster * 180/math.pi > 90:
51  if y_max < y_for_x_min:
52  point1 = np.array([x_for_y_max, y_max])
53  else:
54  point1 = np.array([x_min, y_for_x_min])
55  if y_min > y_for_x_max:
56  point2 = np.array([x_for_y_min, y_min])
57  else:
58  point2 = np.array([x_max, y_for_x_max])
59  else:
60  if y_for_x_min > y_min:
61  point1 = np.array([x_min, y_for_x_min])
62  else:
63  point1 = np.array([x_for_y_min, y_min])
64  if y_for_x_max < y_max:
65  point2 = np.array([x_max, y_for_x_max])
66  else:
67  point2 = np.array([x_for_y_max, y_max])
68  seg = ExtendedSegment(point1, point2, line.angular_cluster, line.spatial_cluster)
69  extended_seg.append(seg)
70  point1 = np.array([x_min, y_min])
71  point2 = np.array([x_min, y_max])
72  point3 = np.array([x_max, y_max])
73  point4 = np.array([x_max, y_min])
74  seg1 = ExtendedSegment(point1, point2, None, 'bordo1')
75  seg2 = ExtendedSegment(point2, point3, None, 'bordo2')
76  seg3 = ExtendedSegment(point4, point3, None, 'bordo3')
77  seg4 = ExtendedSegment(point1, point4, None, 'bordo4')
78  extended_seg.extend((seg1, seg2, seg3, seg4))
79  return extended_seg
80 
81 
82 # this function create the set of extended segment starting from a set of edges.
83 def create_extended_from_edges(edges, x_min, y_min, x_max, y_max):
84  extended_lines = []
85  for edge in edges:
86  # horizontal edge
87  if edge.angular_cluster == 0:
88  point1 = np.array([x_min, edge.y1])
89  point2 = np.array([x_max, edge.y1])
90  # vertical edge
91  elif edge.angular_cluster == math.radians(90):
92  point1 = np.array([edge.x1, y_min])
93  point2 = np.array([edge.x1, y_max])
94  # oblique edge
95  else:
96  m = math.tan(edge.angular_cluster)
97  q = edge.y1 - (m * edge.x1)
98  y_for_x_min = m * x_min + q
99  y_for_x_max = m * x_max + q
100  x_for_y_min = (y_min - q) / m
101  x_for_y_max = (y_max - q) / m
102  if edge.angular_cluster < 0 or edge.angular_cluster * 180 / math.pi > 90:
103  if y_max < y_for_x_min:
104  point1 = np.array([x_for_y_max, y_max])
105  else:
106  point1 = np.array([x_min, y_for_x_min])
107  if y_min > y_for_x_max:
108  point2 = np.array([x_for_y_min, y_min])
109  else:
110  point2 = np.array([x_max, y_for_x_max])
111  else:
112  if y_for_x_min > y_min:
113  point1 = np.array([x_min, y_for_x_min])
114  else:
115  point1 = np.array([x_for_y_min, y_min])
116  if y_for_x_max < y_max:
117  point2 = np.array([x_max, y_for_x_max])
118  else:
119  point2 = np.array([x_for_y_max, y_max])
120  # TODO CHECK IF AN EXTENDED SEGMENT IS ALREADY PRESENT IN THIS LIST
121  line = ExtendedSegment(point1, point2, edge.angular_cluster, edge.spatial_cluster)
122  extended_lines.append(line)
123  return extended_lines
124 
125 
126 # this function is used to sort the list by weight
127 def sort_weight(val):
128  return val.weight
129 
130 
131 # this function is used to divide the extended segments by m
132 def divide_segments(extended_segments):
133  clusters = []
134  ang = []
135  for seg in extended_segments:
136  angular_cluster = seg.angular_cluster
137  if angular_cluster not in ang:
138  ang.append(angular_cluster)
139  for a in ang:
140  tmp = []
141  for s in extended_segments:
142  if s.angular_cluster == a:
143  tmp.append(s)
144  clusters.append(tmp)
145  return clusters
146 
147 
148 def point_point_distance(seg1, seg2):
149  m = seg1.angular_cluster
150  m_perp = -1 / m
151  q1 = (-m * seg1.x1 + seg1.y1)
152  q_p = (-m_perp * seg2.x1 + seg2.y1)
153  x = (q1 - q_p) / (m_perp - m)
154  y = (m_perp * x) + q_p
155  distance = math.sqrt((seg2.x1 - x)*(seg2.x1 - x) + (seg2.x1 - y)*(seg2.x1 - y))
156  return distance
157 
158 
159 def point_line_distance(segment1, x1, y1):
160  if segment1.x2 - segment1.x1 == 0:
161  distance = math.fabs(segment1.x1 - x1)
162  else:
163  m = (segment1.y2 - segment1.y1)/(segment1.x2 - segment1.x1)
164  q = -m*segment1.x1 + segment1.y1
165  distance = math.fabs(y1 - m*x1 - q)/math.sqrt(1 + m*m)
166  return distance
167 
168 
169 # this function is used to get the cluster of extended segments very close each others.
170 def get_clusters(extended_segments, distance):
171  merged_segments = []
172  # create a structure like this: [[1,2,3][5,6][7,8]] where each element is a cluster of near extended segments
173  for i1, segment1 in enumerate(extended_segments):
174  for i2 in range(i1+1, len(extended_segments)):
175  segment2 = extended_segments[i2]
176  # if are parallel. and not offset extended segments.
177  if segment1.angular_cluster == segment2.angular_cluster:
178  real_distance = point_line_distance(segment1, segment2.x1, segment2.y1)
179  if real_distance < distance:
180  # print real_distance, ' ', i1, ' ', i2
181  if len(merged_segments) == 0:
182  merged_segments.append([segment1, segment2])
183  # merged_segments.append([i1, i2])
184  else:
185  index_1 = -1
186  index_2 = -1
187  for i, elem in enumerate(merged_segments):
188  if segment1 in elem:
189  index_1 = i
190  # if segment2 not in elem:
191  # elem.append(segment2)
192  # elem.append(i2)
193  # index = 1
194  if segment2 in elem:
195  index_2 = i
196  # elif segment2 in elem:
197  # if segment1 not in elem:
198  # elem.append(segment1)
199  # elem.append(i1)
200  # index = 1
201  if index_1 == index_2 == -1:
202  merged_segments.append([segment1, segment2])
203  if index_1 == -1 and index_2 != -1:
204  merged_segments[index_2].append(segment1)
205  if index_1 != -1 and index_2 == -1:
206  merged_segments[index_1].append(segment2)
207  if index_1 != index_2 and index_1 != -1 and index_2 != -1:
208  cluster1 = merged_segments[index_1]
209  cluster2 = merged_segments[index_2]
210  cluster3 = cluster1 + cluster2
211  merged_segments.remove(cluster1)
212  merged_segments.remove(cluster2)
213  merged_segments.append(cluster3)
214  # if index == 0:
215  # merged_segments.append([segment1, segment2])
216  # merged_segments.append([i1, i2])
217  return merged_segments
218 
219 
220 def reallocate_walls(seg1, seg2, walls):
221  for wall in walls:
222  if wall.spatial_cluster == seg2.spatial_cluster:
223  wall.set_spatial_cluster(seg1.spatial_cluster)
224 
225 
226 # this function is used to remove the extended segments very close each other by removing the less significant
227 def merge_together(extended_segments, distance, walls):
228  extended_segments_v2 = []
229  for seg in extended_segments:
230  if seg.angular_cluster is not None:
231  extended_segments_v2.append(seg)
232  segments = divide_segments(extended_segments_v2)
233  # merge all clusters into this structure: [[1,2,3],[4,5],[6,7,8],[9,10]] by angular cluster.
234  # note that one segment con appear in only one cluster.
235  merged_segments = []
236  for el in segments:
237  cl = get_clusters(el, distance)
238  merged_segments = merged_segments + cl
239  seg_to_remove = []
240  for cluster in merged_segments:
241  # sort each cluster by segment weight. from most significant to less significant.
242  cluster.sort(key=sort_weight, reverse=True)
243  for j1, seg1 in enumerate(cluster):
244  for j2 in range(j1+1, len(cluster)):
245  seg2 = cluster[j2]
246  if not (seg1 is None or seg2 is None):
247  dist = point_line_distance(seg1, seg2.x1, seg2.y1)
248  if dist < distance:
249  reallocate_walls(seg1, seg2, walls)
250  seg_to_remove.append(seg2)
251  cluster[j2] = None
252  for seg in seg_to_remove:
253  try:
254  extended_segments_v2.remove(seg)
255  except:
256  print('segment already removed')
257  for seg in extended_segments:
258  try:
259  if seg.angular_cluster is None:
260  extended_segments_v2.append(seg)
261  except:
262  print('segment already removed')
263  return extended_segments_v2
ExtendedSegment.ExtendedSegment.x1
x1
Definition: ExtendedSegment.py:11
ExtendedSegment.ExtendedSegment.x2
x2
Definition: ExtendedSegment.py:13
ExtendedSegment.ExtendedSegment.spatial_cluster
spatial_cluster
Definition: ExtendedSegment.py:16
ExtendedSegment.ExtendedSegment.angular_cluster
angular_cluster
Definition: ExtendedSegment.py:15
ExtendedSegment.ExtendedSegment.__init__
def __init__(self, point1, point2, angular_cluster, spatial_cluster)
Definition: ExtendedSegment.py:10
ExtendedSegment.ExtendedSegment.rooms_coverage
rooms_coverage
Definition: ExtendedSegment.py:18
ExtendedSegment.ExtendedSegment
Definition: ExtendedSegment.py:9
ExtendedSegment.reallocate_walls
def reallocate_walls(seg1, seg2, walls)
Definition: ExtendedSegment.py:220
ExtendedSegment.divide_segments
def divide_segments(extended_segments)
Definition: ExtendedSegment.py:132
ExtendedSegment.create_extended_from_edges
def create_extended_from_edges(edges, x_min, y_min, x_max, y_max)
Definition: ExtendedSegment.py:83
ExtendedSegment.merge_together
def merge_together(extended_segments, distance, walls)
Definition: ExtendedSegment.py:227
ExtendedSegment.create_extended_segments
def create_extended_segments(x_min, x_max, y_min, y_max, extended_lines)
Definition: ExtendedSegment.py:28
ExtendedSegment.sort_weight
def sort_weight(val)
Definition: ExtendedSegment.py:127
ExtendedSegment.ExtendedSegment.y1
y1
Definition: ExtendedSegment.py:12
ExtendedSegment.ExtendedSegment.set_weight
def set_weight(self, weight)
Definition: ExtendedSegment.py:20
ExtendedSegment.get_clusters
def get_clusters(extended_segments, distance)
Definition: ExtendedSegment.py:170
ExtendedSegment.point_point_distance
def point_point_distance(seg1, seg2)
Definition: ExtendedSegment.py:148
ExtendedSegment.ExtendedSegment.y2
y2
Definition: ExtendedSegment.py:14
ExtendedSegment.point_line_distance
def point_line_distance(segment1, x1, y1)
Definition: ExtendedSegment.py:159
ExtendedSegment.ExtendedSegment.weight
weight
Definition: ExtendedSegment.py:17
ExtendedSegment.ExtendedSegment.set_coverage
def set_coverage(self, number_of_rooms)
Definition: ExtendedSegment.py:24


rose2
Author(s): Gabriele Somaschini, Matteo Luperto
autogenerated on Wed Jun 28 2023 02:21:53