簡體   English   中英

如何使用 Rasterio 更改 Raster 的 dtype

[英]How to change the dtype of a Raster using Rasterio

在柵格數據集上應用多邊形掩碼時,我一直無法處理 Python 的 rasterio 包中沒有數據值的問題。 這個特殊的柵格是具有 7 個波段的 Landsat uint8,並且沒有固有地指定無數據值,因為 255 是無數據的保留值。 但是,有時 uint8 數據是從 uint16 數據壓縮而來的,而 255 值是一個有效的數據值,我不希望將其視為“無數據”(數據是完整的位范圍)。 如果未指定此參數,rasterio 的掩碼函數的默認值是將 0 視為“無數據”值,這同樣存在問題,因為 0 有時被視為有效數據值。 有什么方法可以覆蓋“無數據”的元數據值?

我嘗試了幾種不同的方法來解決這個問題(詳見下文),但都沒有成功。

  1. 使用 rasterio.open() 將 uint8 數據轉換為 uint16 數據並指定“256”作為無數據值,因為它超出了任何 uint8 數據的范圍,但在 uint16 數據范圍內被接受。 這就是某些軟件程序(如 ArcMap)有時會處理不分配數據值的方式。

  2. 與步驟 1 類似,但嘗試使用 rasterio.open() 打開 uint8 數據並在函數中設置 'nodata=np.nan'。 收到錯誤:“給定的無數據值 nan 超出其數據類型的有效范圍。” 盡管在文檔中 nan 被列為“nodata”參數的有效條目。

  3. 在使用 rasterio.mask() 的掩碼過程中,指定 nodata=nan。 收到錯誤“無法將 fill_value nan 轉換為 dtype。”

import rasterio
import fiona
import numpy as np

fp_src = ''
fp_dst = ''
shape = ''

# get shapes
with fiona.open(shape, 'r') as shapefile:
    geoms = [feature['geometry'] for feature in shapefile]



# Method Number 1
# ~~~~~~~~~~~~~~~~~~~~~~~~~

# open original raster, copy meta & alter dtype
with rasterio.open(fp_src) as src_dataset:
    kwds = src_dataset.profile
    kwds['dtype'] = 'uint16'
    src_meta = src_dataset.meta

# write a new raster with the copied and altered meta
with rasterio.open(fp_dst, 'w', **kwds) as dst_dataset:
    dst_meta = dst_dataset.meta

src_dataset.close()
dst_dataset.close()

img = rasterio.open(fp_dst)

# mask img and set nodata to 256 (out of the uint8 range)
out_image, out_transform = mask(img, geoms, nodata=256)
# out_image output: values outside of the geoms are 256 & values inside are 0.



# Method Number 2
# ~~~~~~~~~~~~~~~~~~~~~~~~~

# open original raster, copy meta & alter dtype
with rasterio.open(fp_src) as src_dataset:
    kwds = src_dataset.profile
    kwds['nodata'] = np.nan
    kwds['dtype'] = 'uint16'
    src_meta = src_dataset.meta

# write a new raster with the copied and altered meta
with rasterio.open(fp_dst, 'w', **kwds) as dst_dataset:
    dst_meta = dst_dataset.meta

src_dataset.close()
dst_dataset.close()

img = rasterio.open(fp_dst)

# mask img and let the mask function default to the image's newly created nodata (np.nan from inside with rastario.open...)
out_image, out_transform = mask(img, geoms)
# out_image output: nodata value, nan, is beyond the valid range of its data type



# Method Number 3
# ~~~~~~~~~~~~~~~~~~~~~~~~~

# mask img and set nodata to nan
out_image, out_transform = mask(fp_src, geoms, nodata=np.nan)
# out_image output: Cannot convert fill_value nan to dtype.

我希望看到給定多邊形之外的所有像素都轉換為“無數據”條目,該條目不一定是有效范圍的一部分,因此腳本不可能意外地將有效值視為無數據。

問題是np.nan是一個不能轉換為整數的浮點數。 以下是我將如何解決這個問題:

with rasterio.open(fp_src) as src_dataset:
    meta = src_dataset.meta
    meta.update(
        {
            "nodata": np.iinfo(src_dataset.dtypes[0]).max
        }
    )
    data = src_dataset.read()

    with rasterio.open(fp_dst, 'w', **meta) as dst_dataset:
        dst_dataset.write(data)

函數np.iinfo(dtype).max找到給定整數類型的最大值。 我將此方法用於具有 1 個波段的數據集,因此它也適用於您的數據。 如果沒有,請告訴我。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM