def Q_split(edge_in_comune): ''' calcola il Q_split come definito nel paper di mura. rappresenta la qualita' dello splitting ''' num = 0 den = 0 for e in edge_in_comune: num = num + (e.weight * sg.lunghezza(e.x1, e.y1, e.x2, e.y2)) den = den + sg.lunghezza(e.x1, e.y1, e.x2, e.y2) q_split = num / den return q_split
def indici_da_eliminare(num_min, lunghezza_min, cluster_centers, lista_muri): ''' trova gli indici di posizione dei cluster angolari causati da un numero di muri < num_min, e con ognuno di questi muri con lunghezza < lunghezza_min. Questi cluster angolari sono quindi causati da muri che possono essere considerati rumore, quindi elimino i cluster angolari e i rispetivi muri (indice cluster angolare in cluster_centers = indice muro in lista_muri) ''' indexes = [] for c in set(cluster_centers): if ( cluster_centers.count(c) <= num_min ): #se il cluster angolare compare meno di tot volte nella lista cluster_centers lunghezze = [] candidati = [] for index, c1 in enumerate(cluster_centers): if c == c1: #per ogni cluster uguale al cluster in questione (con meno di tot occorrenze) candidati.append(index) #prendo il rispettivo muro (index cluster_centers = index lista_muri) m = lista_muri[index] lunghezze.append(sg.lunghezza(m.x1, m.y1, m.x2, m.y2)) if tutti_corti(lunghezze, lunghezza_min ): #se tutte le lunghezze sono <= lunghezza_min for i in candidati: indexes.append(i) del candidati[:] del lunghezze[:] diag = indici_diagonali(cluster_centers) indexes = indexes + diag return set(indexes)
def separaUndersegmentazione(plan_o, critical_points, parametri_obj, path_obj, xmin, ymin, xmax, ymax): ''' permette di separare le stanze undersegmentate. in primis una stanza e' stata undersegmentata se esistono almeno 2 celle che la compongono che si toccano ed il peso di quella cella e' superiore a 0.3. ''' print "il numero di critical points e '", len(critical_points) stanze = plan_o.spazi conta = 0 #in sostanza vado a chiudere le porte for stanza in stanze: #queste due liste mi servono per ricordarmi il vecchio valore dell'edge per poi risettarlo vecchio_valore_edge = [] #lista dei velori numerici dei singoli edge edge_modificato = [] #oggetto di tipo edge cellette_stanza = stanza.cells trovato = False #controllo per vedere se la stanza e' stata undersegmentata for c1 in cellette_stanza: for c2 in cellette_stanza: if fc.adiacenti(c1.c, c2.c) and c1 != c2: if ( fc.edge_comune(c1.c, c2.c)[0].weight >= 0.3 ): #il bordo in comune non deve essere supportato da segmenti(se questo avviene in una stanza significa che e' stata eliminata una parete che in teoria era stata gia' vista) trovato = True if trovato == True: #in questo punto va lo splitting della stanza #1) trovo l'edge su cui si trova il critical point #2) setto un peso alto su quell'edge e ricompunto DBSCAN porte_colleganti = [] celle_collegate = [] for index, p in enumerate(critical_points): coppia = [] for celletta in cellette_stanza: if (celletta.cella.boundary).distance( Point(p[0], p[1]) ) < 0.2: # se il contorno della cella dista meno di 0,2 dal critical points(nel caso non basti aumentare questo parametro ) porte_colleganti.append(Point(p[0], p[1])) if celletta not in coppia: coppia.append(celletta) if len(coppia) == 2: if fc.adiacenti(coppia[0].c, coppia[1].c) and coppia[0] != coppia[1]: print "ho trovato le 2 celle che si toccano per questo pixel ", index edge_comune = fc.edge_comune(coppia[0].c, coppia[1].c)[0] #assegno un peso alto a quell'edge (e come se ci fosse la porta chiusa) for edge1 in coppia[0].c.bordi: if edge1 == edge_comune: print "la lunghezza del segmento e' :", sg.lunghezza( edge1.x1, edge1.y1, edge1.x2, edge1.y2) edge_modificato.append( edge1 ) #mi salvo il vecchio valore dell'edge vecchio_valore_edge.append(edge1.weight) edge1.set_weight(1) for edge2 in coppia[1].c.bordi: if edge2 == edge_comune: edge2.set_weight(1) #ora che ho chiuso le porte posso ricomputare DBSCAN #TODO: controllare questa parte da qui in giu', che non vengono settate bene le cose(frontiere etc) #in questo punto adesso per ogni stanza che ne ha bisogno ricomputo DBSCAN come all'inizio #metti qui tutto il DBSCAN #------------------CREO LE MATRICI L, D, D^-1, ED M = D^-1 * L------------------------ #ci si riferisce alla stanza corrente presa in consierazione celle = [] celle_poligoni = [] for celletta in stanza.cells: celle.append(celletta.c) celle_poligoni.append(celletta.cella) (matrice_l, matrice_d, matrice_d_inv, X) = lay.crea_matrici(celle, sigma=parametri_obj.sigma) #------------------------------------------------------------------------------------- #----------------DBSCAN PER TROVARE CELLE NELLA STESSA STANZA------------------------- clustersCelle = lay.DB_scan(parametri_obj.eps, parametri_obj.minPts, X, celle_poligoni) print "la lunghezza di clustersCelle e' ", len(clustersCelle) colori = dsg.get_colors(clustersCelle) stanze, spazi_nuovi = lay.crea_spazio(clustersCelle, celle, celle_poligoni, colori, xmin, ymin, xmax, ymax, filepath=path_obj.filepath) #elimino la vecchia stanza da plan_o ed inserisco quelle nuove print "il numero di stanze appena create e' ", len(spazi_nuovi) #TODO: controllare che le stanze appena create siano correntte(intendo le celle parziali etc) elimina_spazio(stanza, plan_o) for spaz in spazi_nuovi: aggiungi_spazio(spaz, plan_o) #-----finito DBScan rimetto a posto i valori degli edge(riapro le porte)----------------- for index, e in enumerate(edge_modificato): for celletta in cellette_stanza: edge_celletta = celletta.c.bordi for eb in edge_celletta: if e == eb: e.set_weight(vecchio_valore_edge[index])