使用GDAL或Rasterio实现栅格差值运算并复制原始影像EXIF信息
Absolutely! Both GDAL and Rasterio are perfect tools to handle your task—performing the difference operation between your drone image and mask, plus transferring the original EXIF metadata to the output. Let’s break down how to do this with each tool:
Using GDAL (Python Bindings)
GDAL gives you low-level control over raster data and metadata, making it straightforward to copy EXIF info. Here's a step-by-step implementation:
- Import GDAL and open your datasets
Add a quick check to confirm both images share the same dimensions (even if you know they do, it prevents accidental errors). - Perform the difference operation
Read pixel arrays from both images and compute the difference (adjust the order to match your needs, e.g., original - mask or mask - original). - Create the output raster
Copy the original image's geotransform, projection, and full metadata (including EXIF) to the new file. - Write the result and clean up
from osgeo import gdal # Open input files in read-only mode original_ds = gdal.Open("original_drone_image.tif", gdal.GA_ReadOnly) mask_ds = gdal.Open("mask_image.tif", gdal.GA_ReadOnly) # Verify dimensions match (optional but recommended) assert original_ds.RasterXSize == mask_ds.RasterXSize, "Images have mismatched width" assert original_ds.RasterYSize == mask_ds.RasterYSize, "Images have mismatched height" # Read pixel data from the first band original_arr = original_ds.GetRasterBand(1).ReadAsArray() mask_arr = mask_ds.GetRasterBand(1).ReadAsArray() # Compute the difference (adjust order as needed) diff_arr = original_arr - mask_arr # Set up output driver and create the result file driver = gdal.GetDriverByName("GTiff") output_ds = driver.Create( "difference_result.tif", original_ds.RasterXSize, original_ds.RasterYSize, 1, gdal.GDT_Int16, # Use signed int to handle negative values; adjust based on your data ) # Copy geospatial reference info from the original image output_ds.SetGeoTransform(original_ds.GetGeoTransform()) output_ds.SetProjection(original_ds.GetProjection()) # Copy all metadata, including EXIF (explicitly target the EXIF domain for TIFFs) output_ds.SetMetadata(original_ds.GetMetadata()) output_ds.SetMetadata(original_ds.GetMetadata("EXIF"), "EXIF") # Write the computed difference array to the output output_ds.GetRasterBand(1).WriteArray(diff_arr) # Close all datasets to save changes properly original_ds = None mask_ds = None output_ds = None
Using Rasterio
Rasterio is more Pythonic and user-friendly, with built-in support for metadata handling. Here's how to implement your workflow:
- Open both images with Rasterio
Access the image data, profile (which includes geospatial settings), and EXIF tags. - Compute the difference
Read pixel arrays and calculate your desired difference. - Prepare the output profile
Copy the original image's profile and adjust the data type to handle potential negative values from the difference. - Write the result and transfer EXIF tags
Use the profile to create the output file, write the data, then explicitly copy the original EXIF tags.
import rasterio # Open original image and capture its data, profile, and EXIF tags with rasterio.open("original_drone_image.tif") as original_src: original_arr = original_src.read(1) output_profile = original_src.profile.copy() exif_tags = original_src.tags() # Open mask image and verify dimensions match with rasterio.open("mask_image.tif") as mask_src: mask_arr = mask_src.read(1) assert original_src.shape == mask_src.shape, "Images have mismatched dimensions" # Compute the difference operation diff_arr = original_arr - mask_arr # Update the output profile to support signed values (adjust dtype as needed) output_profile.update( dtype=rasterio.int16, count=1, compress='lzw' # Optional: add compression to reduce file size ) # Write the result and copy EXIF tags to the output with rasterio.open("difference_result.tif", 'w', **output_profile) as dst: dst.write(diff_arr, 1) dst.update_tags(**exif_tags)
Key Things to Keep in Mind
- Data Type Handling: If your original drone image uses unsigned integers (like
uint8), subtracting the mask can produce negative values. Use a signed data type (e.g.,int16orfloat32) for the output to avoid data loss. - EXIF Relevance: Some EXIF tags (like exposure settings or GPS data) describe the original drone capture—transferring these to the result makes sense since it’s derived directly from that image.
- File Format: Both examples use TIFF, which fully supports EXIF metadata. If you’re working with JPEG, ensure your output format retains EXIF support before proceeding.
内容的提问来源于stack exchange,提问作者Aceituna
相关产品推荐
相关产品推荐

