Procesamiento de datos geográficos de Python doce: lectura y escritura de datos ráster


1. GDAL

  GDAL (Biblioteca de abstracción de datos geoespaciales) es una biblioteca de escritura y lectura de archivos ráster muy popular y potente. La biblioteca GDAL es de código abierto, pero tiene una licencia flexible, por lo que muchos paquetes de software comerciales la utilizan. La mayoría de las plataformas GIS o de teledetección existentes, ya sea el software comercial ArcGIS, ENVI o el software de código abierto GRASS, QGIS, utilizan GDAL como biblioteca de construcción subyacente.
  La biblioteca GDAL es bien conocida por su capacidad para leer y escribir muchos formatos diferentes, pero también contiene algunas funciones de procesamiento de datos, como el análisis de proximidad. El módulo NumPy se especializa en procesar datos matriciales grandes y puede usar GDAL para leer directamente los datos en una matriz NumPy. Después de manipular los datos, se pueden usar NumPy u otros módulos para procesar estas matrices, y la matriz se puede volver a escribir en el disco como un dataset ráster.
  Puede ver el controlador de ráster GDAL :

Inserte la descripción de la imagen aquí
  Cada conductor lee y escribe un formato de datos específico. La estructura de datos de GDAL coincide aproximadamente con el dataset ráster.Cada conjunto de datos contiene una o más bandas, Cada banda contiene datos de píxeles y posibles vistas generales. La información de referencia geográfica se incluye en el conjunto de datos porque todas las bandas utilizan la misma información de referencia geográfica.

Inserte la descripción de la imagen aquí
  La serie de satélites LANDSAT es administrada conjuntamente por la Administración Nacional de Aeronáutica y del Espacio (NASA) y el Servicio Geológico de los Estados Unidos (USGS). Desde 1972, se han lanzado 8 satélites de la serie LANDSAT (el sexto lanzamiento falló). Landsat1-5 se encuentran actualmente fuera de servicio. Landsat7 tiene datos de brecha de datos causados ​​por la falla del corrector de línea de escaneo (SLC) del sensor desde junio de 2003, pero aún está funcionando. Landsat8 fue lanzado el 11 de febrero de 2013 y comenzó a adquirir imágenes luego de 100 días de operación de prueba, aún está en operación.
  El Servicio Geológico de EE. UU. Procesa imágenes de Landsat en la colección de imágenes de GeoTIFF . A excepción de la banda 6 (infrarrojos térmicos) y la banda 8 (pancromática), cada banda tiene una resolución de 30 metros porque proviene de la misma escena Landsat y tiene el mismo tamaño. Las bandas se pueden apilar directamente una encima de otra sin modificaciones.

  1. Combine bandas ráster independientes en una imagen:

# Script to stack three 1-band rasters into a a single 3-band image.
import os
from osgeo import gdal

os.chdir(r'E:\Google chrome\Download\gis with python\Landsat\Washington')
band1_fn = 'p047r027_7t20000730_z10_nn10.tif'
band2_fn = 'p047r027_7t20000730_z10_nn20.tif'
band3_fn = 'p047r027_7t20000730_z10_nn30.tif'

# 打开GeoTIFF波段1,索引为1
# 波段索引从1开始,而不是0
in_ds = gdal.Open(band1_fn)
in_band = in_ds.GetRasterBand(1)

# 利用和波段1相同的属性创建三波段GeoTIFF
gtiff_driver = gdal.GetDriverByName('GTiff')  # 使用驱动对象创建新的数据集
out_ds = gtiff_driver.Create('nat_color.tif',
    in_band.XSize, in_band.YSize, 3, in_band.DataType)
out_ds.SetProjection(in_ds.GetProjection())
out_ds.SetGeoTransform(in_ds.GetGeoTransform())

# 从输入波段复制像素到输出波段3
in_data = in_band.ReadAsArray()
out_band = out_ds.GetRasterBand(3)
out_band.WriteArray(in_data)

# 从数据集,而不是波段复制像素
in_ds = gdal.Open(band2_fn)
out_band = out_ds.GetRasterBand(2)
out_band.WriteArray(in_ds.ReadAsArray())

# 为每个波段计算统计值
out_ds.GetRasterBand(1).WriteArray(
    gdal.Open(band3_fn).ReadAsArray())

