Exemplo n.º 1
0
def crea_matrice_l(facce, sigma, val):
    '''
	crea la matrice L cosi' come definita nel paper di Mura
	'''
    riga = []
    #creo la matrice con solo la prima riga
    faccia = facce[0]
    for altra_faccia in facce:
        adj = fc.adiacenti(faccia, altra_faccia)
        if (faccia == altra_faccia):
            #print("stessa faccia")
            val = 1
        else:
            #print("non sono la stessa faccia")
            if (adj):
                #print("adiacenti")
                e = fc.edge_comune(faccia, altra_faccia)
                w = e[0].weight
                val = math.exp(-w / sigma)
            else:
                #print("non adiacenti")
                val = 0
        riga.append(val)

    matrice_l = np.matrix([riga])
    del riga[:]

    for faccia in facce[1:]:
        for altra_faccia in facce:
            adj = fc.adiacenti(faccia, altra_faccia)
            if (faccia == altra_faccia):
                #print("stessa faccia")
                val = 1
            else:
                #print("non sono la stessa faccia")
                if (adj):
                    #print("adiacenti")
                    e = fc.edge_comune(faccia, altra_faccia)
                    w = e[0].weight
                    val = math.exp(-w / sigma)
                else:
                    #print("non adiacenti")
                    val = 0
            riga.append(val)
        matrice_l = np.vstack([matrice_l, riga])
        del riga[:]

    return matrice_l
def estrai_celle_supportate_da_extended_segmement(celle_confinanti, stanza,
                                                  extended_segments):
    '''
	delle celle che fanno parte della lista delle celle_confinanti, 
	estraggo solo quelle che hanno tutti i lati che non toccano l'interno supportati da un extended segment(cioe' che l'extended segment deve toccare almeno una stanza)
	'''

    #per tutte le celle out che confinano con il bordo
    candidate = []
    for cella_conf in celle_confinanti:

        #estraggo le extended segment della cella_confinante
        extended_cella_out = ext.estrai_extended_segment_da_cella(
            cella_conf.c, extended_segments)

        for celle_st in stanza.cells:
            if fc.adiacenti(celle_st.c, cella_conf.c):
                if (
                        fc.edge_comune(celle_st.c,
                                       cella_conf.c)[0].weight < 0.2
                ):  #il bordo in comune non deve essere supportato da segmenti
                    edge_comuni = fc.edge_comune(
                        celle_st.c, cella_conf.c
                    )  #ottengo la lista degli edge comuni alle 2 celle
                    #seleziono le extended segment corrispondenti
                    comuni = []
                    for bordo in edge_comuni:
                        comuni.append(
                            ext.estrai_extended_segment_da_bordo_cella(
                                bordo, extended_segments))

                    extended_cella_out = list(
                        set(extended_cella_out) - set(comuni)
                    )  #tolgo dalle extended della cella out quelle che ha in comune con la cella interna

                    #ora controllo che tutte le extend_segment trovate abbiano un supporto significativo

                    tutte_ok = True
                    for e in extended_cella_out:
                        if e.peso < 0.05:  #se non e' coperto da un po' di segmentini allora l'intera cella non va bene.
                            tutte_ok = False

                    if tutte_ok == True:
                        #cella_conf.set_celletta_parziale(True) #questo sicuramente no perche' questa cella non e' parziale
                        #cella_conf.set_celletta_out(False)
                        candidate.append(cella_conf)

    return candidate
Exemplo n.º 3
0
def trova_spazi_parziali_due(plan_o):
    '''
	secondo metodo per trovare le stanze parziali. faccio un confronto pesato 
	'''

    spazi_in = plan_o.spazi  #oggetto di tipo spazio
    cellette_esterne = plan_o.cellette_esterne  #oggetto di tipo poligono

    spazi_al_confine_interni = spazi_al_confine(spazi_in, cellette_esterne)

    #ora cerco per ogni spazio del confine la lista di edges che ha in comune con l'esterno

    for s in spazi_al_confine_interni:
        edge_in_comune = []  #edge di una stanza in comune con l'esterno
        for c1 in s.cells:
            for c2 in cellette_esterne:
                if fc.adiacenti(c1.c, c2.c):
                    edge_com = fc.edge_comune(c1.c, c2.c)
                    for ele in edge_com:
                        edge_in_comune.append(
                            ele)  #colleziono tutti gli edge in comune
        if Q_split(edge_in_comune
                   ) < 0.6:  #0.6 e' un parametro di cui si deve fare il tuning
            #significa che e' una stanza parziale
            for spazio in plan_o.spazi:
                if s == spazio:
                    spazio.set_parziale(True)
