Tiến hành tính toán giữa các dải hoặc raster là một nhiệm vụ GIS phổ biến khác. Ở đây, chúng tôi sẽ tính toán
In [1]: import rasterio In [2]: import numpy as np In [3]: from rasterio.plot import show
# Filepath In [4]: fp = r"C:\HY-DATA\HENTENKA\CSC\Data\Helsinki_masked_p188r018_7t20020529_z34__LV-FIN.tif" In [5]: raster = rasterio.open(fp) Để tính toán NDVI (Chỉ số thực vật khác biệt được chuẩn hóa), bạn cần hai dải: Band-4 là Kênh Đỏ và Band-5 là hồng ngoại gần (NIR)
In [6]: red = raster.read(4) In [7]: nir = raster.read(5) In [8]: red Out[8]: array([[0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], ..., [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0]], dtype=uint8) In [9]: nir Out[9]: array([[0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], ..., [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0]], dtype=uint8) In [10]: type(nir) Out[10]: numpy.ndarray In [11]: show(nir) Out[11]: <matplotlib.axes._subplots.AxesSubplot at 0x20c905720f0> Như chúng ta có thể thấy các giá trị được lưu trữ dưới dạng numpy.ndarray.
In [12]: red = red.astype(float) In [13]: nir = nir.astype(float) In [14]: nir Out[14]: array([[ 0., 0., 0., ..., 0., 0., 0.], [ 0., 0., 0., ..., 0., 0., 0.], [ 0., 0., 0., ..., 0., 0., 0.], ..., [ 0., 0., 0., ..., 0., 0., 0.], [ 0., 0., 0., ..., 0., 0., 0.], [ 0., 0., 0., ..., 0., 0., 0.]]) Bây giờ chúng ta có thể thấy rằng các số đã thay đổi thành số thập phân (có một dấu chấm sau 0). Tiếp theo chúng ta cần điều chỉnh hành vi của Numpy một chút. Theo mặc định, Numpy sẽ phàn nàn về việc chia với các giá trị bằng không. Chúng ta cần thay đổi hành vi đó vì chúng ta có nhiều giá trị 0 trong dữ liệu của mình.
In [15]: np.seterr(divide='ignore', invalid='ignore') Out[15]: {'divide': 'warn', 'invalid': 'warn', 'over': 'warn', 'under': 'ignore'} Bây giờ chúng ta cần khởi tạo NDVI với số không trước khi chúng ta thực hiện các tính toán (đây là thủ thuật cụ thể không có In [16]: ndvi = np.empty(raster.shape, dtype=rasterio.float32)
In [17]: check = np.logical_or ( red > 0, nir > 0 )
In [18]: ndvi = np.where ( check, (nir - red ) / ( nir + red ), -999 ) In [19]: ndvi Out[19]: array([[-999., -999., -999., ..., -999., -999., -999.], [-999., -999., -999., ..., -999., -999., -999.], [-999., -999., -999., ..., -999., -999., -999.], ..., [-999., -999., -999., ..., -999., -999., -999.], [-999., -999., -999., ..., -999., -999., -999.], [-999., -999., -999., ..., -999., -999., -999.]]) In [20]: ndvi.mean() Out[20]: -108.16964389074909 In [21]: ndvi.std() Out[21]: 310.4604815144337 In [22]: show(ndvi, cmap='summer') Out[22]: <matplotlib.axes._subplots.AxesSubplot at 0x20c99ecd780> |