mean_shift.py
Go to the documentation of this file.
1 from __future__ import division
2 from object import Segment as sg
3 import math
4 
5 
6 def mean_shift(h, min_offset, walls):
7  # compute center_clusters with mean-shift. The radian inclinations of the walls are clustered
8  # for each wall set the inclination
9  for wall in walls:
10  direction = sg.radiant_inclination(wall.x1, wall.y1, wall.x2, wall.y2)
11  if direction < -0.26:
12  direction += math.pi
13  elif 0 > direction >= -0.26:
14  direction = -direction
15  wall.set_direction(direction)
16 
17  # compute list of inclination of edges
18  directions = []
19  for wall in walls:
20  directions.append(wall.direction)
21 
22  # initially cluster centers are all the inclinations
23  cluster_centers = directions[:]
24  new_cluster_centers = compute_new_cluster_centers(h, cluster_centers, directions)
25  max_diff = maximum_difference(cluster_centers, new_cluster_centers)
26  cluster_centers = new_cluster_centers[:]
27  del new_cluster_centers[:]
28  while max_diff > min_offset:
29  new_cluster_centers = compute_new_cluster_centers(h, cluster_centers, directions)
30  max_diff = maximum_difference(cluster_centers, new_cluster_centers)
31  cluster_centers = new_cluster_centers[:]
32  del new_cluster_centers[:]
33  return cluster_centers
34 
35 
36 def compute_new_cluster_centers(h, cluster_centers, directions):
37  # compute new cluster_centers starting from those of previous step
38 
39  new_cluster_centers = []
40  for alfa in cluster_centers:
41  numerator = 0
42  # compute numerator
43  for teta in directions:
44  kernel = 0
45  condition = (1-(math.cos(alfa-teta)))/h
46  if condition <= 1:
47  kernel = math.pow(1-condition, 2)
48  tmp = kernel * teta
49  numerator += tmp
50  denominator = 0
51  # compute the denominator
52  for teta in directions:
53  kernel = 0
54  condition = (1-(math.cos(alfa-teta)))/h
55  if condition <= 1:
56  kernel = math.pow(1-condition, 2)
57  denominator += kernel
58  # finally, add new cluster_center to list of new_cluster_centers
59  new_cluster_centers.append(numerator/denominator)
60  return new_cluster_centers
61 
62 
63 def maximum_difference(cluster_centers, new_cluster_centers):
64  # compute maxi difference between new and old cluster_centers to determine if clustering could be considered finished
65 
66  max_diff = 0
67  for index, old in enumerate(cluster_centers):
68  new = new_cluster_centers[index]
69  if abs(new-old) > max_diff:
70  max_diff = abs(new-old)
71  return max_diff
72 
73 
74 def indexes_to_be_deleted(num_min, min_length, cluster_centers, walls_list, diagonals=True):
75  # if DIAGONALS = TRUE DELETE DIAGONALS LINES
76  # trova gli indici di posizione dei cluster angolari causati da un numero di muri < num_min, e con ognuno di questi muri con
77  # lunghezza < lunghezza_min. Questi cluster angolari sono quindi causati da muri che possono essere considerati rumore, quindi elimino
78  # i cluster angolari e i rispetivi muri (indice cluster angolare in cluster_centers = indice muro in lista_muri)
79  indexes = []
80  for cluster in set(cluster_centers):
81  # if angular cluster appear less then num_min in cluster_centers list
82  if cluster_centers.count(cluster) <= num_min:
83  lengths = []
84  candidates = []
85  for index, cluster1 in enumerate(cluster_centers):
86  # for each cluster equal to this cluster (with less then tot occurrences)
87  if cluster == cluster1:
88  candidates.append(index)
89  # take the respective wall (index cluster_centers = index wall_list)
90  m = walls_list[index]
91  lengths.append(sg.length(m.x1, m.y1, m.x2, m.y2))
92  # if all lengths are <= min_length
93  if all_short(lengths, min_length):
94  for i in candidates:
95  indexes.append(i)
96  del candidates[:]
97  del lengths[:]
98  if diagonals:
99  diag = diagonal_indexes(cluster_centers)
100  indexes = indexes + diag
101  return set(indexes)
102 
103 
104 def diagonal_indexes(cluster_centers):
105  # find position indexes of angular diagonal clusters
106 
107  indexes = []
108  for cluster in set(cluster_centers):
109  if not (-0.15 < cluster < 0.15) and not (1.45 < cluster < 1.7) and not (-1.7 < cluster < -1.45):
110  for index, cluster1 in enumerate(cluster_centers):
111  if cluster == cluster1:
112  indexes.append(index)
113  return indexes
114 
115 
116 def all_short(lengths, min_length):
117  # return True if all lengths are less then min_length
118 
119  for length in lengths:
120  if length > min_length:
121  return False
122  return True
123 
124 
125 def merge_similar_cluster(cluster_centers):
126  # some clusters could be very similar. in this case simple average is used.
127 
128  for cluster1 in set(cluster_centers):
129  for cluster2 in set(cluster_centers):
130  if (cluster1 != cluster2) and (abs(cluster1-cluster2) <= 0.01):
131  new_cluster = (cluster1+cluster2)/2
132  # print("merge"+str(c1)+" e "+str(c2)+" in "+str(new_cluster))
133  for index, cluster3 in enumerate(cluster_centers):
134  if(cluster3 == cluster1) or (cluster3 == cluster2):
135  cluster_centers[index] = new_cluster
136  return True
137  return False
mean_shift.mean_shift
def mean_shift(h, min_offset, walls)
Definition: mean_shift.py:6
mean_shift.merge_similar_cluster
def merge_similar_cluster(cluster_centers)
Definition: mean_shift.py:125
mean_shift.compute_new_cluster_centers
def compute_new_cluster_centers(h, cluster_centers, directions)
Definition: mean_shift.py:36
mean_shift.maximum_difference
def maximum_difference(cluster_centers, new_cluster_centers)
Definition: mean_shift.py:63
mean_shift.diagonal_indexes
def diagonal_indexes(cluster_centers)
Definition: mean_shift.py:104
mean_shift.all_short
def all_short(lengths, min_length)
Definition: mean_shift.py:116
mean_shift.indexes_to_be_deleted
def indexes_to_be_deleted(num_min, min_length, cluster_centers, walls_list, diagonals=True)
Definition: mean_shift.py:74


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