Exemplo n.º 4
0
def estrai_solo_extended_visti(spazio_parz, extended_segments, cellette_out):
    '''
	permette di estrarre tutti gli extended segments di una stanza parziale che sono stati sicuramente visti in precedenza.
	un extended segment risulta sicuramente visto se all'interno della stanza parziale esiste almeno una cella completa 
	che condivide pareti con l'esterno.
	
	non necessariamente l'esterno si puo' ad esempio controllare anche confrondando la cella con celle di altre stanze.
	'''

    celle = spazio_parz.cells
    cellette = []  # ci sono solo le celle della stanza parziale complete

    for ce in celle:
        if ce.parziale == False:
            cellette.append(ce)

    extended = []
    edge_comuni = []
    for celletta in cellette:
        for celletta_out in cellette_out:
            if fc.adiacenti(celletta.c, celletta_out.c):
                comuni = fc.edge_comune(celletta.c, celletta_out.c)
                for e in comuni:
                    edge_comuni.append(e)

    edge_comuni = list(set(edge_comuni))
    for edge in edge_comuni:
        extended.append(
            ext.estrai_extended_segment_da_bordo_cella(edge,
                                                       extended_segments))

    return list(set(extended))
Exemplo n.º 5
0
def estrai_extended_da_spazio(spazio, extended_segments, cellette_out):
    '''
	permette di estrarre le extended segment esterni di uno spazio
	'''
    #se c'e' una cella che condivide un edge con l'esterno allora l'extended di qull'edge e' esterno

    extended = []
    edge_comuni = []
    for celletta in spazio.cells:
        for celletta_out in cellette_out:
            if fc.adiacenti(celletta.c, celletta_out.c):
                comuni = fc.edge_comune(celletta.c, celletta_out.c)
                for e in comuni:
                    edge_comuni.append(e)
        #controllo che non tocchi il bordo, se si aggiungo anche quelle celle
        bordi_cella = celletta.c.bordi
        for e in bordi_cella:
            if e.cluster_spaziale == "bordo1" or e.cluster_spaziale == "bordo2" or e.cluster_spaziale == "bordo3" or e.cluster_spaziale == "bordo4":
                edge_comuni.append(e)

    edge_comuni = list(set(edge_comuni))
    for edge in edge_comuni:
        extended.append(
            ext.estrai_extended_segment_da_bordo_cella(edge,
                                                       extended_segments))

    return list(set(extended))
def elimina_celle_che_eliminerebbero_parete(plan_o, celle_confinanti, s):
    '''
	nella lista delle celle confinanti ad una stanza parziale, ci potrebbero essere delle celle che se venissero aggiunte andrebbero
	ad eliminare una parete gia' vista nelle prossimita', queste celle molto probabilmente non devono essere aggiunte, allora le elimino dall'insieme
	delle celle confinanti.
	'''
    #estraggo le celle delle altre stanze
    celle_di_altre_stanze = []
    for s2 in plan_o.spazi:
        if s2 != s:
            for c in s2.cells:
                celle_di_altre_stanze.append(c)

    #estraggo celle circostanti
    celle_circostanti = celle_di_altre_stanze + plan_o.cellette_esterne  #creo una lista delle celle circostanti ad una stanza
    #extended visti di una stanza parziale.
    b = sp.estrai_solo_extended_visti(
        s, plan_o.extended_segments,
        celle_circostanti)  #estraggo solo le extended sicuramente viste
    tot_segment_visti = list(set(b))

    celle_da_eliminare = []
    for cella_conf in celle_confinanti:
        for cella_st in s.cells:
            if fc.adiacenti(cella_st.c, cella_conf.c):
                edge = fc.edge_comune(
                    cella_st.c, cella_conf.c)[0]  #estraggo l'edge in comune
                #se l'edge in comune ha stesso coefficiente spaziale di uno degli extended visti, allora quella cella non va bene
                for ext in tot_segment_visti:
                    if ext.cluster_spaziale == edge.cluster_spaziale:
                        celle_da_eliminare.append(cella_conf)

    return list(set(celle_confinanti) - set(celle_da_eliminare))