out_ds.FlushCache()
for i in range(1, 4):
    out_ds.GetRasterBand(i).ComputeStatistics(False)

# 创建概视图或金字塔图层
out_ds.BuildOverviews('average', [2, 4, 8, 16, 32])

del out_ds

  Imagen RGB:

Inserte la descripción de la imagen aquí
  driver.Create (nombre de archivo, tamaño x, tamaño y, [bandas], [tipo_datos], [opciones]) :

  1. nombre de archivo: la ruta del conjunto de datos creado
  2. ysize: el número de columnas en el nuevo conjunto de datos
  3. bandas: el número de bandas en el nuevo conjunto de datos, el valor predeterminado es 1
  4. data_type: el tipo de datos que se almacenará en el nuevo conjunto de datos, el valor predeterminado es GDT_Byte
  5. opción: crea una lista de cadenas de opciones. El valor se basa en el tipo de conjunto de datos creado.

  Tipo de datos GDAL:

constante tipo de datos
GDT_Unknown Desconocido
GDT_Byte Entero de 8 bits sin signo (byte)
GDT_UInt16 Entero de 16 bits sin signo
GDT_Int16 Entero de 16 bits con signo
GDT_UInt32 Entero de 32 bits sin signo
GDT_Int32 Entero de 32 bits con signo
GDT_Float32 Punto flotante de 32 bits
GDT_Float64 Punto flotante de 64 bits
GDT_CInt16 Entero complejo de 16 bits
GDT_CInt32 Entero complejo de 32 bits
GDT_CFloat32 Punto flotante complejo de 32 bits
GDT_CFloat64 Punto flotante complejo de 64 bits
GDT_TypeCount Número de tipos de datos disponibles

  Esta información se obtiene de la banda de entrada, pero estas imágenes utilizan el tipo predeterminado GDT_Byte.

  1. Vea el SRS del conjunto de datos de tres bandas vacío:

out_ds.SetProjection(in_ds.GetProjection())
out_ds.SetGeoTransform(in_ds.GetGeoTransform())

  Obtenga el SRS del conjunto de datos de entrada y cópielo en el nuevo conjunto de datos, y luego realice la misma operación en geotransform . geotransform proporciona las coordenadas originales y el tamaño de píxel, junto con el valor de rotación, para hacer que la parte superior de la imagen mire hacia el norte. Si el conjunto de datos debe colocarse en el espacio correcto, el conjunto de datos y el tamaño de píxel son parámetros muy importantes.

  2. Después de crear el conjunto de datos, agregue valores de píxeles y lea los valores de píxeles leídos de la banda 1 en la matriz NumPy . Sin proporcionar ningún parámetro a la función Readasarray () , todos los valores de píxeles se devolverán en una matriz bidimensional con el mismo tamaño que la cuadrícula. La variable in_data contiene una matriz bidimensional de valores de píxeles:

in_data = in_band.ReadAsArray()

  3. Debido a que la banda 1 es la banda azul, debe colocarse en la posición de la tercera banda de la capa de salida para obtener el orden de la banda RGB.
  Luego, obtenga el tercer Eberton de out_data y use la función WriteArray () para copiar los valores de píxeles en la matriz in_data a la tercera banda del nuevo conjunto de datos.

out_band = out_ds.GetRasterBand(3)
out_band.WriteArray(in_data)

  4. Agregue las bandas roja y verde al conjunto de datos y encienda GeoTIFF para la banda 2. Leer datos de píxeles directamente del conjunto de datos.

in_ds = gdal.Open(band2_fn)
out_band = out_ds.GetRasterBand(2)
out_band.WriteArray(in_ds.ReadAsArray())

  Cuando se llama a la función ReadAsArray en el conjunto de datos, si el conjunto de datos que se está leyendo tiene varias bandas, se obtendrá una matriz tridimensional. Debido a que el archivo Landsat tiene solo una banda, devuelve una matriz bidimensional.

  5. Haga lo mismo con los valores de píxeles rojos, pero comprima a menos código:

