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
Пример #2
0
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())
Пример #3
0
def detect_rectangle(pil_image, xtile, ytile, lat, long, zoom, threshold=None):
    """ Tries to detect the rectangle at a given point on an image. """

    # Get the x,y coordinates of the click
    x, y = geolocation.deg_to_tilexy_matrix(lat, long, zoom)

    pil_image = np.array(pil_image)
    building_points = run_all(pil_image, x, y, threshold)
    vertex_list = []
    # corners are already structured
    for corner in building_points:
        next_vertex = geolocation.tilexy_to_deg_matrix(xtile, ytile, zoom,
                                                       corner[0], corner[1])
        vertex_list.append(list(next_vertex))

    Rectangle(vertex_list)

    retangles_to_add = Rectangle.get_added_rectangles()

    # return the rectangle's id added from the click/merge, the rectangle's points, and the ids of all rectangles to remove (from merging)
    return (retangles_to_add[0].get_id(), retangles_to_add[0].get_points(),
            Rectangle.arr_rect_to_id(Rectangle.get_removed_rectangles()))
Пример #4
0
    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
Пример #5
0
def detect_rectangle(pil_image, xtile, ytile, lat, long, zoom, grayscale=True):
    """ Tries to detect the rectangle at a given point on an image. """

    # chooses right get_intensity or get_RGB function
    def point_finder(im, x, y, step_x, step_y, grayscale):
        if grayscale:
            return get_next_intensity_change(im, x, y, step_x, step_y)
        else:
            return get_next_RGB_change(im, x, y, step_x, step_y)

    # to choose the right scoring function
    def scorer(im, building_list, click_x, click_y, grayscale):
        if grayscale:
            return mapping_scorer(im, building_list, click_x, click_y)
        else:
            return mapping_scorer_RGB(im, building_list, click_x, click_y)

    # used to find the corners given the results of the get_next functions
    # info is formatted as ((point_x, point_y), slope_n)
    def point_slope_intersect(info1, info2):
        x_1 = info1[0][0]
        y_1 = info1[0][1]
        m_1 = info1[1]
        x_2 = info2[0][0]
        y_2 = info2[0][1]
        m_2 = info2[1]

        x = (y_2 - y_1 + m_1 * x_1 - x_2 * m_2) / (m_1 - m_2)
        y = y_1 + m_1 * (x - x_1)
        return x, y

    if grayscale:
        pil_image = PIL.ImageOps.grayscale(pil_image)

    im = np.array(pil_image)

    # Get the x,y coordinates of the click
    x, y = geolocation.deg_to_tilexy_matrix(lat, long, zoom)

    # default is to search for every 15 degrees
    angles = [15 * x * math.pi / 180 for x in range(0, 6)]
    building_list = []
    for angle in angles:
        # Get the boundaries of the rectangle
        quad_one = point_finder(im, x, y, math.cos(angle), math.sin(angle),
                                grayscale)
        quad_four = point_finder(im, x, y, math.sin(angle), -math.cos(angle),
                                 grayscale)
        quad_two = point_finder(im, x, y, -math.sin(angle), math.cos(angle),
                                grayscale)
        quad_three = point_finder(im, x, y, -math.cos(angle), -math.sin(angle),
                                  grayscale)

        slope2 = math.tan(angle)
        if slope2 == 0:
            # hard coded because slope_point_intersect doesn't work when slope is 0
            building_list.append([(quad_one[0], quad_two[1]),
                                  (quad_one[0], quad_four[1]),
                                  (quad_three[0], quad_four[1]),
                                  (quad_three[0], quad_two[1])])
        else:
            slope1 = -1 / slope2
            # top right
            corner1 = point_slope_intersect((quad_one, slope1),
                                            (quad_two, slope2))
            # bottom right
            corner2 = point_slope_intersect((quad_one, slope1),
                                            (quad_four, slope2))
            # bottom left
            corner3 = point_slope_intersect((quad_three, slope1),
                                            (quad_four, slope2))
            # top left
            corner4 = point_slope_intersect((quad_three, slope1),
                                            (quad_two, slope2))
            building_list.append([corner1, corner2, corner3, corner4])

    best_map = scorer(im, building_list, x, y, grayscale)
    corner1 = best_map[0]
    corner2 = best_map[1]
    corner3 = best_map[2]
    corner4 = best_map[3]

    # Calculate the geocoordinates of the rectangle
    topright = geolocation.tilexy_to_deg_matrix(xtile, ytile, zoom, corner1[0],
                                                corner1[1])
    bottomright = geolocation.tilexy_to_deg_matrix(xtile, ytile, zoom,
                                                   corner2[0], corner2[1])
    bottomleft = geolocation.tilexy_to_deg_matrix(xtile, ytile, zoom,
                                                  corner3[0], corner3[1])
    topleft = geolocation.tilexy_to_deg_matrix(xtile, ytile, zoom, corner4[0],
                                               corner4[1])

    topleft = list(topleft)
    topright = list(topright)
    bottomright = list(bottomright)
    bottomleft = list(bottomleft)

    Rectangle([topleft, topright, bottomright, bottomleft])

    retangles_to_add = Rectangle.get_added_rectangles()

    # return the rectangle's id added from the click/merge, the rectangle's points, and the ids of all rectangles to remove (from merging)
    return (retangles_to_add[0].get_id(), retangles_to_add[0].get_points(),
            Rectangle.arr_rect_to_id(Rectangle.get_removed_rectangles()))
