Example #1
0
def crop_raster_to_geometry(raster, geometry):
    im = raster.read()
    mask = geometry_mask(geometry,
                         im[0].shape,
                         raster.transform,
                         all_touched=False)
    im[:, mask] = np.NaN
    return im
Example #2
0
def crop_image_to_geometry(im, metadata, geometry):
    h, w = im.shape[-2], im.shape[-1]
    mask = geometry_mask(geometry, (h, w), metadata['transform'])

    try:
        im[:, mask] = np.NaN
    except IndexError:
        im[mask] = np.NaN

    return im
Example #3
0
    def write_tiles(
        self,
        dir: str,
        n_jobs=1,
        predictions=None,
        mask_features=None,
        cmap: mpl.colors.Colormap = plt.get_cmap("viridis"),
        min_threshold: Union[int, float] = 0,
        bad_value={
            "color": "k",
            "alpha": 0
        },
        metadata: Dict = None,
        transform: Callable = None,
        backend="multiprocessing",
        **kwargs,
    ):
        if min_threshold is not None:
            cmap.set_bad(**bad_value)
            cmap.set_under(**bad_value)
        if not os.path.isdir(dir):
            os.makedirs(dir)
        if metadata:
            with open("{dir}/metadata.json".format(dir=dir), "w") as file:
                file.write(json.dumps(metadata))
        if predictions is None:
            predictions = self.generate_predictions(n_jobs=n_jobs,
                                                    transform=transform,
                                                    backend=backend)
        max_threshold = np.max(predictions)
        min_threshold = np.min(predictions)
        for idx, tile in enumerate(self.tiles):
            x, y, z = tile
            preds = predictions[idx]
            if mask_features is not None:
                fdw = self.transformers[idx]
                vector_mask = geometry_mask(
                    mask_features,
                    transform=fdw,
                    all_touched=True,
                    out_shape=(self.tile_dimension, self.tile_dimension),
                )
                preds[vector_mask] = min_threshold - 100
            folder = "{directory}/{z}/{x}".format(directory=dir, z=z, x=x)
            if not os.path.exists(folder):
                os.makedirs(folder)
            file_path = "{folder}/{y}.png".format(folder=folder, y=y)

            plt.imsave(file_path,
                       preds,
                       cmap=cmap,
                       vmin=min_threshold,
                       vmax=max_threshold)
Example #4
0
    def __getitem__(self, idx):

        ident = multiprocessing.current_process().ident
        try:
            if ident not in self.process_tiffs:
                self.process_tiffs[ident] = rasterio.open(self.tiff_name)
            tiff = self.process_tiffs[ident]
            geometry = self.df_roof_geometries.loc[idx]['projected_geometry']
            roof_image, transform = mask(tiff, [geometry],
                                         crop=True,
                                         pad=True,
                                         filled=self.filled,
                                         pad_width=self.padding)

            roof_image = roof_image[0:3, :, :]
            roof_mask = geometry_mask(
                self.df_roof_geometries['projected_geometry'],
                transform=transform,
                invert=True,
                out_shape=(roof_image.shape[1], roof_image.shape[2]),
                all_touched=True)

            #roof_mask = roof_image[0, :, :]

            roof_mask = roof_mask.astype(np.uint8)
            roof_mask[roof_mask > 0] = 255

            roof_image = np.transpose(roof_image, (1, 2, 0))
            roof_image = roof_image[:, :, ::-1]

            if self.scale_factor != 1.0:
                #print('resizing ... ')
                roof_image = cv2.resize(
                    roof_image,
                    dsize=(int(roof_image.shape[1] * self.scale_factor),
                           int(roof_image.shape[0] * self.scale_factor)))
                roof_mask = cv2.resize(
                    roof_mask,
                    dsize=(int(roof_mask.shape[1] * self.scale_factor),
                           int(roof_mask.shape[0] * self.scale_factor)))

            augmented = self.transforms(image=roof_image, mask=roof_mask)
            img = augmented['image']
            roof_mask = augmented['mask']

            return img, roof_mask, idx
        except:
            self.process_tiffs[ident] = rasterio.open(self.tiff_name)
            return self.__getitem__(idx)
