3

I have been able to plot and display my raster images using matplotlib. That part is successful. The part which I am stuck on is be able to save that plot somehow. For rasterio I've found two helpful tutorials:

https://rasterio.readthedocs.io/en/latest/topics/windowed-rw.html

and

https://www.earthdatascience.org/courses/earth-analytics-python/multispectral-remote-sensing-in-python/export-numpy-array-to-geotiff-in-python/

I've gotten a calculate for a function called NDVI and through matplotlib I can display it just the way I want with the following code. But when I go to save the file as a GeoTIFF the image on my desktop is all black. I plan to reproject the data too and I have that code commented out.

Here is my code:

import rasterio
import matplotlib.pyplot as plt
import numpy as np


nirband = r"LC08_L1TP_015033_20170822_20170912_01_T1_B5.TIF"

redband =r"LC08_L1TP_015033_20170822_20170912_01_T1_B4.TIF"


#rasterio.windows.Window(col_off, row_off, width, height)
window = rasterio.windows.Window(2000,2000,800,600)

with rasterio.open(nirband) as src:
    subset = src.read(1, window=window)

fig, ax = plt.subplots(figsize=(12,6))
plt.imshow(subset)
plt.title(f'Band 5 Subset')





with rasterio.open(nirband) as src:
    nir = src.read(1, window=window)

with rasterio.open(redband) as src:
    red = src.read(1, window=window)

red = red.astype(float)
nir = nir.astype(float)
np.seterr(divide='ignore', invalid='ignore')

ndvi = np.empty(nir.shape, dtype=rasterio.float32)
check = np.logical_or ( red > 0, nir > 0 )
naip_ndvi = np.where ( check,  (1.0*(nir - red )) / (1.0*( nir + red )),-2 )


fig, ax = plt.subplots(figsize=(12,6))
ndvi = ax.imshow(naip_ndvi)
ax.set(title="NDVI")



with rasterio.open("LC08_L1TP_015033_20170822_20170912_01_T1_B5.TIF") as src:
    naip_data_ras = src.read()
    naip_meta = src.profile


with rasterio.open('MyExample.tif', 'w',**naip_meta) as dst:
    dst.write(naip_ndvi, window=window)


# =============================================================================
# with rasterio.open('example.tif') as dataset:
# 
#     # Read the dataset's valid data mask as a ndarray.
#     mask = dataset.dataset_mask()
# 
#     # Extract feature shapes and values from the array.
#     for geom, val in rasterio.features.shapes(
#             mask, transform=dataset.transform):
# 
#         # Transform shapes from the dataset's own coordinate
#         # reference system to CRS84 (EPSG:4326).
#         geom = rasterio.warp.transform_geom(
#             dataset.crs, 'EPSG:4326', geom, precision=6)
# 
#         # Print GeoJSON shapes to stdout.
#         print(geom)
# =============================================================================

Here is what NDVI looks like when I use matplotlib (I want to save this to my desktop as a GeoTIFF file):

NDVI

Thank you for any and all help!

prusswan
  • 6,853
  • 4
  • 40
  • 61
yuen2
  • 79
  • 1
  • 2
  • 7

2 Answers2

0

How are you viewing the output image? In an image viewer, or in GIS or remote sensing software that can add a contrast stretch to the file? NDVI values run from -1 to 1 - maybe the range of values is too small for your software to display automatcally. I had a similar issue recently with modifying PlanetScope imagery - it displayed as expected using matplotlib but the tiff appeared black.

You could try scaling the output by multiplying the cell values by 100 - this may help with display issues. You could also verify the output image values by using software that can apply a contrast stretch to the image (QGIS, esri products, ImageJ, or image processing software)

mdh
  • 1
  • 1
0

Your src.profile (from "LC08_L1TP_015033_20170822_20170912_01_T1_B5.TIF") probably has a dtype of int32 or something similar while your naip_ndvi contains float values.

You should set the dtype for your dst to float32 (or float64)

with rasterio.open("LC08_L1TP_015033_20170822_20170912_01_T1_B5.TIF") as src:
    naip_data_ras = src.read()
    naip_meta = src.profile
    
    # set dtype to float
    naip_meta["dtype"] = rasterio.float32
Sam
  • 171
  • 1
  • 4