def detect_rectangle(pil_image,
                     xtile,
                     ytile,
                     lat,
                     long,
                     zoom,
                     complex,
                     threshold=None):
    """ Tries to detect the rectangle at a given point on an image. """

    if not complex:
        pil_image = PIL.ImageOps.grayscale(pil_image)

        im = np.array(pil_image)

        # Get the x,y coordinates of the click
        x, y = geolocation.deg_to_tilexy_matrix(lat, long, zoom)

        quad_one = get_next_intensity_change(im, x, y, 1, 0)
        quad_four = get_next_intensity_change(im, x, y, 0, -1)
        quad_two = get_next_intensity_change(im, x, y, 0, 1)
        quad_three = get_next_intensity_change(im, 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
        topright = geolocation.tilexy_to_deg_matrix(xtile, ytile, zoom,
                                                    corner1[0], corner1[1])
        bottomright = geolocation.tilexy_to_deg_matrix(xtile, ytile, zoom,
                                                       corner2[0], corner2[1])
        bottomleft = geolocation.tilexy_to_deg_matrix(xtile, ytile, zoom,
                                                      corner3[0], corner3[1])
        topleft = geolocation.tilexy_to_deg_matrix(xtile, ytile, zoom,
                                                   corner4[0], corner4[1])

        topleft = list(topleft)
        topright = list(topright)
        bottomright = list(bottomright)
        bottomleft = list(bottomleft)

        Rectangle([topleft, topright, bottomright, bottomleft])

        retangles_to_add = Rectangle.get_added_rectangles()

        # return the rectangle's id added from the click/merge, the rectangle's points, and the ids of all rectangles to remove (from merging)
        return (retangles_to_add[0].get_id(), retangles_to_add[0].get_points(),
                Rectangle.arr_rect_to_id(Rectangle.get_removed_rectangles()))

    else:
        """COMPLEX MODE: Tries to detect the rectangle at a given point on an image. """
        if threshold == None:
            threshold = 25

        # Get the x,y coordinates of the click
        x, y = geolocation.deg_to_tilexy_matrix(lat, long, zoom)

        pil_image = np.array(pil_image)
        building_points = run_all(pil_image, x, y, threshold)
        vertex_list = []
        # corners are already structured
        for corner in building_points:
            next_vertex = geolocation.tilexy_to_deg_matrix(
                xtile, ytile, zoom, corner[0], corner[1])
            vertex_list.append(list(next_vertex))

        Rectangle(vertex_list)

        retangles_to_add = Rectangle.get_added_rectangles()

        # return the rectangle's id added from the click/merge, the rectangle's points, and the ids of all rectangles to remove (from merging)
        return (retangles_to_add[0].get_id(), retangles_to_add[0].get_points(),
                Rectangle.arr_rect_to_id(Rectangle.get_removed_rectangles()))