out_ds.GetRasterBand(1).WriteArray(gdal.Open(band3_fn).ReadAsArray())

  6. Calcule los datos estadísticos de cada banda en el conjunto de datos, lo que puede facilitar la visualización del software. Los datos estadísticos incluyen el control promedio, mínimo, máximo y estándar de la banda. Esto permite que el software GIS utilice esta información para estirar los datos de la pantalla para que se vea mejor.
  Antes de los datos estadísticos, debe asegurarse de que los datos se hayan escrito en el disco y calcular los datos estadísticos de cada banda. Pase False a esta función para indicarle las estadísticas reales que necesita, no estimaciones, ya que puede obtenerse de la descripción general o de un subconjunto de píxeles muestreados. Si el valor estimado es aceptable, pase True a la función; esto hace que el cálculo sea más rápido, porque no es necesario verificar todos los píxeles:

out_ds.FlushCache()
for i in range(1, 4):
    out_ds.GetRasterBand(i).ComputeStatistics(False)

  7. Cree una descripción general del conjunto de datos.

out_ds.BuildOverviews('average', [2, 4, 8, 16, 32])

  Puede verlo en rasterio.Este módulo se basa en GDAL, que básicamente usa GDAL para leer y escribir datos, pero el módulo rasterio intenta facilitar el procesamiento de datos ráster.
  El módulo imageio no depende de GDAL. Es un módulo escrito puramente en Python. No se enfoca en datos geoespaciales. Puede leer y escribir muchos formatos raster diferentes, incluyendo formatos de video.

2. Leer parte del conjunto de datos

  Acceda a un subconjunto en lugar de acceder a la imagen completa. La función ReadAsAsrray () tiene varios parámetros opcionales, que variarán dependiendo de si está utilizando un conjunto de datos o una banda.
  band.ReadAsArray ([xoff], [yoff], [win_xsize], [win_ysize], [buf_xsize], [buf_ysize], [buf_obj])

  1. xoff : el punto de partida de la lectura de la columna, el valor predeterminado es 0
  2. yoff : el punto de partida de la lectura de la línea, el valor predeterminado es 0
  3. win_xsize : el número de columnas a leer, todas las columnas se leen por defecto
  4. win_ysize : el número de filas a leer, todas las filas se leen por defecto
  5. buf_xsize : el número de columnas en la matriz de salida, el valor predeterminado es win_xsize, si el valor es diferente de win_xsize, los datos se volverán a muestrear
  6. buf_ysize : el número de filas en la matriz de salida, el valor predeterminado es win_xsize, si el valor es diferente de win_ysize, los datos se volverán a muestrear
  7. buf_obj : matriz NumPy utilizada para almacenar matrices en lugar de crear matrices. Si es necesario, los datos se volverán a muestrear para ajustarse a la matriz. El valor se convertirá a este tipo de matriz.

  Los parámetros xoff y yoff se utilizan para especificar el valor de compensación de la columna y la fila para comenzar a leer, respectivamente. El valor predeterminado comienza desde la primera fila y la primera columna.
  Los parámetros win_xsize y win_ysize se utilizan para mostrar cuántas filas y columnas se han leído. Todas las filas y columnas
  se leen de forma predeterminada. Si buf_xsize y buf_ysize proporcionados no coinciden con el tamaño de la matriz, obtendrá un error, pero no No es necesario dar buf_xsize y buf_ysize El valor de porque esto está determinado por la propia matriz.

  1. Lea los datos en 3 filas y 6 columnas a partir de la fila 6000 y la columna 1400:

import os
import numpy as np
from osgeo import gdal


data_dir = r'E:\Google chrome\Download\gis with python'

# 打开Landsat波段
os.chdir(os.path.join(data_dir, 'Landsat', 'Washington'))
ds = gdal.Open('p047r027_7t20000730_z10_nn10.tif')
band = ds.GetRasterBand(1)

# 读取指定范围数据
data = band.ReadAsArray(1400, 6000, 6, 3)
print(data)

Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
  2. Conversión de tipo de datos:

# 使用numpy将数据转换为浮点数
data = band.ReadAsArray(1400, 6000, 6, 3).astype(float)
print(data)

Inserte la descripción de la imagen aquí
  3. Al leer datos, use GDAL para convertir:
  primero, cree una matriz de punto flotante y luego páselo a readasarray como un parámetro buf_obj, mientras se asegura de que la matriz creada tenga el mismo tamaño que los datos que se leen.

# 通过将它们读入浮点数组,来转换为浮点数
import numpy as np

