4.4. Escrita em arquivos de Imagens

Uma forma de escrever em arquivos de imagens é por meio da abertura de um arquivo de referência, geração de matrizes das bandas com alterações nos dados originais, e salvamento em um novo arquivo. Veja a sequência de passos: - abrir dataset - obter bandas individuais - acessar array de pixels (formato NumPy) - alterar os array de pixels - enviar para os objetos GDAL - atualizar metadados das imagens - salvar as alterações no arquivo

O exemplo a seguir abre a imagem de referência (com 5 bandas), aplica o contraste nas 3 bandas visíveis, e salva um novo arquivo contendo somente 3 bandas, em ordem diferente (RGB).

# importar a biblioteca gdal e a matplotlib
from osgeo import gdal
import matplotlib.pyplot as plt

# informar o uso de exceções
gdal.UseExceptions()

      # abrir o dataset da imagem RapidEye, com 5 bandas
      # (ao usar o colab, lembre-se de fazer o upload na aba de arquivos)
      dataset = gdal.Open("crop_rapideye.tif", gdal.GA_ReadOnly)

      # obter os objetos com as informações das bandas
      band_blue = dataset.GetRasterBand(1)
      band_green = dataset.GetRasterBand(2)
      band_red = dataset.GetRasterBand(3)
      band_rededge = dataset.GetRasterBand(4)
      band_nir = dataset.GetRasterBand(5)

      # obter as matrizes de pixels de cada banda
      array_blue = band_blue.ReadAsArray()
      array_green = band_green.ReadAsArray()
      array_red = band_red.ReadAsArray()
      array_rededge = band_rededge.ReadAsArray()
      array_nir = band_nir.ReadAsArray()

# aqui já se pode fechar a imagem original
dataset = None

# realizar alterações nas matrizes, lembrando de observar o
# tipo de dados original, de modo a manter os dados nos limites adequados
# definir um valor de ganho e aplicar nas bandas do visível
gain = 2.5
array_blue_gain = array_blue.copy() * gain
array_green_gain = array_green.copy() * gain
array_red_gain = array_red.copy() * gain

# verificar valores fora do limite
limit = 255
array_blue_gain[array_blue_gain > limit] = limit
array_green_gain[array_green_gain > limit] = limit
array_red_gain[array_red_gain > limit] = limit

# definir driver, neste caso GeoTIFF
driver = gdal.GetDriverByName('GTiff')

# obter metadados da imagem original, e alterar o número de bandas
number_of_lines = dataset.RasterYSize
number_of_columns = dataset.RasterXSize
number_of_bands = 3 # dataset.RasterCount
data_type = dataset.GetRasterBand(1).DataType

# criar novo dataset
dataset_new = driver.Create("crop_rapideye_contrastRGB.tif",
                            number_of_columns,
                            number_of_lines,
                            number_of_bands,
                            data_type)

# copiar informações espaciais da banda já existente
dataset_new.SetGeoTransform(dataset.GetGeoTransform())
# copiar informações de projeção
dataset_new.SetProjection(dataset.GetProjectionRef())
# escrever dados da matriz_contraste na banda
dataset_new.GetRasterBand(1).WriteArray(array_red_gain)
dataset_new.GetRasterBand(2).WriteArray(array_green_gain)
dataset_new.GetRasterBand(3).WriteArray(array_blue_gain)
# salvar valores
dataset_new.FlushCache()
# fechar o novo dataset
dataset_new = None

4.4.1. Visualização do resultado

Para visualizar a composição colorida, podemos reabrir o arquivo (nesse caso já organizado em RGB nas bandas 1, 2 e 3).

dataset = gdal.Open("crop_rapideye_contrastRGB.tif", gdal.GA_ReadOnly)

      # obter os objetos com as informações das bandas
      band_red = dataset.GetRasterBand(1)
      band_green = dataset.GetRasterBand(2)
      band_blue = dataset.GetRasterBand(3)

      # obter as matrizes de pixels de cada banda
      array_red = band_red.ReadAsArray()
      array_green = band_green.ReadAsArray()
      array_blue = band_blue.ReadAsArray()

      # definimos os números de linhas/colunas/bandas
number_of_lines = dataset.RasterYSize
number_of_columns = dataset.RasterXSize

      # isso criamos uma matriz com 3 dimensões
      # (3 bandas x linhas x colunas)
      array_rgb = np.zeros((number_of_lines, number_of_columns, 3))

      # veja que, para visualizar corretamente,
      # precisaremos dividir as matrizes pelo
      # maior valor, para obtermos uma matriz
      # com valores normalizados entre 0.0 e 1.0
      array_rgb[:, :, 0] = array_red / array_red.max()
      array_rgb[:, :, 1] = array_green / array_green.max()
      array_rgb[:, :, 2] = array_blue / array_blue.max()

      plt.figure(figsize=(20, 5))
      plt.imshow(array_rgb)
      plt.title('Composição colorida gerada em novo arquivo');