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');