def stream(self, scene: Scene, bands: List[str], boundary: GeoPolygon = None) -> Image: band_stack = [] for band in bands: try: url = self._get_url(scene, band) except UserWarning as e: print(e) continue image_dataset = gdal.Open('/vsicurl/' + url) if not image_dataset: raise UserWarning(f'Unable to stream band: {band} {url}') band_labels = {band: 0} if boundary: band = self._image_loader.load_from_dataset_and_clip( image_dataset, band_labels, boundary) else: band = self._image_loader.load_from_dataset( image_dataset, band_labels) band_stack.append(band) if len(band_stack) > 1: return Image.stack(band_stack) else: return band_stack[0]
def calculate(image: Image, L: float = 0., H: float = 1., E: float = 0.5, clip: float = 0.) -> Image: bcet_image = np.zeros(image.shape) for i in tqdm(range(image.band_count), total=image.band_count, desc='Calculating bands'): x = image[i].pixels l0 = np.ma.min(x) h0 = np.ma.max(x) e = np.ma.mean(x) l = l0 + (clip * (h0-l0)) h = h0 - (clip * (h0-l0)) L = L H = H E = E s = np.ma.mean(x**2) b = (h**2 * (E - L) - s * (H - L) + l**2 * (H - E)) / (2 * (h * (E - L) - e * (H - L) + l * (H - E))) a = (H - L) / ((h - l) * (h + l - 2 * b)) c = L - a * (l - b)**2 bcet_image[:, :, i] = a * (x - b)**2 + c bcet_image[bcet_image > H] = H bcet_image[bcet_image < L] = L return Image(bcet_image, image.geotransform, image.projection)
def image(): import numpy as np from remotesensing.image import Image, Geotransform return Image( pixels=np.zeros((10, 10, 2)), geotransform=Geotransform(10, 10, 2, 2, 0, 0), projection='')
def calculate(image: Image, k: float = 0.6) -> Image: x = np.amin(image.pixels, axis=2) dds_image = np.copy(image.pixels) for i in range(image.band_count): dds_image[:, :, i] -= (k * x) return Image(dds_image, image.geotransform, image.projection)
def load_from_dataset(self, image_dataset: gdal.Dataset) -> Image: geo_transform = self._load_geotransform(image_dataset) projection = image_dataset.GetProjection() pixels = image_dataset.ReadAsArray() if pixels.ndim > 2: pixels = pixels.transpose(1, 2, 0) return Image(pixels, geo_transform, projection)
def segment_image(cls, image: Image, extract_values: bool = True, n_segments: int = 100, compactness: float = 10., sigma: int = 0, enforce_connectivity: bool = True) -> "Superpixels": pixels = image.pixels pixels[np.isnan(pixels)] = 0. if image.band_count == 1: pixels = np.dstack((pixels, pixels, pixels)) segments = slic(pixels, n_segments=n_segments, compactness=compactness, sigma=sigma, enforce_connectivity=enforce_connectivity) superpixel_list = [] for i in range(segments.max()): segment = segments == i superpixel_list.append( gis.vectorise_image(segment, levels=[0.9, 1.1]).iloc[0].geom) gdf = gpd.GeoDataFrame(geometry=superpixel_list) image.pixels = np.copy(image.pixels).astype(float) if extract_values: if image.band_count == 1: gdf['features'] = gdf.geometry.apply( lambda x: np.nanmean(image.clip_with(x).pixels)) else: gdf['features'] = gdf.geometry.apply(lambda x: np.nanmean( image.clip_with(x).pixels, axis=(0, 1))) return Superpixels(gdf, image.geotransform, image.epsg, number_of_features=image.band_count)
def calibrate_landsat(self, image: Image, band_list: List[str]) -> Image: if image.band_count == 1: calibrated_image = self.calibrate_landsat_band(image.pixels, 0) else: calibrated_image = np.zeros(image.shape) for i, band_name in enumerate(band_list): band_array = image.pixels[:, :, i] calibrated_image[:, :, i] = self.calibrate_landsat_band(band_array, i) return Image(calibrated_image, image.geotransform, image.projection, band_labels={i+1: band for i, band in enumerate(band_list)})
def apply_model(self, image): """ :type image: image.Image :rtype: image.Image """ """ Run the trained model on an image """ if not self.trained: raise UserWarning( "Model needs to be trained before it can be tested.") features = image.pixels.reshape(image.width * image.height, image.band_count) features[np.isnan(features)] = 0 results_list = self.model.predict(features) results_image = results_list.reshape(image.width, image.height) results_image[np.isnan(image[0].pixels)] = 0. return Image(results_image, self.image.geotransform, self.image.projection)
def load_from_dataset_and_clip(self, image_dataset: gdal.Dataset, extent: GeoPolygon) -> Image: geo_transform = self._load_geotransform(image_dataset) pixel_polygon = extent.to_pixel(geo_transform) bounds = [int(bound) for bound in pixel_polygon.polygon.bounds] pixels = image_dataset.ReadAsArray(bounds[0], bounds[1], bounds[2] - bounds[0], bounds[3] - bounds[1]) subset_geo_transform = geo_transform.subset(x=bounds[0], y=bounds[1]) pixel_polygon = extent.to_pixel(subset_geo_transform) if pixels.ndim > 2: pixels = pixels.transpose(1, 2, 0) return Image(pixels, subset_geo_transform, image_dataset.GetProjection())\ .clip_with(pixel_polygon, mask_value=0)
def calculate(cls, low_resolution_image: Image, pan_image: Image) -> Image: pan_smooth = cls._smooth_image(pan_image.pixels) if low_resolution_image.band_count > 2: pansharpened = np.zeros(( pan_image.shape[0], pan_image.shape[1], low_resolution_image.shape[2])) for b in tqdm(range(pansharpened.shape[2]), total=pansharpened.shape[2], desc="Fusing images"): pansharpened[:, :, b] = cls._fuse_images( low_resolution_image=low_resolution_image[b].pixels, pan_image=pan_image.pixels, smoothed_pan_image=pan_smooth) else: pansharpened = cls._fuse_images( low_resolution_image=low_resolution_image.pixels, pan_image=pan_image.pixels, smoothed_pan_image=pan_smooth) return Image(pansharpened, pan_image.geotransform, pan_image.projection)