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
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
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)
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)
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
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
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()
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
'/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