def elimina_celle_con_parete_vista(celle_confinanti, s):
    '''
	dalla lista delle celle confinanti alla stanza s ci potrebbero essere delle celle che mi fanno sparire una parete gia' vista dal laser.
	Non volgio tener conto di quelle celle.
	'''
    #candidate = celle_confinanti[:]#copio le celle confinanti come se fossero tutte candidate
    da_eliminare = []
    for cella_conf in celle_confinanti:
        for cella_st in s.cells:
            if fc.adiacenti(cella_st.c, cella_conf.c):
                # se la cella ha una parete in comune gia' vista allora non va bene
                if (fc.edge_comune(cella_st.c, cella_conf.c)[0].weight > 0.05
                    ):  #metto un minimo di gioco per il rumore (era 0.005)
                    #significa che ci sono dei segmenti visti
                    #quindi se aggiungessi questa celle alla stanza eliminerei una parete che effettivamente era stata gia' osservata
                    #candidate.remove(cella_conf)#la elimino dalla lista delle celle candidate
                    da_eliminare.append(cella_conf)

    candidate = list(set(celle_confinanti) - set(da_eliminare))

    return candidate, da_eliminare
def elimina_celle_che_eliminerebbero_parete2(plan_o, celle_confinanti, s,
                                             elementi_livello_precedente):
    '''
	questo metodo e' molto simile al precendente ma ha senso usarlo solo per livelli sucessivi al primo, perche' va a 
	controllare se la cella che vorrei aggiungere all'insieme potebbe portarmi ad eliminare una cella 
	'''
    #estraggo le celle delle altre stanze
    celle_di_altre_stanze = []
    for s2 in plan_o.spazi:
        if s2 != s:
            for c in s2.cells:
                celle_di_altre_stanze.append(c)

    #estraggo celle circostanti
    celle_circostanti = celle_di_altre_stanze + plan_o.cellette_esterne  #creo una lista delle celle circostanti ad una stanza
    #extended visti di una stanza parziale.
    b = sp.estrai_solo_extended_visti(
        s, plan_o.extended_segments,
        celle_circostanti)  #estraggo solo le extended sicuramente viste
    tot_segment_visti = list(set(b))

    elementi_livello_successivo = list(
        set(celle_confinanti) - set(elementi_livello_precedente))
    celle_da_eliminare = []
    for cella_conf_l1 in elementi_livello_precedente:
        for cella_conf_l2 in elementi_livello_successivo:
            if fc.adiacenti(cella_conf_l1.c, cella_conf_l2.c):
                #non solo le celle vicine alla stanza devono soddisfare la condizione precede, ma anche le celle dello stesso insieme di elementi
                edge = fc.edge_comune(
                    cella_conf_l1.c,
                    cella_conf_l2.c)[0]  #estraggo l'edge in comune
                #se l'edge in comune ha stesso coefficiente spaziale di uno degli extended visti, allora quella cella non va bene
                for ext in tot_segment_visti:
                    if ext.cluster_spaziale == edge.cluster_spaziale:
                        celle_da_eliminare.append(cella_conf_l2)

    return list(set(celle_confinanti) - set(celle_da_eliminare))
