def get_image_from_latlng_outline(self, corner1, corner2, zoom=18): xtile1, ytile1 = geolocation.deg_to_tile(corner1[0], corner1[1], zoom) xtile2, ytile2 = geolocation.deg_to_tile(corner2[0], corner2[1], zoom) larger_x, smaller_x = xtile2, xtile1 if xtile1 > xtile2: larger_x, smaller_x = xtile1, xtile2 larger_y, smaller_y = ytile2, ytile1 if ytile1 > ytile2: larger_y, smaller_y = ytile1, ytile2 x_range = larger_x - smaller_x y_range = larger_y - smaller_y # image = Image.new("RGB", (256 * (x_range + 1), 256 * (y_range + 1))) images = [] lat_lngs = [] for i_x, xt in enumerate(range(smaller_x, larger_x + 1)): for i_y, yt in enumerate(range(smaller_y, larger_y + 1)): try: tile_part = self.download_tile(xt, yt, zoom) # image.paste(tile_part, (256 * i_x, 256 * i_y)) images.append(np.array(tile_part)) lat_lngs.append(geolocation.tile_to_deg(xt, yt, 18)) except Exception as e: print(e) pass return images, lat_lngs # image
def handle_zone_data(info): keys = ['building_stack', 'field_stack'] geostruct_list = [] geo_corners = [] geo_tiles = [] for k in keys: if k not in info: continue info[k] = info[k][0] for structure in info[k]: if k == 'building_stack': geostruct_list.append('building') else: geostruct_list.append('field') points = [] tiles = [] for lat_lng_dict in structure: lat = lat_lng_dict['lat'] lng = lat_lng_dict['lng'] xt, yt = geolocation.deg_to_tile(lat, lng, zoom=18) points.append([lat, lng]) tiles.append([xt, yt]) geo_corners.append(points) geo_tiles.append(tiles) # list of length n which gives id for each GeoAdd.addAllGeo(geostruct_list, geo_corners, geo_tiles) return geo_corners[0][0] # to take the user to
def detect_building(self): # Get the x_click,y coordinates of the click x_click, y_click = geolocation.deg_to_tilexy_matrix(self.lat, self.long, self.zoom) # find xtile, ytile xtile, ytile = geolocation.deg_to_tile(self.lat, self.long, self.zoom) if self.first: # writes the pre_image before any changes cv2.imwrite('detectors/runtime_images/pre_image.png', self.image) print("running flood fill on existing image") flood_fill = FloodFill(self.image, x_click, y_click, self.THRESHOLD) flood_fill_image, message = flood_fill.flood_fill() cv2.imwrite('detectors/runtime_images/flood_fill_multi_click.png', flood_fill_image) print("ran flood fill") cropped_image = flood_fill.crop_image() cv2.imwrite('detectors/runtime_images/flood_fill_display.png', cropped_image) print('cropped image') edge_image, total_edge_list = flood_fill.find_edges() cv2.imwrite('detectors/runtime_images/flood_fill_edges.png', edge_image) print('found edges') polygon = Polygonify(total_edge_list) rect_points = polygon.find_polygon(rectangle=True) vertex_list = [] # gets polygon's points into lat/long for corner in rect_points: next_vertex = geolocation.tilexy_to_deg_matrix(xtile, ytile, self.zoom, corner[0], corner[1]) vertex_list.append(list(next_vertex)) return vertex_list, message
def detect_building(self): grayscale_image = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY) # Get the x,y coordinates of the click x, y = geolocation.deg_to_tilexy(self.lat, self.long, self.zoom) # find xtile, ytile xtile, ytile = geolocation.deg_to_tile(self.lat, self.long, self.zoom) quad_one = self._get_next_intensity_change(grayscale_image, x, y, 1, 0) quad_four = self._get_next_intensity_change(grayscale_image, x, y, 0, -1) quad_two = self._get_next_intensity_change(grayscale_image, x, y, 0, 1) quad_three = self._get_next_intensity_change(grayscale_image, x, y, -1, 0) corner1 = quad_one[0], quad_two[1] corner2 = quad_one[0], quad_four[1] corner3 = quad_three[0], quad_four[1] corner4 = quad_three[0], quad_two[1] # Calculate the geocoordinates of the rectangle top_right = geolocation.tilexy_to_deg(xtile, ytile, self.zoom, corner1[0], corner1[1]) bottom_right = geolocation.tilexy_to_deg(xtile, ytile, self.zoom, corner2[0], corner2[1]) bottom_left = geolocation.tilexy_to_deg(xtile, ytile, self.zoom, corner3[0], corner3[1]) top_left = geolocation.tilexy_to_deg(xtile, ytile, self.zoom, corner4[0], corner4[1]) top_left = list(top_left) top_right = list(top_right) bottom_right = list(bottom_right) bottom_left = list(bottom_left) # gets the current rect id, the current rect points, and any rectangles that may have been deleted return [top_left, top_right, bottom_right, bottom_left]
def image_xy_to_tile(x, y, lat, lng): print(x, y, lat, lng) xtile, ytile = geolocation.deg_to_tile(lat, lng, zoom) xy_xtile = x // TILE_SIZE + xtile xy_ytile = y // TILE_SIZE + ytile x_in_tile = x - (x // TILE_SIZE) * TILE_SIZE # in the tile finds the x,y y_in_tile = y - (y // TILE_SIZE) * TILE_SIZE return xy_xtile, xy_ytile, x_in_tile, y_in_tile
def mapclick(): if request.method == 'POST': result = request.form info = result_to_dict(result) lat = float(info['lat']) long = float(info['long']) zoom = int(info['zoom']) complex = False if info['complex'] == 'true': complex = True threshold = int(info['threshold']) json_post = {} global osm possible_building_matches = osm.ways_binary_search((lat, long)) # consider moving this to a function inside the OSM_Interactor class, and copy the Rectangle has point inside code if possible_building_matches != None: for points in possible_building_matches: synced_building_as_rect = building_detection_combined.Rectangle( points, to_id=False) if synced_building_as_rect.has_point_inside((lat, long)): json_post = { "rectsToAdd": [], "rectsToDelete": ['INSIDEBUILDING'] } return json.dumps(json_post) # find xtile, ytile xtile, ytile = geolocation.deg_to_tile(lat, long, zoom) # find x, y x, y = geolocation.deg_to_tilexy(lat, long, zoom) # Get those tiles backend_image = imd.get_tiles_around(xtile, ytile, zoom) # create a rectangle from click # rect_data includes a tuple -> (list of rectangle references to add/draw, list of rectangle ids to remove) rect_id, rect_points, rectangles_id_to_remove = building_detection_combined.detect_rectangle( backend_image, xtile, ytile, lat, long, zoom, complex, threshold) # if area too big if osm.check_area(rect_points, sort=False): json_post = {"rectsToAdd": [], "rectsToDelete": []} else: json_post = { "rectsToAdd": [{ "id": rect_id, "points": rect_points }], "rectsToDelete": { "ids": rectangles_id_to_remove } } return json.dumps(json_post)
def send_new_protocol(): result = request.form info = result_to_dict(result) lat = info['lat'] lng = info['lng'] zoom = info['zoom'] xtile, ytile = geolocation.deg_to_tile(lat, lng, zoom) json_post = {'xTile': xtile, 'yTile': ytile} return json_post
def identify_region(): result = request.form info = result_to_dict(result) lat = float(info['lat']) lng = float(info['lng']) zoom = float(info['zoom']) strategy = info['strategy'] imd = get_imd() # old way, tabling for now... # image = imd.get_image_from_latlng_outline((lat1, lng1), (lat2, lng2)) # image.save('setup/setup_image.png') # image = np.array(image) # detection needs an np array # find xtile, ytile xtile, ytile = geolocation.deg_to_tile(lat, lng, zoom) image = np.array(imd.download_tile(xtile, ytile, zoom)) building_ids = None building_points = None if strategy == 'mrcnn': # SETUP MRCNN STUFF global mrcnn if mrcnn is None: # import if not already imported print('import MRCNN stuff...') from Mask_RCNN_Detect import Mask_RCNN_Detect mrcnn = Mask_RCNN_Detect('weights/epoch55.h5') mask_data = mrcnn.detect_building(image, lat, lng, zoom) building_ids = list(mask_data.keys()) building_points = list(mask_data.values()) else: detector = Detector(image, lat, lng, zoom) rect_id, rect_points = detector.detect_building() building_ids = [rect_id] building_points = [rect_points] print(building_points) json_post = { "rects_to_add": [{ "ids": building_ids, "points": building_points }], "rects_to_delete": { "ids": [] } } return json.dumps(json_post)
def mapclick(): global osm, mcrnn, imd if request.method == 'POST': result = request.form info = result_to_dict(result) lat = float(info['lat']) lng = float(info['lng']) zoom = int(info['zoom']) strategy = info['strategy'] # find xtile, ytile xtile, ytile = geolocation.deg_to_tile(lat, lng, zoom) image = np.array(imd.download_tile(xtile, ytile, zoom)) if strategy == 'mrcnn': # SETUP MRCNN STUFF global mrcnn if mrcnn is None: # import if not already imported print('import MRCNN stuff...') from Mask_RCNN_Detect import Mask_RCNN_Detect mrcnn = Mask_RCNN_Detect('weights/epoch55.h5') mask_data = mrcnn.detect_building(image, lat, lng, zoom) building_ids = list(mask_data.keys()) building_points = list(mask_data.values()) else: detector = Detector(image, lat, lng, zoom) rect_id, rect_points = detector.detect_building() building_ids = [rect_id] building_points = [rect_points] json_post = { "rects_to_add": [{ "ids": building_ids, "points": building_points }], "rects_to_delete": { "ids": [] } } return json.dumps(json_post)
def delete_mask(self, lat=None, lng=None, zoom=None, building_id=None): assert lat is not None or building_id is not None if building_id is not None: xtile, ytile = self.id_to_geo[building_id] del self.geo_to_point[(xtile, ytile)][building_id] del self.id_to_geo[building_id] return building_id # find xtile, ytile xtile, ytile = geolocation.deg_to_tile(lat, lng, zoom) if (xtile+1, ytile+1) in self.geo_to_point: relevant = self.geo_to_point[(xtile+1,ytile+1)] for building_id in relevant: points = relevant[building_id] polygon = pltPath.Path(points) if polygon.contains_point([lat,lng]): del relevant[building_id] del self.id_to_geo[building_id] return building_id return -1 # no match
def get_rectangle_from_image_lat_long(gray_scale_image, lat_deg, long_deg, zoom): global image, width, height image = gray_scale_image.copy() height = image.shape[0] width = image.shape[1] # TODO check if this converts lat/long to x/y x, y = geolocation.deg_to_tilexy_matrix(lat_deg, long_deg, zoom) top_y = draw_up(x, y, threshold, timeout) bot_y = draw_down(x, y, threshold, timeout) right_x = draw_right(x, y, threshold, timeout) left_x = draw_left(x, y, threshold, timeout) # TODO check if this converts x/y to lat/long # How to deal with this: 9 slippy tiles in one pic slippy_tiles_tuple = geolocation.deg_to_tile(lat_deg, long_deg, zoom) x_tile = slippy_tiles_tuple[0] y_tile = slippy_tiles_tuple[1] top_right_lat_long = list( geolocation.tilexy_to_deg_matrix(x_tile, y_tile, zoom, right_x, top_y)) top_left_lat_long = list( geolocation.tilexy_to_deg_matrix(x_tile, y_tile, zoom, left_x, top_y)) bot_left_lat_long = list( geolocation.tilexy_to_deg_matrix(x_tile, y_tile, zoom, left_x, bot_y)) bot_right_lat_long = list( geolocation.tilexy_to_deg_matrix(x_tile, y_tile, zoom, right_x, bot_y)) Rectangle([ top_right_lat_long, top_left_lat_long, bot_left_lat_long, bot_right_lat_long ]) return Rectangle.get_added_rectangles(), Rectangle.arr_rect_to_id( Rectangle.get_removed_rectangles())
def detect_building(self, image, lat=None, long=None, zoom=None, rectanglify=True, to_fill=False): assert(image.shape[-1] == 3) # must be size hxwx3 # to return masks = self._detect_single(image, rectanglify, to_fill) # just a regular image, not part of Flask setup if lat is None or long is None or zoom is None: masks = resize(masks, (image.shape[0], image.shape[1]), preserve_range=True) # masks can be reshaped, corners can't masks = masks != 0 # converts to bool mask return masks # list of lat/long points to plot to_return = {} # find xtile, ytile xtile, ytile = geolocation.deg_to_tile(lat, long, zoom) if (xtile+1, ytile+1) not in self.geo_to_point: self.geo_to_point[(xtile+1,ytile+1)] = {} relevant = self.geo_to_point[(xtile+1,ytile+1)] print(lat) print(long) print(xtile) print(ytile) if rectanglify: # finds corners building_ids = np.unique(masks) building_ids = building_ids[building_ids != 0].astype(int).tolist() for i, ids in enumerate(building_ids): points = np.argwhere(masks == ids).tolist() # gets as coordinates if len(points) != 4: print("NOT 4 INSTANCE, SKIPPING BY DEFAULT") continue for j in range(len(points)): x = points[j][1] y = points[j][0] x = int((image.shape[1] / masks.shape[1]) * x) # scales x to what it would be in the original image y = int((image.shape[1] / masks.shape[1]) * y) # scales y to what it would be in the original image geopoint = list(geolocation.tilexy_to_deg_matrix(xtile+1, ytile+1, zoom, x, y)) points[j] = geopoint tmp = points[2] # needs to be swapped to be in the right order when plotted points[2] = points[3] points[3] = tmp to_return[self.building_id] = points relevant[self.building_id] = points # all the points are stored in class memory self.id_to_geo[self.building_id] = (xtile+1, ytile+1) # if the building id is given, we can backtrace the geotile self.building_id += 1 # the full mask is being plotted else: # will turn all True x,y points to lat/long for r in range(masks.shape[1]): # horizontal (x) for c in range(masks.shape[0]): # vertical (y) if masks[c, r] != 0: geo_point = list(geolocation.tilexy_to_deg_matrix(xtile+1, ytile+1, zoom, r, c)) spot_id = masks[c, r] if spot_id not in to_return: to_return[spot_id] = [geo_point] # storing all these points in memory will suck, need to "rectanglify" relevant[spot_id] = [geo_point] else: to_return[spot_id].append(geo_point) relevant[spot_id].append(geo_point) self.image_id += 1 return to_return