def SaveResult(self, path): geotiff = GetDriverByName('Gtiff') output = geotiff.Create(path, self.output_cols, self.output_rows, 1, gdal.GDT_Float32) output_band = output.GetRasterBand(1) output_band.WriteArray(self.ndvi) output.SetGeoTransform(self.ds_B4.GetGeoTransform()) print ("File created successfully.")
def _write_tiff(self, output_path, result): # Initialize a geotiff driver. geotiff = GetDriverByName('GTiff') output = geotiff.Create(output_path, self._dim[0], self._dim[1], 1, gdal.GDT_Float64) output_band = output.GetRasterBand(1) output_band.SetNoDataValue(np.nan) output_band.WriteArray(result) # Set the geographic transformation as the input. output.SetGeoTransform(self._geotransform)
def ndvi(in_nir_band, in_colour_band, in_rows, in_cols, in_geotransform, out_tiff): """ Performs an NDVI calculation given two input bands, as well as other information that can be retrieved from the original image. @param in_nir_band A GDAL band object representing the near-infrared image data. @type in_nir_band GDALRasterBand @param in_colour_band A GDAL band object representing the colour image data. @type: in_colour_band GDALRasterBand @param in_rows The number of rows in both input bands. @type: in_rows int @param in_cols The number of columns in both input bands. @type: in_cols int @param in_geotransform The geographic transformation to be applied to the output image. @type in_geotransform Tuple (as returned by GetGeoTransform()) @param out_tiff Path to the desired output .tif file. @type: out_tiff String (should end in ".tif") @return None """ # Read the input bands as numpy arrays. np_nir = in_nir_band.ReadAsArray(0, 0, in_cols, in_rows) np_colour = in_colour_band.ReadAsArray(0, 0, in_cols, in_rows) # Convert the np arrays to 32-bit floating point to make sure division will occur properly. np_nir_as32 = np_nir.astype(np.float32) np_colour_as32 = np_colour.astype(np.float32) # Calculate the NDVI formula. numerator = subtract(np_nir_as32, np_colour_as32) denominator = add(np_nir_as32, np_colour_as32) result = divide(numerator, denominator) # Remove any out-of-bounds areas result[result == -0] = -99 # Initialize a geotiff driver. geotiff = GetDriverByName('GTiff') # If the desired output is an int16, map the domain [-1,1] to [0,255], create an int16 geotiff with one band and # write the contents of the int16 NDVI calculation to it. Otherwise, create a float32 geotiff with one band and # write the contents of the float32 NDVI calculation to it. output = geotiff.Create(out_tiff, in_cols, in_rows, 1, gdal.GDT_Float32) output_band = output.GetRasterBand(1) output_band.SetNoDataValue(-99) output_band.WriteArray(result) # Set the geographic transformation as the input. output.SetGeoTransform(in_geotransform) return None
def ndvi(in_nir_band, in_colour_band, in_rows, in_cols, in_geotransform, out_tiff, data_type=gdal.GDT_Float32): # Read the input bands as numpy arrays. np_nir = in_nir_band.ReadAsArray(0, 0, in_cols, in_rows) np_colour = in_colour_band.ReadAsArray(0, 0, in_cols, in_rows) # Convert the np arrays to 32-bit floating point to make sure division will occur properly. np_nir_as32 = np_nir.astype(np.float32) np_colour_as32 = np_colour.astype(np.float32) # Calculate the NDVI formula. numerator = subtract(np_nir_as32, np_colour_as32) denominator = add(np_nir_as32, np_colour_as32) result = divide(numerator, denominator) # Remove any out-of-bounds areas result[result == -0] = -99 # Initialize a geotiff driver. geotiff = GetDriverByName('GTiff') # create a float32 geotiff with one band and # write the contents of the float32 NDVI calculation to it. if data_type == gdal.GDT_Float32: output = geotiff.Create(out_tiff, in_cols, in_rows, 1, gdal.GDT_Float32) output_band = output.GetRasterBand(1) output_band.SetNoDataValue(-99) output_band.WriteArray(result) else: raise ValueError( 'Invalid output data type. Valid types are gdal.UInt16 or gdal.Float32.' ) # Set the geographic transformation as the input. output.SetGeoTransform(in_geotransform) return None
def apply_valid_range(input_data_set_path: str, file_path: str) -> str: """Apply Valid Range -10000 -> 10000. Args: input_data_set_path (str) - Path to the input data set file_path (str) - Target data set filename Returns: Path to valid_range_image """ src_ds = GDALOpen(input_data_set_path, GA_ReadOnly) if src_ds is None: raise ValueError( 'Could not open data set "{}"'.format(input_data_set_path)) driver = GetDriverByName('MEM') src_band = src_ds.GetRasterBand(1) data_set = driver.Create('', src_ds.RasterXSize, src_ds.RasterYSize, 1, src_band.DataType) data_set.SetGeoTransform(src_ds.GetGeoTransform()) data_set.SetProjection(src_ds.GetProjection()) data_set_band = data_set.GetRasterBand(1) data_set_band.WriteArray(src_band.ReadAsArray()) band_array = data_set_band.ReadAsArray() dummy = -9999 data_set_band.SetNoDataValue(dummy) band_array[band_array <= -10000] = dummy band_array[band_array >= 10000] = dummy driver = GetDriverByName('GTiff') data_set_band.WriteArray(band_array) dst_ds = driver.CreateCopy(file_path, data_set, options=["COMPRESS=LZW"]) del dst_ds del src_ds del data_set return file_path
def ndvi(in_nir_band, in_colour_band, in_rows, in_cols, in_geotransform, out_tiff, data_type=gdal.GDT_Float32): #Leia as faixas de entrada como matrizes numpy. np_nir = in_nir_band.ReadAsArray(0, 0, in_cols, in_rows) np_colour = in_colour_band.ReadAsArray(0, 0, in_cols, in_rows) # Converta os arrays np em ponto flutuante de 32 bits para garantir que a divisao ocorra corretamente. np_nir_as32 = np_nir.astype(np.float32) np_colour_as32 = np_colour.astype(np.float32) #Tratando divisao por zero np.seterr(divide='ignore', invalid='ignore') # Calculando a formula NDVI = (nir + red) / ( nir + red) numerator = subtract(np_nir_as32, np_colour_as32) denominator = add(np_nir_as32, np_colour_as32) result = divide(numerator, denominator) # Remove todas as areas fora do limite result[result == -0] = -99 #capturando valores minimo e maximo com numpy np.nanmin(result), np.nanmax(result) #classe que noramliza a escala de cores class MidpointNormalize(colors.Normalize): def __init__(self, vmin=None, vmax=None, midpoint=None, clip=False): self.midpoint = midpoint colors.Normalize.__init__(self, vmin, vmax, clip) def __call__(self, value, clip=None): x, y = [self.vmin, self.midpoint, self.vmax], [0, 0.5, 1] return np.ma.masked_array(np.interp(value, x, y), np.isnan(value)) # definindo valores minimo e maximo para construcao do grafico (NDVI vai do -1 a 1) min = -1 #np.nanmin(result); max = 1 #np.nanmax(result); mid = 0.25 #criando imagem .png, demonstrando grafico escala falsa cor fig = plt.figure(figsize=(15, 10)) ax = fig.add_subplot(111) cmap = plt.cm.RdYlGn cax = ax.imshow(result, cmap=cmap, clim=(min, max), norm=MidpointNormalize(midpoint=mid, vmin=min, vmax=max)) ax.axis('off'), ax.set_title('Escala NDVI', fontsize=18, fontweight='bold') cbar = fig.colorbar(cax, orientation='horizontal', shrink=0.50) fig.savefig('ndvi-escala.png', dpi=200, bbox_inches='tight', pad_inches=0.7) #mostra a imagem plt.show() #criando imagem com o histograma fig2 = plt.figure(figsize=(15, 10)) ax = fig2.add_subplot(111) plt.title("Histograma NDVI", fontsize=18, fontweight='bold') plt.xlabel("Escala NDVI", fontsize=12) plt.ylabel("# pixels", fontsize=12) x = result[~np.isnan(result)] numBins = 20 count = len(x) lista = [-1] i = 0 while (i <= count): lista.append(round(x[i], 2)) # append or extend i = i + 100 lista = sorted(lista) data = np.array(lista) data = set(data) data = sorted(data) print(data) ax.hist(lista, numBins, color='#43A047', alpha=0.8) fig2.savefig('ndvi-histograma.png', dpi=200, bbox_inches='tight', pad_inches=0.7) #mostra a imagem plt.show() #Motando grafico Highcharts options = { 'title': { 'text': 'Calculo NDVI' }, 'subtitle': { 'text': 'resultado das imagens processadas' }, 'xAxis': { 'categories': [ '-1', '-0.75', '-0.50', '-0.25', '0', '0.25', '0.50', '0.75', '1' ], }, 'yAxis': { 'title': { 'text': 'Pixels' } }, } chart.set_dict_options(options) #convertendo o array num para lista #data = data.tolist() #print(data) chart.add_data_set(data, series_type='areaspline', name='NDVI Series') chart.set_options('chart', { 'resetZoomButton': { 'relativeTo': 'plot', 'position': { 'x': 0, 'y': -30 } } }) chart.set_options('xAxis', { 'events': { 'afterBreaks': 'function(e){return}' }, 'tickInterval': 0.25 }) chart.set_options('tooltip', {'formatter': 'default_tooltip'}) chart.save_file('grafico') #Inicializando o driver geotiff. geotiff = GetDriverByName('GTiff') # If the desired output is an int16, map the domain [-1,1] to [0,255], create an int16 geotiff with one band and # write the contents of the int16 NDVI calculation to it. Otherwise, create a float32 geotiff with one band and # write the contents of the float32 NDVI calculation to it. if data_type == gdal.GDT_UInt16: ndvi_int8 = multiply((result + 1), (2**7 - 1)) output = geotiff.Create(out_tiff, in_cols, in_rows, 1, gdal.GDT_Byte) output_band = output.GetRasterBand(1) output_band.SetNoDataValue(-99) output_band.WriteArray(ndvi_int8) elif data_type == gdal.GDT_Float32: output = geotiff.Create(out_tiff, in_cols, in_rows, 1, gdal.GDT_Float32) output_band = output.GetRasterBand(1) output_band.SetNoDataValue(-99) output_band.WriteArray(result) else: raise ValueError( 'Tipo de dados de saida invalidos. Os tipos validos sao gdal.UInt16 ou gdal.Float32.' ) # Set the geographic transformation as the input. output.SetGeoTransform(in_geotransform) return None
def ndvi(in_nir_band, in_colour_band, in_rows, in_cols, in_geotransform, out_tiff, data_type=gdal.GDT_Float32): """ Performs an NDVI calculation given two input bands, as well as other information that can be retrieved from the original image. @param in_nir_band A GDAL band object representing the near-infrared image data. @type in_nir_band GDALRasterBand @param in_colour_band A GDAL band object representing the colour image data. @type: in_colour_band GDALRasterBand @param in_rows The number of rows in both input bands. @type: in_rows int @param in_cols The number of columns in both input bands. @type: in_cols int @param in_geotransform The geographic transformation to be applied to the output image. @type in_geotransform Tuple (as returned by GetGeoTransform()) @param out_tiff Path to the desired output .tif file. @type: out_tiff String (should end in ".tif") @param data_type Data type of output image. Valid values are gdal.UInt16 and gdal.Float32. Default is gdal.Float32 @type data_type GDALDataType @return None """ # Read the input bands as numpy arrays. np_nir = in_nir_band.ReadAsArray(0, 0, in_cols, in_rows) np_colour = in_colour_band.ReadAsArray(0, 0, in_cols, in_rows) # Convert the np arrays to 32-bit floating point to make sure division will occur properly. np_nir_as32 = np_nir.astype(np.float32) np_colour_as32 = np_colour.astype(np.float32) # Calculate the NDVI formula. numerator = subtract(np_nir_as32, np_colour_as32) denominator = add(np_nir_as32, np_colour_as32) result = divide(numerator, denominator) print("NDVI min {}, max {}, mean {}".format(np.nanmin(result), np.nanmax(result), np.nanmean(result))) # Remove any out-of-bounds areas result[result == -0] = -99 # Initialize a geotiff driver. geotiff = GetDriverByName('GTiff') # If the desired output is an int16, map the domain [-1,1] to [0,255], create an int16 geotiff with one band and # write the contents of the int16 NDVI calculation to it. Otherwise, create a float32 geotiff with one band and # write the contents of the float32 NDVI calculation to it. if data_type == gdal.GDT_UInt16: ndvi_int8 = multiply((result + 1), (2**7 - 1)) output = geotiff.Create(out_tiff, in_cols, in_rows, 1, gdal.GDT_Byte) output_band = output.GetRasterBand(1) output_band.SetNoDataValue(-99) output_band.WriteArray(ndvi_int8) elif data_type == gdal.GDT_Float32: output = geotiff.Create(out_tiff, in_cols, in_rows, 1, gdal.GDT_Float32) output_band = output.GetRasterBand(1) output_band.SetNoDataValue(-99) output_band.WriteArray(result) else: raise ValueError( 'Invalid output data type. Valid types are gdal.UInt16 or gdal.Float32.' ) # Set the geographic transformation as the input. print('File NDVI generated: {}'.format(out_tiff)) print('GeoTransform: {}'.format(output.GetGeoTransform())) output.SetGeoTransform(in_geotransform) return None
def ndvi(in_nir_band, in_colour_band, in_rows, in_cols, in_geotransform, out_tiff, data_type=gdal.GDT_Float32): """ Performs an NDVI calculation given two input bands, as well as other information that can be retrieved from the original image. @param in_nir_band: A GDAL band object representing the near-infrared image data. @type in_nir_band: GDALRasterBand @param in_colour_band: A GDAL band object representing the colour image data. @type: in_colour_band: GDALRasterBand @param in_rows: The number of rows in both input bands. @type: in_rows: int @param in_cols: The number of columns in both input bands. @type: in_cols: int @param in_geotransform: The geographic transformation to be applied to the output image. @type in_geotransform: Tuple (as returned by GetGeoTransform()) @param out_tiff: Path to the desired output .tif file. @type: out_tiff: String (should end in ".tif") @param data_type: Data type of output image. Valid values are gdal.UInt16 and gdal.Float32. Default is gdal.Float32 @type data_type: GDALDataType @return: """ # Read the input bands as numpy arrays. np_nir = in_nir_band.ReadAsArray(0, 0, in_cols, in_rows) np_colour = in_colour_band.ReadAsArray(0, 0, in_cols, in_rows) # Convert the np arrays to 32-bit floating point to make sure division will occur properly. np_nir_as32 = np_nir.astype(np.float32) np_colour_as32 = np_colour.astype(np.float32) # Calculate the NDVI formula. numerator = subtract(np_nir_as32, np_colour_as32) denominator = add(np_nir_as32, np_colour_as32) result = divide(numerator, denominator) # Remove any NaNs cause by division by zero. ndvi_float32 = nan_to_num(result) # Initialize a geotiff driver. geotiff = GetDriverByName('GTiff') # If the desired output is an int16, map the domain [-1,1] to [0,255], create an int16 geotiff with one band and # write the contents of the int16 NDVI calculation to it. Otherwise, create a float32 geotiff with one band and # write the contents of the float32 NDVI calculation to it. if data_type == gdal.GDT_UInt16: ndvi_int16 = multiply((ndvi_float32 + 1), (2**7 - 1)) output = geotiff.Create(out_tiff, in_cols, in_rows, 1, gdal.GDT_UInt16) output.GetRasterBand(1).WriteArray(ndvi_int16) elif data_type == gdal.GDT_Float32: output = geotiff.Create(out_tiff, in_cols, in_rows, 1, gdal.GDT_Float32) output.GetRasterBand(1).WriteArray(ndvi_float32) else: raise ValueError('Invalid output data type. Valid types are gdal.UInt16 or gdal.Float32.') # Set the geographic transformation as the input. output.SetGeoTransform(in_geotransform) # return the output image in case you want to do something else with it. return output