Example #5
0
def detect_data(dataset, shapes, bounds):
    """Detect if any data pixels are found in shapes.

    Typically this is performed against a reduced resolution version of a data
    file as a pre-screening step.

    Parameters
    ----------
    dataset : open rasterio dataset
    shapes : list-like of GeoJSON features
    bounds : list-like of [xmin, ymin, xmax, ymax]

    Returns
    -------
    bool
        Returns True if there are data pixels present
    """
    window = get_window(dataset, bounds)
    raster_window = Window(0, 0, dataset.width, dataset.height)

    try:
        # This will raise a WindowError if windows do not overlap
        window = window.intersection(raster_window)
    except WindowError:
        # no overlap => no data
        return False

    data = dataset.read(1, window=window)
    nodata = int(dataset.nodata)

    if not np.any(data != nodata):
        # entire window is nodata
        return False

    # create mask
    # note: this intentionally uses all_touched=True
    mask = (geometry_mask(
        shapes,
        transform=dataset.window_transform(window),
        out_shape=data.shape,
        all_touched=True,
    )
            | (data == nodata))

    if np.any(data[~mask]):
        return True

    return False
Example #6
0
def boundless_raster_geometry_mask(dataset, shapes, bounds, all_touched=False):
    """Alternative to rasterio.mask::raster_geometry_mask that allows boundless
    reads from raster data sources.

    Parameters
    ----------
    dataset : open rasterio dataset
    shapes : list-like of geometry objects that provide __geo_interface__
    bounds : list-like of [xmin, ymin, xmax, ymax]
    all_touched : bool, optional (default: False)
    """

    window = get_window(dataset, bounds)

    transform = dataset.window_transform(window)
    out_shape = (int(window.height), int(window.width))
    mask = geometry_mask(shapes,
                         transform=transform,
                         out_shape=out_shape,
                         all_touched=all_touched)

    return mask, transform, window
Example #7
0
def main(cfg):

    if not os.path.exists(cfg.out_dir):
        os.mkdir(cfg.out_dir)
    resolutions = {}
    measure = []

    train_df = pd.read_csv(f'{cfg.base_dir}/train_metadata.csv')
    for index, row in train_df.iterrows():
        image = row['img_uri']
        train_label = row['label_uri']
        base_name = os.path.basename(image)[:-4]

        if train_label.find('nia') == -1:
            continue

        prefix = image[0:12]
        out_dir = f'{cfg.out_dir}/{prefix}/{base_name}'
        if not os.path.exists(out_dir):
            os.makedirs(out_dir)
        #else:
        #  continue

        print(f'processing {image}')
        df_roof_geometries = gpd.read_file(f'{cfg.base_dir}/{train_label}')

        tiff = rasterio.open(f'{cfg.base_dir}/{image}')
        tiff_crs = tiff.crs.data
        df_roof_geometries['projected_geometry'] = (
            df_roof_geometries['geometry'].to_crs(tiff_crs))

        pad_width = 1024 + 512
        proccesed = 0
        print(tiff.res[0])
        resolutions[base_name] = tiff.res[0]
        measure.append(tiff.res[0])

        if cfg.shuffle:
            df_roof_geometries = df_roof_geometries.sample(frac=1)

        for index, row in df_roof_geometries.iterrows():
            mask_name = f'{out_dir}/{str(cfg.scale).replace(".", "_")}_{index}_mask.png'
            if mask_name.find(cfg.process_tier) == -1:
                continue
            if os.path.exists(mask_name):
                continue

            geometry = row['projected_geometry']
            roof_image, transform = mask(tiff, [geometry],
                                         crop=True,
                                         pad=True,
                                         filled=False,
                                         pad_width=pad_width)
            roof_image = roof_image[0:3, :, :]
            roof_mask = geometry_mask(df_roof_geometries['projected_geometry'],
                                      transform=transform,
                                      invert=True,
                                      out_shape=(roof_image.shape[1],
                                                 roof_image.shape[2]),
                                      all_touched=True)

            roof_mask = roof_mask.astype(np.uint8)
            roof_mask[roof_mask > 0] = 255

            roof_image = np.transpose(roof_image, (1, 2, 0))
            roof_image = roof_image[:, :, ::-1]

            if cfg.scale != 1:
                roof_image = cv2.resize(roof_image,
                                        (int(roof_image.shape[1] / cfg.scale),
                                         int(roof_image.shape[0] / cfg.scale)),
                                        interpolation=cv2.INTER_LINEAR)
                roof_mask = cv2.resize(roof_mask,
                                       (int(roof_mask.shape[1] / cfg.scale),
                                        int(roof_mask.shape[0] / cfg.scale)),
                                       interpolation=cv2.INTER_LINEAR)

            if cfg.crop1024:
                roof_image = roof_image[0:1024, 0:1024, :]
                roof_mask = roof_mask[0:1024, 0:1024]

            cv2.imwrite(
                f'{out_dir}/{str(cfg.scale).replace(".", "_")}_{index}.jpg',
                roof_image)
            cv2.imwrite(
                f'{out_dir}/{str(cfg.scale).replace(".", "_")}_{index}_mask.png',
                roof_mask)

            if index % 500 == 0:
                print(f'processed {index}/{len(df_roof_geometries)}')
            if proccesed > cfg.max_samples:
                break
            proccesed += 1

    f = open(f'{out_dir}/resolutions.pkl', "wb")
    pickle.dump(resolutions, f)
    f.close()