Exemplo n.º 9
0
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])
Exemplo n.º 10
0
def unisci_stanze_oversegmentate(plan_o):
    '''
	se esistono due spazi diversi che sono collegati tramite un edge di una cella che ha un peso basso allora unisco quegli spazi
	'''

    spazi = plan_o.spazi

    #per ogni spazio guardo se esiste un altro spazio che ha una cella che ha a sua volta un edge in comune con il primo spazio
    stanze_da_unire = []

    c = 0
    for s1 in spazi:
        for s2 in spazi:
            for c1 in s1.cells:
                for c2 in s2.cells:
                    if fc.adiacenti(c1.c, c2.c):
                        if fc.edge_comune(
                                c1.c, c2.c
                        )[0].weight < 0.25 and s1 != s2 and s1.out == False and s2.out == False:  # se hanno un peso basso
                            #dovrei unire i due spazi
                            coppia = [s1, s2]
                            if (coppia not in stanze_da_unire) and (
                                [coppia[1], coppia[0]] not in stanze_da_unire
                            ):  #mi interessa anche il senso contrario. Li voglio unire solo una volta
                                stanze_da_unire.append(coppia)
                                c += 1

    for ele in stanze_da_unire:
        print ele
    print "\n"

    #ora che ho le coppie di spazi devo unire tutte le coppie che hanno almeno un elemento in comune poiche' fanno parte della stessa stanza.
    l = stanze_da_unire
    out = []
    while len(l) > 0:
        first, rest = l[0], l[1:]
        first = set(first)

        lf = -1
        while len(first) > lf:
            lf = len(first)

            rest2 = []
            for r in rest:
                if len(first.intersection(set(r))) > 0:
                    first |= set(r)
                else:
                    rest2.append(r)
            rest = rest2

        out.append(first)
        l = rest

    #lista di elementi comuni (appartenenti alla stessa stanza)
    elementi_comuni = []
    for s in out:
        elementi_comuni.append(list(s))
    '''
	elementi_comuni=[]
	for index1,coppia1 in enumerate(stanze_da_unire):
		da_unire = [coppia1[0],coppia1[1]]
		for index2,coppia2 in enumerate(stanze_da_unire):
			if index2>index1:
				if coppia1 != coppia2:#aggiungo in cascata tutti quelli che dovrebbero essere uniti
					if coppia1[1] == coppia2[0]:
						da_unire.append(coppia2[1])					
					if len(elementi_comuni) >0:
						for e in elementi_comuni:
							if (coppia1[0] in e) and (coppia1[1] in e):
								da_unire = e
								#ricorda che potrebbe non essere necessariamente coppia2[1], devi selezionare quello diverso
								if coppia2[0] in e: 
									da_unire.append(coppia2[1])
								else:
									da_unire.append(coppia2[0])
								elementi_comuni.remove(e)# in teoria dovrebbe andare bene dato che ce ne dovrebbe essere solo uno di elemento da eliminare
					#da aggiungere anche gli altri controlli 
		elementi_comuni.append(da_unire)
	
	for ele in elementi_comuni:
		print ele
	'''
    for e in elementi_comuni:
        prima_coppia = [e[0], e[1]]
        count = 2
        spazio_risultante = sp.unisci_spazi(prima_coppia[0], prima_coppia[1])
        #elimino i vecchi spazi(che ormai ho unito )
        print "gli spazi sono: ", len(plan_o.spazi)
        elimina_spazio(prima_coppia[0], plan_o)
        elimina_spazio(prima_coppia[1], plan_o)
        print "gli spazi sono: ", len(plan_o.spazi)
        #aggiungo alla lista degli spazi di un Plan la stanza che ho appena creato
        aggiungi_spazio(spazio_risultante, plan_o)
        print "gli spazi sono, ora che ho aggiunto: ", len(plan_o.spazi)
        while count < len(e):
            seconda_coppia = [spazio_risultante, e[count]]
            count += 1
            spazio_risultante = sp.unisci_spazi(spazio_risultante,
                                                seconda_coppia[1])
            #elimino i vecchi spazi(che ormai ho unito )
            print "gli spazi sono: ", len(plan_o.spazi)
            elimina_spazio(seconda_coppia[0], plan_o)
            elimina_spazio(seconda_coppia[1], plan_o)
            print "gli spazi sono: ", len(plan_o.spazi)
            #aggiungo alla lista degli spazi di un Plan la stanza che ho appena creato
            aggiungi_spazio(spazio_risultante, plan_o)
            print "gli spazi sono, ora che ho aggiunto: ", len(plan_o.spazi)

    print "il numero di cellette adiacenti con basso peso sono", c
