def test_gdal_translate(self): img = np.ones((self.height, self.width, 2), np.int16) path = os.path.join(os.getcwd(), "test_gdal_translate.tif") scaled = os.path.join(os.getcwd(), "scaled.tif") out_resolution = (20, -20) ImageIO.write_geotiff(img, path, self.projection, self.coordinates) self.assertTrue(os.path.exists(path)) ds = ImageTools.gdal_translate(path, scaled, tr=" ".join([str(i) for i in out_resolution]), scale="0 1 0 255") self.assertEqual(ds.resolution, out_resolution) self.assertEqual(ds.array.shape, (self.height // 2, self.width // 2, 2)) np.testing.assert_almost_equal(ds.array, 255) FileSystem.remove_file(path) FileSystem.remove_file(scaled)
def test_merge_then_translate(self): datasets = [] init = np.zeros((2, 2), np.int16) path = os.path.join(os.getcwd(), "test_gdal_merge.tif") ImageIO.write_geotiff(init, path, self.projection, self.coordinates) ds_in = GDalDatasetWrapper.from_file(path) for i in range(1, 3, 1): img = np.ones((i*2, i*2), np.int16) * i ds_n = GDalDatasetWrapper(ds=ds_in.get_ds(), array=img) self.assertTrue(os.path.exists(path)) datasets.append(ds_n) ds_merged = ImageTools.gdal_merge(*datasets, dst="out.tif", separate=True, q=True, a_nodata=0) # Array of shape (4, 4, 2): expected = np.array([[[1, 2], [1, 2], [0, 2], [0, 2]], [[1, 2], [1, 2], [0, 2], [0, 2]], [[0, 2], [0, 2], [0, 2], [0, 2]], [[0, 2], [0, 2], [0, 2], [0, 2]]], dtype=np.int16) FileSystem.remove_file("out.tif") np.testing.assert_equal(expected.dtype, ds_merged.array.dtype) np.testing.assert_almost_equal(expected, ds_merged.array) self.assertEqual(ds_merged.nodata_value, 0) self.assertEqual(ds_merged.epsg, 32631) ds_translate = ImageTools.gdal_translate(ds_merged, a_nodata=0) FileSystem.remove_file(path) np.testing.assert_equal(expected.dtype, ds_translate.array.dtype) np.testing.assert_almost_equal(ds_translate.array, expected) self.assertEqual(ds_translate.nodata_value, 0) self.assertEqual(ds_translate.epsg, 32631)
def get_ndvi(red, nir, vrange=(-1, 1), dtype=np.float32): """ Calculate the NDVI (Normalized-Difference Vegetation Index) :param red: The red band dataset :type red: :class:`Common.GDalDatasetWrapper.GDalDatasetWrapper` :param nir: The nir band dataset :type nir: :class:`Common.GDalDatasetWrapper.GDalDatasetWrapper` :param vrange: The range of output values as tuple. By default: (-1, 1). :type vrange: tuple of int :param dtype: The output dtype. :type dtype: :class`np.dtype` :return: The NDVI as numpy array. :rtype: :class:`Common.GDalDatasetWrapper.GDalDatasetWrapper` """ if nir.extent != red.extent or nir.epsg != red.epsg: raise ValueError("Cannot calculate NDSI on two different extents.") if nir.resolution != red.resolution: # Resize to nir resolution in this case. tr = " ".join([str(i) for i in nir.resolution]) ds_red = ImageTools.gdal_translate(red, tr=tr, r="cubic") else: ds_red = red # TODO Add new test img_red = np.array(ds_red.array, dtype=np.float32) img_nir = np.array(nir.array, dtype=np.float32) # Compensate for nan: np.seterr(divide='ignore', invalid='ignore') img_ndvi = np.where((img_red + img_nir) != 0, (img_red - img_nir) / (img_red + img_nir), -1) # Scale to vrange img_ndvi_scaled = ImageTools.normalize(img_ndvi, value_range_out=vrange, value_range_in=(-1, 1), dtype=dtype, clip=True) return GDalDatasetWrapper(ds=nir.get_ds(), array=img_ndvi_scaled)
def get_synthetic_band(self, synthetic_band, **kwargs): wdir = kwargs.get("wdir", self.fpath) output_folder = os.path.join(wdir, self.base) output_bname = "_".join([self.base.split(".")[0], synthetic_band.upper() + ".tif"]) output_filename = kwargs.get("output_filename", os.path.join(output_folder, output_bname)) max_value = kwargs.get("max_value", 10000.) # Skip existing: if os.path.exists(output_filename): return output_filename if synthetic_band.lower() == "ndvi": FileSystem.create_directory(output_folder) b4 = self.find_file(pattern=r"*B0?4(_10m)?.jp2$")[0] b8 = self.find_file(pattern=r"*B0?8(_10m)?.jp2$")[0] ds_red = GDalDatasetWrapper.from_file(b4) ds_nir = GDalDatasetWrapper.from_file(b8) ds_ndvi = ImageApps.get_ndvi(ds_red, ds_nir, vrange=(0, max_value), dtype=np.int16) ds_ndvi.write(output_filename, options=["COMPRESS=DEFLATE"]) elif synthetic_band.lower() == "ndsi": FileSystem.create_directory(output_folder) b3 = self.find_file(pattern=r"*B0?3(_10m)?.jp2$")[0] b11 = self.find_file(pattern=r"*B11(_20m)?.jp2$")[0] ds_green = ImageTools.gdal_translate(b3, tr="20 20", r="cubic") ds_swir = GDalDatasetWrapper.from_file(b11) ds_ndsi = ImageApps.get_ndsi(ds_green, ds_swir, vrange=(0, max_value), dtype=np.int16) ds_ndsi.write(output_filename, options=["COMPRESS=DEFLATE"]) elif synthetic_band.lower() == "mca_sim": FileSystem.create_directory(output_folder) b4 = self.find_file(pattern=r"*B0?4(_10m)?.jp2$")[0] b3 = self.find_file(pattern=r"*B0?3(_10m)?.jp2$")[0] img_red, drv = ImageIO.tiff_to_array(b4, array_only=False) img_green = ImageIO.tiff_to_array(b3) img_mcasim = (img_red + img_green) / 2 ImageIO.write_geotiff_existing(img_mcasim, output_filename, drv, options=["COMPRESS=DEFLATE"]) else: raise ValueError("Unknown synthetic band %s" % synthetic_band) return output_filename