Ejemplo n.º 1
0
def crea_matrici(celle,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
	
	return (matrice_l, matrice_d, matrice_d_inv, X)
Ejemplo n.º 2
0
def get_layout_planimetria(metricMap, mappa_pulita, minVal, maxVal, rho, theta,
                           thresholdHough, minLineLength, maxLineGap, eps,
                           minPts, h, minOffset, minLateralSeparation):
    '''
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 = mappa_pulita
    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)

    dsg.disegna_hough(img_rgb, walls)

    lines = flip_lines(walls[0], 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(cv2.imread(metricMap),
                           minVal,
                           maxVal,
                           apertureSize=5)
    t = 1  #threshold di hough
    m = 20  #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 lista_muri.
    num_min = 3
    lunghezza_min = 3
    indici = ms.indici_da_eliminare(num_min, lunghezza_min, cluster_centers,
                                    walls)

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

    dsg.disegna(walls)

    #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 lista_muri
    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 lista_muri
    walls = sg.spatialClustering(minLateralSeparation, walls)

    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)

    sg.disegna_cluster_spaziali(cluster_spaziali, walls)

    #trovo gli estremi del contorno esterno. Mi servono per settare xmin ymin xmax ymax.
    [x, y, w, h] = cv2.boundingRect(contours[0])

    #-------------------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 è 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 è più grande di una soglia la cella è interna
            if (cella.intersection(contorno).area >= cella.area / 2):
                f.set_out(False)
            #altrimenti è 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.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)
	'''

    #------------------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.
    dsg.disegna_stanze(stanze, colori, xmin, ymin, xmax, ymax)
    plt.show()

    return (stanze, clustersCelle, estremi, colori)