Exemplo n.º 11
0
def postprocessing(plan_o, parametri_obj):
    '''
	unisco stanze che dovrebbero essere unite, lo faccio epr coppia di spazi.
	1) trovo gli edge adiacenti tra spazi.
	2) e calcolo l'affinita' pesato su tutti gli edge in comune  
	'''

    spazi = plan_o.spazi

    #per ogni spazio guardo se esiste un altro spazio che ha una cella che ha a sua volta un edge in comune con il primo spazio
    stanze_da_unire = []

    c = 0
    s2_temp = spazi[0]
    edge_in_comune = []
    for s1 in spazi:
        for s2 in spazi:
            edge_in_comune = []
            s2_temp = s2
            for c1 in s1.cells:
                for c2 in s2.cells:
                    if fc.adiacenti(c1.c, c2.c):
                        edge_com = fc.edge_comune(c1.c, c2.c)
                        for ele in edge_com:
                            edge_in_comune.append(
                                ele)  #colleziono tutti gli edge in comune

            if len(edge_in_comune) > 0 and Q_split(
                    edge_in_comune
            ) < parametri_obj.soglia_q_split and s1 != s2_temp and s1.out == False and s2_temp.out == False:  # se hanno un peso basso
                #if fc.edge_comune(c1.c, c2.c)[0].weight < 0.25 and s1!= s2 and s1.out == False and s2.out == False: # se hanno un peso basso
                #dovrei unire i due spazi
                coppia = [s1, s2_temp]
                if (coppia not in stanze_da_unire) and (
                    [coppia[1], coppia[0]] not in stanze_da_unire
                ):  #mi interessa anche il senso contrario. Li voglio unire solo una volta
                    stanze_da_unire.append(coppia)
                    c += 1

    for ele in stanze_da_unire:
        print ele
    print "\n"

    #ora che ho le coppie di spazi devo unire tutte le coppie che hanno almeno un elemento in comune poiche' fanno parte della stessa stanza.
    l = stanze_da_unire
    out = []
    while len(l) > 0:
        first, rest = l[0], l[1:]
        first = set(first)

        lf = -1
        while len(first) > lf:
            lf = len(first)

            rest2 = []
            for r in rest:
                if len(first.intersection(set(r))) > 0:
                    first |= set(r)
                else:
                    rest2.append(r)
            rest = rest2

        out.append(first)
        l = rest

    #lista di elementi comuni (appartenenti alla stessa stanza)
    elementi_comuni = []
    for s in out:
        elementi_comuni.append(list(s))

    #li stanpo solo per vedere se sono corretti
    for ele in elementi_comuni:
        print ele

    for e in elementi_comuni:
        prima_coppia = [e[0], e[1]]
        count = 2
        spazio_risultante = sp.unisci_spazi(prima_coppia[0], prima_coppia[1])
        #elimino i vecchi spazi(che ormai ho unito )
        print "gli spazi sono: ", len(plan_o.spazi)
        elimina_spazio(prima_coppia[0], plan_o)
        elimina_spazio(prima_coppia[1], plan_o)
        print "gli spazi sono: ", len(plan_o.spazi)
        #aggiungo alla lista degli spazi di un Plan la stanza che ho appena creato
        aggiungi_spazio(spazio_risultante, plan_o)
        print "gli spazi sono, ora che ho aggiunto: ", len(plan_o.spazi)
        while count < len(e):
            seconda_coppia = [spazio_risultante, e[count]]
            count += 1
            spazio_risultante = sp.unisci_spazi(spazio_risultante,
                                                seconda_coppia[1])
            #elimino i vecchi spazi(che ormai ho unito )
            print "gli spazi sono: ", len(plan_o.spazi)
            elimina_spazio(seconda_coppia[0], plan_o)
            elimina_spazio(seconda_coppia[1], plan_o)
            print "gli spazi sono: ", len(plan_o.spazi)
            #aggiungo alla lista degli spazi di un Plan la stanza che ho appena creato
            aggiungi_spazio(spazio_risultante, plan_o)
            print "gli spazi sono, ora che ho aggiunto: ", len(plan_o.spazi)

    print "il numero di cellette adiacenti con basso peso sono", c
