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)
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)