I am loading a tif file with rasterio to cut it to pieces and save the pieces. However, the saved pieces look different from the loaded file. The file is ortho photo map shot from a plane and has 4 layers – R, G, B, NIR
. The input file is a high resolution raster with some 15×15 cm per pixel, see sample image:
When I tried to just load it to python and save it as is the image changes to this:
I have no idea what might be wrong, can it be due to the memory constraint? I have tried many different “fixes” as are added in code but none helped. The original file has 129MB and the saved from raster.io 476MB – why is that? All chunks have about 15-18MB and look exactly as faded as the second image.
Here is my code:
import rasterio
from rasterio.windows import Window
import os
# Function to split raster
def split_raster(image_path, output_folder, chunk_width, chunk_height):
with rasterio.open(image_path) as src:
# Get the dimensions of the image
img_width = src.width
img_height = src.height
# Calculate the number of chunks in both dimensions
num_chunks_x = (img_width + chunk_width - 1) // chunk_width # Ensures all parts are included
num_chunks_y = (img_height + chunk_height - 1) // chunk_height # Ensures all parts are included
# Ensure the output directory exists
if not os.path.exists(output_folder):
os.makedirs(output_folder)
# Loop over chunks and save them
for i in range(num_chunks_x):
for j in range(num_chunks_y):
# Define the window to crop
window = Window(i * chunk_width, j * chunk_height, chunk_width, chunk_height)
# Adjust window size if it exceeds image bounds (handling edge cases)
window = window.intersection(Window(0, 0, img_width, img_height))
# Read the data from the window
chunk_data = src.read(window=window)
# Define the metadata for the chunk
chunk_transform = src.window_transform(window)
chunk_meta = src.meta.copy()
chunk_meta.update({
"driver": "GTiff",
"height": window.height,
"width": window.width,
"transform": chunk_transform,
"compress": "lzw", # Using LZW compression to preserve color integrity
"count": src.count, # Ensure all channels are included
"dtype": src.dtypes[0] # Ensure the data type is preserved
})
if src.nodata is not None:
chunk_meta.update({"nodata": src.nodata})
chunk_meta.update({
"photometric": src.profile.get("photometric", "RGB") # Ensure correct color interpretation
})
# Save the chunk
chunk_name = f"chunk_{i}_{j}.tif"
chunk_path = os.path.join(output_folder, chunk_name)
with rasterio.open(chunk_path, "w", **chunk_meta) as dst:
dst.write(chunk_data)
print(f"Saved {chunk_path}")
if j==4:
break
break
# Define parameters
image_path = '../Code/ZnH/B6-1.tif' # Path to the large raster image
output_folder = "../Code/ZnH/splits" # Folder to save the chunks
chunk_width = 512 # Width of each chunk
chunk_height = 512 # Height of each chunk
# Split the raster
split_raster(image_path, output_folder, chunk_width, chunk_height)