Exemplo n.º 12
0
def get_layout_parziale(metricMap, minVal, maxVal, rho, theta, thresholdHough, minLineLength, maxLineGap, eps, minPts, h, minOffset, minLateralSeparation, diagonali=True):
	'''
prende in input la mappa metrica, i parametri di canny, hough, mean-shift, dbscan, distanza per clustering spaziale. Genera il layout delle stanze e ritorna la lista di poligoni shapely che costituiscono le stanze, la lista di cluster corrispondenti, la lista estremi che contiene [minx,maxx,miny,maxy] e la lista di colori.
	'''
	
	img_rgb = cv2.imread(metricMap)
	ret,thresh1 = cv2.threshold(img_rgb,127,255,cv2.THRESH_BINARY)


	#------------------CANNY E HOUGH PER TROVARE MURI----------------------------------
	
	#canny
	cannyEdges = cv2.Canny(thresh1,minVal,maxVal,apertureSize = 5)
	#hough
	walls = cv2.HoughLinesP(cannyEdges,rho,theta,thresholdHough,minLineLength,maxLineGap) 

	if cv2.__version__[0] == '3' :
		walls = [i[0]for i in walls]
	elif cv2.__version__[0] == '2' :
		walls = walls[0]
	else :
		raise EnvironmentError('Opencv Version Error. You should have OpenCv 2.* or 3.*')

	dsg.disegna_hough(img_rgb,walls)

	lines = flip_lines(walls, img_rgb.shape[0]-1)

	walls = crea_muri(lines)
	
	#disegno i muri
	sg.disegna_segmenti(walls)


	#------------SETTO XMIN YMIN XMAX YMAX DI walls--------------------------------------------

	#tra tutti i punti dei muri trova l'ascissa e l'ordinata minima e massima.
	estremi = sg.trova_estremi(walls)
	xmin = estremi[0]
	xmax = estremi[1]
	ymin = estremi[2]
	ymax = estremi[3]
	offset = 20
	xmin -= offset
	xmax += offset
	ymin -= offset
	ymax += offset


	#---------------CONTORNO ESTERNO-------------------------------------------------------

	#creo il contorno esterno facendo prima canny sulla mappa metrica.
	cannyEdges = cv2.Canny(img_rgb,minVal,maxVal,apertureSize = 5)
	t=1 #threshold di hough
	m=21 #maxLineGap di hough
	hough_contorni, contours = im.trova_contorno(t,m,cannyEdges, metricMap)

	#dsg.disegna_hough(cannyEdges, hough_contorni)

	contours = flip_contorni(contours, img_rgb.shape[0]-1)

	#disegno contorno esterno
	vertici = []
	for c1 in contours:
		for c2 in c1:
			vertici.append([float(c2[0][0]),float(c2[0][1])])
	dsg.disegna_contorno(vertici,xmin,ymin,xmax,ymax)


	#-------------------MEAN SHIFT PER TROVARE CLUSTER ANGOLARI---------------------------------------
	
	#creo i cluster centers tramite mean shift
	cluster_centers = ms.mean_shift(h, minOffset, walls)


	#ci sono dei cluster angolari che sono causati da pochi e piccoli line_segments, che sono solamente rumore. Questi cluster li elimino dalla lista cluster_centers ed elimino anche i rispettivi segmenti dalla walls.
	num_min = 3
	lunghezza_min = 3
	indici = ms.indici_da_eliminare(num_min, lunghezza_min, cluster_centers, walls, diagonali)


	#ora che ho gli indici di clusters angolari e di muri da eliminare, elimino da walls e cluster_centers, partendo dagli indici piu alti
	for i in sorted(indici, reverse=True):
		del walls[i]
		del cluster_centers[i]


	#ci son dei cluster che si somigliano ma non combaciano per una differenza infinitesima, e non ho trovato parametri del mean shift che rendano il clustering piu' accurato di cosi', quindi faccio una media normalissima, tanto la differenza e' insignificante.
	unito = ms.unisci_cluster_simili(cluster_centers)
	while(unito):
		unito = ms.unisci_cluster_simili(cluster_centers)


	#assegno i cluster ai muri di walls
	walls = sg.assegna_cluster_angolare(walls, cluster_centers)


	#creo lista di cluster_angolari
	cluster_angolari = []
	for muro in walls:
		cluster_angolari.append(muro.cluster_angolare)


	#---------------CLUSTER SPAZIALI--------------------------------------------------------------------

	#setto i cluster spaziali a tutti i muri di walls
	walls = sg.spatialClustering(minLateralSeparation, walls)

	#disegno i cluster angolari
	#sg.disegna_cluster_angolari(cluster_centers, walls, cluster_angolari)

	#creo lista di cluster spaziali
	cluster_spaziali = []
	for muro in walls:
		cluster_spaziali.append(muro.cluster_spaziale)

	#disegno cluster spaziali
	sg.disegna_cluster_spaziali(cluster_spaziali, walls)


	#-------------------CREO EXTENDED_LINES---------------------------------------------------------

	extended_lines = rt.crea_extended_lines(cluster_spaziali, walls, xmin, ymin)


	#extended_lines hanno punto, cluster_angolare e cluster_spaziale, per disegnarle pero' mi servono 2 punti. Creo lista di segmenti
	extended_segments = ext.crea_extended_segments(xmin,xmax,ymin,ymax, extended_lines)


	#disegno le extended_lines in rosso e la mappa in nero
	ext.disegna_extended_segments(extended_segments, walls)


	#-------------CREO GLI EDGES TRAMITE INTERSEZIONI TRA EXTENDED_LINES-------------------------------

	edges = sg.crea_edges(extended_segments)

	#sg.disegna_segmenti(edges)


	#----------------------SETTO PESI DEGLI EDGES------------------------------------------------------

	edges = sg.setPeso(edges, walls)

	#sg.disegna_pesanti(edges, peso_min)


	#----------------CREO LE CELLE DAGLI EDGES----------------------------------------------------------

	print("creando le celle")

	celle = fc.crea_celle(edges)

	print("celle create")

	#fc.disegna_celle(celle)


	#----------------CLASSIFICO CELLE----------------------------------------------

	#creo poligono del contorno
	contorno = Polygon(vertici)
	
	celle_poligoni = []
	indici = []
	celle_out = []
	celle_parziali = []
	for index,f in enumerate(celle):
		punti = []
		for b in f.bordi:
			punti.append([float(b.x1),float(b.y1)])
			punti.append([float(b.x2),float(b.y2)])
		#ottengo i vertici della cella senza ripetizioni
		punti = sort_and_deduplicate(punti)
		#ora li ordino in senso orario
		x = [p[0] for p in punti]
		y = [p[1] for p in punti]
		global centroid
		centroid = (sum(x) / len(punti), sum(y) / len(punti))
		punti.sort(key=algo)
		#dopo averli ordinati in senso orario, creo il poligono della cella.
		cella = Polygon(punti)
		#se il poligono della cella non interseca quello del contorno esterno della mappa, la cella e' fuori.
		if cella.intersects(contorno)==False:
			#indici.append(index)
			f.set_out(True)
			f.set_parziale(False)
			celle_out.append(f)
		#se il poligono della cella interseca il contorno esterno della mappa
		if (cella.intersects(contorno)):
			#se l'intersezione e' piu' grande di una soglia la cella e' interna
			if(cella.intersection(contorno).area >= cella.area/2):
				f.set_out(False)
			#altrimenti e' esterna
			else:
				f.set_out(True)
				f.set_parziale(False)
				celle_out.append(f)
	
	#le celle che non sono state messe come out, ma che sono adiacenti al bordo dell'immagine (hanno celle adiacenti < len(bordi)) sono per forza parziali
	a=0
	for f in celle:
		for f2 in celle:
			if (f!=f2) and (fc.adiacenti(f,f2)):
				a += 1
		if (a<len(f.bordi)):
			#print("ciao")
			if not (f.out):
				f.set_out(True)
				f.set_parziale(True)
				celle_parziali.append(f)
		a = 0

	#le celle adiacenti ad una cella out tramite un edge che pesa poco, sono parziali.	
	a = 1
	while(a!=0):
		a = 0
		for f in celle:
			for f2 in celle:
				if (f!=f2) and (f.out==False) and (f2.out==True) and (fc.adiacenti(f,f2)):
					if(fc.edge_comune(f,f2)[0].weight < 0.1):  #qua nella funzione normale c'e' 0.2
						f.set_out(True)
						f.set_parziale(True)
						celle_parziali.append(f)
						a = 1
	
	
	#tolgo dalle celle out le parziali
	celle_out = list(set(celle_out)-set(celle_parziali))
	#tolgo dalle celle quelle out e parziali
	celle = list(set(celle)-set(celle_out))
	celle = list(set(celle)-set(celle_parziali))


	#--------------------------POLIGONI CELLE-------------------------------------------------

	#adesso creo i poligoni delle celle (celle = celle interne) e delle celle esterne e parziali 

	#poligoni celle interne
	celle_poligoni = []
	for f in celle:
		punti = []
		for b in f.bordi:
			punti.append([float(b.x1),float(b.y1)])
			punti.append([float(b.x2),float(b.y2)])
		punti = sort_and_deduplicate(punti)
		x = [p[0] for p in punti]
		y = [p[1] for p in punti]
		centroid = (sum(x) / len(punti), sum(y) / len(punti))
		punti.sort(key=algo)
		cella = Polygon(punti)
		celle_poligoni.append(cella)	

	#poligoni celle esterne
	out_poligoni = []
	for f in celle_out:
		punti = []
		for b in f.bordi:
			punti.append([float(b.x1),float(b.y1)])
			punti.append([float(b.x2),float(b.y2)])
		punti = sort_and_deduplicate(punti)
		x = [p[0] for p in punti]
		y = [p[1] for p in punti]
		centroid = (sum(x) / len(punti), sum(y) / len(punti))
		punti.sort(key=algo)
		cella = Polygon(punti)
		out_poligoni.append(cella)

	#poligoni celle parziali
	parz_poligoni = []
	for f in celle_parziali:
		punti = []
		for b in f.bordi:
			punti.append([float(b.x1),float(b.y1)])
			punti.append([float(b.x2),float(b.y2)])
		punti = sort_and_deduplicate(punti)
		x = [p[0] for p in punti]
		y = [p[1] for p in punti]
		centroid = (sum(x) / len(punti), sum(y) / len(punti))
		punti.sort(key=algo)
		cella = Polygon(punti)
		parz_poligoni.append(cella)



	#------------------CREO LE MATRICI L, D, D^-1, ED M = D^-1 * L---------------------------------------

	sigma = 0.1
	val = 0
	matrice_l = mtx.crea_matrice_l(celle, sigma, val)

	matrice_d = mtx.crea_matrice_d(matrice_l)

	matrice_d_inv = matrice_d.getI()

	matrice_m = matrice_d_inv.dot(matrice_l)
	matrice_m = mtx.simmetrizza(matrice_m)

	X = 1-matrice_m


	#----------------DBSCAN PER TROVARE CELLE NELLA STESSA STANZA-----------------------------------------

	clustersCelle = []
	clustersCelle = clustering_dbscan_celle(eps, minPts, X)


	colori, fig, ax = dsg.disegna_dbscan(clustersCelle, celle, celle_poligoni, xmin, ymin, xmax, ymax, edges, contours)
	'''
	#plotto le celle esterne
	for f_poly in out_poligoni:
		f_patch = PolygonPatch(f_poly,fc='#ffffff',ec='BLACK')
		ax.add_patch(f_patch)
		ax.set_xlim(xmin,xmax)
		ax.set_ylim(ymin,ymax)
		ax.text(f_poly.representative_point().x,f_poly.representative_point().y,str("out"),fontsize=8)
	'''
	
	#plotto le celle parziali
	for f_poly in parz_poligoni:
		f_patch = PolygonPatch(f_poly,fc='#d3d3d3',ec='BLACK')
		ax.add_patch(f_patch)
		ax.set_xlim(xmin,xmax)
		ax.set_ylim(ymin,ymax)
		ax.text(f_poly.representative_point().x,f_poly.representative_point().y,str("parz"),fontsize=8)
	plt.show()
	

	#------------------POLIGONI STANZE-------------------------------------------------------------------

	#creo i poligoni delle stanze (unione dei poligoni delle celle con stesso cluster).
	stanze = []
	stanze = unisciCelle(clustersCelle, celle, celle_poligoni, False)

	#disegno layout stanze.
	fig, ax = dsg.disegna_stanze(stanze, colori, xmin, ymin, xmax, ymax)
	#plotto le celle parziali, questo per funzionare ha bisogno che si commenti riga 127 di disegna.py (#plt.show()).
	
	for f_poly in parz_poligoni:
		f_patch = PolygonPatch(f_poly,fc='#d3d3d3',ec='BLACK')
		ax.add_patch(f_patch)
		ax.set_xlim(xmin,xmax)
		ax.set_ylim(ymin,ymax)
	plt.show()
	
	return (stanze, clustersCelle, estremi, colori)