Example #8
0
def indices_along_line(linestring, im_shape, meta):

    # In case the im is three-dimensional

    # Gets every x and y coordinates constituting the line
    x, y = np.array(linestring.xy)
    x_indices, y_indices = [], []

    # Checking every line between two consecutive points
    for i in range(len(x) - 1):
        if i == 0:
            p0 = (x[i], y[i])
        else:
            p0 = p1

        p1 = (x[i + 1], y[i + 1])

        # Gets every index the line goes through

        line = geom.LineString([p0, p1])
        indices = np.array(
            np.where(
                geometry_mask([line],
                              im_shape[-2:],
                              meta['transform'],
                              all_touched=False,
                              invert=True))).transpose()

        # Computes the numbers of x and y cells traversed by the line
        y_index, x_index = get_index_from_points([p1, p0], meta=meta)
        dy, dx = y_index[-1] - y_index[0], x_index[-1] - x_index[0]

        # Checks whether the line is horizontal or vertical
        last, first = 0, 1
        if np.abs(dy) < np.abs(dx):
            last, first = first, last

        # Sorts the array accordingly
        if dy > 0:
            if dx >= 0:
                indices = indices[np.lexsort(
                    [indices[:, last], indices[:, first]])]
            else:
                indices[:, 1] = -indices[:, 1]
                indices = indices[np.lexsort(
                    [indices[:, last], indices[:, first]])]
        else:
            indices[:, 0] = -indices[:, 0]
            if dx >= 0:
                indices = indices[np.lexsort(
                    [indices[:, last], indices[:, first]])]

            else:
                indices[:, 1] = -indices[:, 1]
                indices = indices[np.lexsort(
                    [indices[:, last], indices[:, first]])]

        # Makes sure the indices are positive, sometimes we need to sort descending
        indices = np.abs(indices)[::-1]

        ys, xs = indices[1:, 0], indices[1:, 1]
        y_indices.extend(ys)
        x_indices.extend(xs)

    indices = (y_indices, x_indices)
    points = get_points_from_index(indices, meta)

    # points = [linestring.interpolate(linestring.project(point)) for point in points]

    if len(im_shape) > 2:
        indices = np.array([np.zeros_like(indices[0]), *indices])

    return tuple(indices), points
Example #9
0
                '/Atlanta_nadir16_catid_1030010002649200/Pan-Sharpen/Pan-Sharpen_Atlanta_nadir16_catid_1030010002649200_',
                '/geojson/spacenet-buildings/spacenet-buildings_')
            geo_name = geo_name.replace('.tif', '.geojson')

            df_roof_geometries = gpd.read_file(f'{geo_name}')
            tiff_crs = tiff.crs.data
            df_roof_geometries['projected_geometry'] = (
                df_roof_geometries['geometry'].to_crs(tiff_crs))

            roof_image, transform = mask(
                tiff,
                df_roof_geometries['projected_geometry'],
                crop=False,
                pad=False,
                filled=False)

            roof_mask = geometry_mask(df_roof_geometries['projected_geometry'],
                                      transform=transform,
                                      invert=True,
                                      out_shape=(img.shape[0], img.shape[1]),
                                      all_touched=True)
            roof_mask = roof_mask.astype(np.uint8)
            roof_mask[roof_mask > 0] = 255

            print(out_img)
            cv2.imwrite(out_img_mask, roof_mask)
        except:
            traceback.print_exc(file=sys.stdout)
            cv2.imwrite(out_img, img)
            pass