def cleanup_all(graph_fname, im_fname, cleaned_fname): g = graph.read_graph(graph_fname) im = numpy.swapaxes(scipy.ndimage.imread(im_fname), 0, 1) r = geom.Rectangle(geom.Point(0, 0), geom.Point(1300, 1300)) small_r = r.add_tol(-20) # filter lousy road segments road_segments, _ = graph.get_graph_road_segments(g) bad_edges = set() for rs in road_segments: if rs.length() < 80 and (len(rs.src().out_edges) < 2 or len(rs.dst().out_edges) < 2) and small_r.contains(rs.src().point) and small_r.contains(rs.dst().point): bad_edges.update(rs.edges) elif rs.length() < 400 and len(rs.src().out_edges) < 2 and len(rs.dst().out_edges) < 2 and small_r.contains(rs.src().point) and small_r.contains(rs.dst().point): bad_edges.update(rs.edges) ng = graph_filter_edges(g, bad_edges) # connect road segments to the image edge road_segments, _ = graph.get_graph_road_segments(ng) segments = [ geom.Segment(geom.Point(0, 0), geom.Point(1300, 0)), geom.Segment(geom.Point(0, 0), geom.Point(0, 1300)), geom.Segment(geom.Point(1300, 1300), geom.Point(1300, 0)), geom.Segment(geom.Point(1300, 1300), geom.Point(0, 1300)), ] big_r = r.add_tol(-2) small_r = r.add_tol(-40) for rs in road_segments: for vertex in [rs.src(), rs.dst()]: if len(vertex.out_edges) == 1 and big_r.contains(vertex.point) and not small_r.contains(vertex.point): '''d = min([segment.distance(vertex.point) for segment in segments]) dst = get_shortest_path(im, vertex.point.scale(0.5), max_distance=d*9) if dst is None: break if dst is not None: nv = ng.add_vertex(dst.scale(2)) ng.add_bidirectional_edge(vertex, nv) print '*** add edge {} to {}'.format(vertex.point, nv.point)''' '''closest_segment = None closest_distance = None for segment in segments: d = segment.distance(vertex.point) if closest_segment is None or d < closest_distance: closest_segment = segment closest_distance = d''' for closest_segment in segments: vector = vertex.in_edges[0].segment().vector() vector = vector.scale(40.0 / vector.magnitude()) s = geom.Segment(vertex.point, vertex.point.add(vector)) p = s.intersection(closest_segment) if p is not None: nv = ng.add_vertex(p) ng.add_bidirectional_edge(vertex, nv) break ng = connect_up(ng, im) ng.save(cleaned_fname)
def graph_filter(g, threshold=0.3, min_len=None): road_segments, _ = graph.get_graph_road_segments(g) bad_edges = set() for rs in road_segments: if min_len is not None and len(rs.edges) < min_len: bad_edges.update(rs.edges) continue probs = [] if len(rs.edges) < 5 or True: for edge in rs.edges: if hasattr(edge, 'prob'): probs.append(edge.prob) else: for edge in rs.edges[2:-2]: if hasattr(edge, 'prob'): probs.append(edge.prob) if not probs: continue avg_prob = numpy.mean(probs) if avg_prob < threshold: bad_edges.update(rs.edges) print('filtering {} edges'.format(len(bad_edges))) ng = graph.Graph() vertex_map = {} for vertex in g.vertices: vertex_map[vertex] = ng.add_vertex(vertex.point) for edge in g.edges: if edge not in bad_edges: ng.add_edge(vertex_map[edge.src], vertex_map[edge.dst]) return ng
def graph_filter(g, threshold=0.3, min_len=None): road_segments, _ = graph.get_graph_road_segments(g) bad_edges = set() for rs in road_segments: if min_len is not None and len(rs.edges) < min_len: bad_edges.update(rs.edges) continue probs = [] if len(rs.edges) < 5 or True: for edge in rs.edges: if hasattr(edge, 'prob'): probs.append(edge.prob) else: for edge in rs.edges[2:-2]: if hasattr(edge, 'prob'): probs.append(edge.prob) if not probs: continue avg_prob = numpy.mean(probs) if avg_prob < threshold: bad_edges.update(rs.edges) print 'filtering {} edges'.format(len(bad_edges)) ng = graph.Graph() vertex_map = {} for vertex in g.vertices: vertex_map[vertex] = ng.add_vertex(vertex.point) for edge in g.edges: if edge not in bad_edges: ng.add_edge(vertex_map[edge.src], vertex_map[edge.dst]) return ng
def get_connections(g, im, limit=None): edge_im = -numpy.ones(im.shape, dtype='int32') for edge in g.edges: for p in geom.draw_line(edge.src.point, edge.dst.point, geom.Point(edge_im.shape[0], edge_im.shape[1])): edge_im[p.x, p.y] = edge.id road_segments, _ = graph.get_graph_road_segments(g) random.shuffle(road_segments) best_rs = None seen_vertices = set() proposed_connections = [] for rs in road_segments: for vertex, opp in [(rs.src(), rs.point_at_factor(10)), (rs.dst(), rs.point_at_factor(rs.length() - 10))]: if len(vertex.out_edges) >= 2 or vertex in seen_vertices: continue seen_vertices.add(vertex) vertex_distances = get_vertex_distances(vertex, MIN_GRAPH_DISTANCE) edge, path = get_shortest_path(im, vertex.point, opp, edge_im, g, vertex_distances) if edge is not None: proposed_connections.append({ 'src': vertex.id, 'edge': edge.id, 'pos': edge.closest_pos(path[-1]).distance, 'path': rdp.rdp([(p.x, p.y) for p in path], RDP_EPSILON), }) if limit is not None and len(proposed_connections) >= limit: break return proposed_connections
def connect_up(g, im, threshold=40.0): # connect road segments to projection bad_edges = set() updated_vertices = set() road_segments, edge_to_rs = graph.get_graph_road_segments(g) edgeIdx = g.edgeIndex() add_points = [] for rs in road_segments: for vertex in [rs.src(), rs.dst()]: if len(vertex.out_edges) > 1 or vertex in updated_vertices: continue vector = vertex.in_edges[0].segment().vector() vector = vector.scale(threshold / vector.magnitude()) best_edge = None best_point = None best_distance = None for edge in edgeIdx.search( vertex.point.bounds().add_tol(threshold)): if edge in rs.edges or edge in rs.get_opposite_rs( edge_to_rs).edges: continue s1 = edge.segment() s2 = geom.Segment(vertex.point, vertex.point.add(vector)) p = s1.intersection(s2) if p is None: # maybe still connect if both edges are roughly the same angle, and vector connecting them would also be similar angle p = edge.src.point if vertex.point.distance(p) >= threshold: continue v1 = s1.vector() v2 = p.sub(vertex.point) if abs(v1.signed_angle(vector)) > math.pi / 4 or abs( v2.signed_angle(vector)) > math.pi / 4: continue elif get_segment_confidence(geom.Segment(vertex.point, p), im) < 55: continue if p is not None and ( best_edge is None or vertex.point.distance(p) < best_distance): best_edge = edge best_point = p best_distance = vertex.point.distance(p) if best_edge is not None: #print '*** insert new vertex at {} from {} with {}'.format(best_point, vertex.point, best_edge.segment()) bad_edges.add(best_edge) add_points.append( (best_point, [best_edge.src, best_edge.dst, vertex])) updated_vertices.add(vertex) for t in add_points: nv = g.add_vertex(t[0]) for v in t[1]: g.add_bidirectional_edge(nv, v) return graph_filter_edges(g, bad_edges)
def label_connections(gt_graph, inferred_graph, connections, threshold=25): g = inferred_graph.clone() get_connections.insert_connections(g, connections) edge_index = g.edgeIndex() gt_index = gt_graph.edgeIndex() for edge in g.edges: if hasattr(edge, 'phantom'): edge.cost = PHANTOM_BASE + PHANTOM_WEIGHT * edge.segment().length() # if it is far from ground truth edge, increase it's edge cost '''segment = edge.segment() midpoint = segment.start.add(segment.vector().scale(0.5)) gt_distance = None for edge in gt_index.search(midpoint.bounds().add_tol(MAX_GT_DISTANCE)): d = edge.segment().distance(midpoint) if gt_distance is None or d < gt_distance: gt_distance = d if gt_distance is None or gt_distance > MAX_GT_DISTANCE: edge.cost *= 100''' # run dijkstra's on every ground truth road segment whose endpoints match # any connections that are traversed in such a search are marked "good" def match_point(point): best_vertex = None best_distance = None for edge in edge_index.search(point.bounds().add_tol(threshold)): if hasattr(edge, 'phantom'): continue for vertex in [edge.src, edge.dst]: d = point.distance(vertex.point) if d < threshold and (best_vertex is None or d < best_distance): best_vertex = vertex best_distance = d return best_vertex road_segments, _ = graph.get_graph_road_segments(gt_graph) good_connection_indices = set() for rs in road_segments: src = match_point(rs.src().point) dst = match_point(rs.dst().point) if src is None or dst is None: continue _, edge_path = graph.shortest_path(src, dst, max_distance=(PHANTOM_WEIGHT+1)*rs.length()) if edge_path is None: continue for edge in edge_path: if hasattr(edge, 'connection_idx'): good_connection_indices.add(edge.connection_idx) good_connections = [connection for i, connection in enumerate(connections) if i in good_connection_indices] bad_connections = [connection for i, connection in enumerate(connections) if i not in good_connection_indices] return good_connections, bad_connections
def load_tile(k): print('... load {}'.format(k)) region, x, y = k.split('_') ims = [] for sat_path in SAT_PATHS: sat_fname = '{}/{}_sat.jpg'.format(sat_path, k) im = skimage.io.imread(sat_fname)[:, :, 0:3] ims.append(im) g = graph.read_graph('{}/{}.graph'.format(OSM_PATH, k)) road_segments, edge_to_rs = graph.get_graph_road_segments(g) return (ims, g, road_segments, edge_to_rs, k)
def connect_up(g, im, threshold=40.0): # connect road segments to projection bad_edges = set() updated_vertices = set() road_segments, edge_to_rs = graph.get_graph_road_segments(g) edgeIdx = g.edgeIndex() add_points = [] for rs in road_segments: for vertex in [rs.src(), rs.dst()]: if len(vertex.out_edges) > 1 or vertex in updated_vertices: continue vector = vertex.in_edges[0].segment().vector() vector = vector.scale(threshold / vector.magnitude()) best_edge = None best_point = None best_distance = None for edge in edgeIdx.search(vertex.point.bounds().add_tol(threshold)): if edge in rs.edges or edge in rs.get_opposite_rs(edge_to_rs).edges: continue s1 = edge.segment() s2 = geom.Segment(vertex.point, vertex.point.add(vector)) p = s1.intersection(s2) if p is None: # maybe still connect if both edges are roughly the same angle, and vector connecting them would also be similar angle p = edge.src.point if vertex.point.distance(p) >= threshold: continue v1 = s1.vector() v2 = p.sub(vertex.point) if abs(v1.signed_angle(vector)) > math.pi / 4 or abs(v2.signed_angle(vector)) > math.pi / 4: continue elif get_segment_confidence(geom.Segment(vertex.point, p), im) < 55: continue if p is not None and (best_edge is None or vertex.point.distance(p) < best_distance): best_edge = edge best_point = p best_distance = vertex.point.distance(p) if best_edge is not None: #print '*** insert new vertex at {} from {} with {}'.format(best_point, vertex.point, best_edge.segment()) bad_edges.add(best_edge) add_points.append((best_point, [best_edge.src, best_edge.dst, vertex])) updated_vertices.add(vertex) for t in add_points: nv = g.add_vertex(t[0]) for v in t[1]: g.add_bidirectional_edge(nv, v) return graph_filter_edges(g, bad_edges)
from discoverlib import graph, geom BRANCH_THRESHOLD = 15 LOOP_THRESHOLD = 50 in_fname = sys.argv[1] out_fname = sys.argv[2] g = graph.read_graph(in_fname) bad_edges = set() merge_vertices = {} merge_groups = [] road_segments, _ = graph.get_graph_road_segments(g) edge_index = g.edgeIndex() # prune short branches for rs in road_segments: if (len(rs.dst().out_edges) < 2 or len(rs.src().out_edges) < 2) and rs.length() < BRANCH_THRESHOLD: for edge in rs.edges: bad_edges.add(edge) class Group(object): def __init__(self): self.l = [] def add(self, x):
def func(in_fname, out_fname): g = graph.read_graph(in_fname) bad_edges = set() merge_vertices = {} merge_groups = [] road_segments, _ = graph.get_graph_road_segments(g) edge_index = g.edgeIndex() # prune short branches for rs in road_segments: if (len(rs.dst().out_edges) < 2 or len(rs.src().out_edges) < 2) and rs.length() < BRANCH_THRESHOLD: for edge in rs.edges: bad_edges.add(edge) # merge short loops for rs in road_segments: if rs.length() < LOOP_THRESHOLD: if rs.src() in merge_vertices and rs.dst() in merge_vertices: group = merge_vertices[rs.src()] dst_group = merge_vertices[rs.dst()] if group != dst_group: group.update(dst_group) for vertex in dst_group: merge_vertices[vertex] = group elif rs.src() in merge_vertices: group = merge_vertices[rs.src()] group.add(rs.dst()) merge_vertices[rs.dst()] = group elif rs.dst() in merge_vertices: group = merge_vertices[rs.dst()] group.add(rs.src()) merge_vertices[rs.src()] = group else: group = Group() group.add(rs.src()) group.add(rs.dst()) merge_vertices[rs.src()] = group merge_vertices[rs.dst()] = group merge_groups.append(group) for edge in rs.edges: merge_vertices[edge.src] = group merge_vertices[edge.dst] = group group.add(edge.src) group.add(edge.dst) def get_avg(group): point_sum = geom.Point(0, 0) for vertex in group: point_sum = point_sum.add(vertex.point) return point_sum.scale(1.0 / len(group)) ng = graph.Graph() vertex_map = {} def get_vertex(vertex): if vertex in merge_vertices: group = merge_vertices[vertex] group_head = group.head() if group_head not in vertex_map: vertex_map[group_head] = ng.add_vertex(get_avg(group)) return vertex_map[group_head] else: if vertex not in vertex_map: vertex_map[vertex] = ng.add_vertex(vertex.point) return vertex_map[vertex] for edge in g.edges: if edge in bad_edges: continue src = get_vertex(edge.src) dst = get_vertex(edge.dst) if src == dst: continue ng.add_edge(src, dst) ng.save(out_fname)
from discoverlib import graph, geom BRANCH_THRESHOLD = 15 LOOP_THRESHOLD = 50 in_fname = sys.argv[1] out_fname = sys.argv[2] g = graph.read_graph(in_fname) bad_edges = set() merge_vertices = {} merge_groups = [] road_segments, _ = graph.get_graph_road_segments(g) edge_index = g.edgeIndex() # prune short branches for rs in road_segments: if (len(rs.dst().out_edges) < 2 or len(rs.src().out_edges) < 2) and rs.length() < BRANCH_THRESHOLD: for edge in rs.edges: bad_edges.add(edge) class Group(object): def __init__(self): self.l = [] def add(self, x): if x not in self.l: self.l.append(x)
def cleanup_all(graph_fname, im_fname, cleaned_fname): g = graph.read_graph(graph_fname) im = numpy.swapaxes(scipy.ndimage.imread(im_fname), 0, 1) r = geom.Rectangle(geom.Point(0, 0), geom.Point(1300, 1300)) small_r = r.add_tol(-20) # filter lousy road segments road_segments, _ = graph.get_graph_road_segments(g) bad_edges = set() for rs in road_segments: if rs.length() < 80 and (len(rs.src().out_edges) < 2 or len( rs.dst().out_edges) < 2) and small_r.contains( rs.src().point) and small_r.contains(rs.dst().point): bad_edges.update(rs.edges) elif rs.length() < 400 and len(rs.src().out_edges) < 2 and len( rs.dst().out_edges) < 2 and small_r.contains( rs.src().point) and small_r.contains(rs.dst().point): bad_edges.update(rs.edges) ng = graph_filter_edges(g, bad_edges) # connect road segments to the image edge road_segments, _ = graph.get_graph_road_segments(ng) segments = [ geom.Segment(geom.Point(0, 0), geom.Point(1300, 0)), geom.Segment(geom.Point(0, 0), geom.Point(0, 1300)), geom.Segment(geom.Point(1300, 1300), geom.Point(1300, 0)), geom.Segment(geom.Point(1300, 1300), geom.Point(0, 1300)), ] big_r = r.add_tol(-2) small_r = r.add_tol(-40) for rs in road_segments: for vertex in [rs.src(), rs.dst()]: if len(vertex.out_edges) == 1 and big_r.contains( vertex.point) and not small_r.contains(vertex.point): '''d = min([segment.distance(vertex.point) for segment in segments]) dst = get_shortest_path(im, vertex.point.scale(0.5), max_distance=d*9) if dst is None: break if dst is not None: nv = ng.add_vertex(dst.scale(2)) ng.add_bidirectional_edge(vertex, nv) print '*** add edge {} to {}'.format(vertex.point, nv.point)''' '''closest_segment = None closest_distance = None for segment in segments: d = segment.distance(vertex.point) if closest_segment is None or d < closest_distance: closest_segment = segment closest_distance = d''' for closest_segment in segments: vector = vertex.in_edges[0].segment().vector() vector = vector.scale(40.0 / vector.magnitude()) s = geom.Segment(vertex.point, vertex.point.add(vector)) p = s.intersection(closest_segment) if p is not None: nv = ng.add_vertex(p) ng.add_bidirectional_edge(vertex, nv) break ng = connect_up(ng, im) ng.save(cleaned_fname)