data = np.empty((3, 6), dtype=float)  # dtype参数用来指定数组的数据类型
band.ReadAsArray(1400, 6000, 6, 3, buf_obj=data)
print(data)

Inserte la descripción de la imagen aquí
  4. Escriba la matriz de datos en la posición designada de otros conjuntos de datos y pase el valor de compensación a la función. Comenzará desde el valor de compensación proporcionado y escribirá todos los datos en la matriz pasados ​​a la función WriteArray () :

band2.WriteArray(data, 1400, 6000)

  5. Procesar un gran conjunto de datos que excede el tamaño de la memoria: solo un bloque a la vez.
  Nota: Los datos ráster se almacenan en bloques en el disco, por lo que procesar imágenes en estos bloques es muy eficiente. como muestra la imagen:

Inserte la descripción de la imagen aquí
  Convierta la elevación de DEM de métrico a pies (solo una pieza a la vez):

import os
import numpy as np
from osgeo import gdal

os.chdir(r'E:\Google chrome\Download\gis with python\osgeopy data\Washington\dem')

# 打开输入光栅并获得其尺寸
in_ds = gdal.Open('gt30w140n90.tif')
in_band = in_ds.GetRasterBand(1)
xsize = in_band.XSize
ysize = in_band.YSize

# 获取块大小和NoData值
block_xsize, block_ysize = in_band.GetBlockSize()
nodata = in_band.GetNoDataValue()

# 创建具有相同维度和数据类型的输出文件
out_ds = in_ds.GetDriver().Create(
    'dem_feet.tif', xsize, ysize, 1, in_band.DataType)
out_ds.SetProjection(in_ds.GetProjection())
out_ds.SetGeoTransform(in_ds.GetGeoTransform())
out_band = out_ds.GetRasterBand(1)

# 在x方向循环这些块
for x in range(0, xsize, block_xsize):

    # 获取要读取的列数
    if x + block_xsize < xsize:
        cols = block_xsize
    else:
        cols = xsize - x

    # 在y方向循环blocks
    for y in range(0, ysize, block_ysize):

        # 获取要读取的行数
        if y + block_ysize < ysize:
            rows = block_ysize
        else:
            rows = ysize - y

        # 读取一个块的数据值,将其转换为英尺
        # 然后将结果写入输出中相同的块位置
        data = in_band.ReadAsArray(x, y, cols, rows)
        data = np.where(data == nodata, nodata, data * 3.28084)
        out_band.WriteArray(data, x, y)

# 刷新缓存
# 设置NoData值后进行统计
out_band.FlushCache()
out_band.SetNoDataValue(nodata)
out_band.ComputeStatistics(False)
out_ds.BuildOverviews('average', [2, 4, 8, 16, 32])
del out_ds

  Este método es más complicado que leer toda la banda a la vez, pero ahorra memoria.
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

2.1 Usar coordenadas del mundo real

  Los datos requeridos: origen de coordenadas, tamaño de píxel y valor de rotación se almacenan en la geotransformación copiados de los conjuntos de datos . La transformación geográfica es una tupla que contiene seis valores:

índice descripción
0 La coordenada x del origen
1 Ancho de píxel
2 x rotación de píxeles (0 ° cuando la imagen mira hacia el norte)
3 La coordenada y del origen
4 y rotación de píxeles (0 ° hacia el norte)
5 Altura de píxel (valor negativo)

La función ApplyGeoTransform proporcionada por GDAL para realizar una transformación afín requiere tres parámetros: geotransform, valor xy valor y. Cuando se utiliza la transformación de geotransformación de un conjunto de datos, esta función puede convertir las coordenadas de la imagen (desplazamiento) en coordenadas del mundo real.
Hay otra forma de pensar (transformación inversa del conjunto de datos):

# 现在得到逆变换
# 原始文件可用于将偏移量转换为真实世界的坐标
# 而逆文件可用于将真实世界的坐标转换为偏移量

# GDAL 1.x: 你会得到一个成功标志和地理变换
success, inv_gt = gdal.InvGeoTransform(gt)
print(success, inv_gt)

Devuelve 1 si tiene éxito, 0 si no tiene éxito.

Supongo que te gusta

Origin blog.csdn.net/amyniez/article/details/113745573
Recomendado
Clasificación