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
Beispiel #2
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))
Beispiel #3
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))
Beispiel #4
0
def extend_line(cluster_spaziali, walls, xmin, xmax, ymin, ymax,filepath='.'):
	'''
	crea le extended line
	'''
	extended_lines = rt.crea_extended_lines(cluster_spaziali, walls, xmin, ymin)
	
	#da qui serve per disegnarle
	#extended_lines (credo parli delle rette) hanno un punto, un cluster_angolare ed un 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)

	#----quinto plot --> disegno la mappa come era in partenza(con le linee) e ci aggiungo le rette.
	#disegno le extended_lines in rosso e la mappa in nero
	#dsg.disegna_extended_segments(extended_segments, walls,filepath = filepath)
	
	return (extended_lines, extended_segments)
Beispiel #5
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)