final 2024_Remote_Sensing
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
import rasterio
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
def map_two_digit_code(code: int) -> str:
|
||||
"""
|
||||
Returns a string label like 'Water -> Agriculture'
|
||||
by interpreting the tens digit as the 'from' class
|
||||
and the ones digit as the 'to' class.
|
||||
|
||||
Example:
|
||||
code = 34
|
||||
tens_digit = 3 -> 'Forest'
|
||||
ones_digit = 4 -> 'Agriculture'
|
||||
return 'Forest -> Agriculture'
|
||||
"""
|
||||
# Define what each digit means
|
||||
digit_to_label = {
|
||||
1: "Water",
|
||||
2: "Urban",
|
||||
3: "Forest",
|
||||
4: "Agriculture"
|
||||
}
|
||||
|
||||
# Tens digit = 'from' class
|
||||
tens_digit = code // 10
|
||||
from_label = digit_to_label.get(tens_digit, "Unknown")
|
||||
|
||||
# Ones digit = 'to' class
|
||||
ones_digit = code % 10
|
||||
to_label = digit_to_label.get(ones_digit, "Unknown")
|
||||
|
||||
return f"{from_label} -> {to_label}"
|
||||
|
||||
def generate_change_detection_report(tif_path: str, output_csv_path: str = None) -> pd.DataFrame:
|
||||
"""
|
||||
Reads a single-band change-detection GeoTIFF with classes from 11 to 44,
|
||||
generates a report of pixel counts, area, and applies a label for every code.
|
||||
|
||||
:param tif_path: Path to the input GeoTIFF.
|
||||
:param output_csv_path: If provided, saves the report as a CSV file.
|
||||
:return: A pandas DataFrame with columns: ['Class_Value', 'Pixel_Count', 'Area', 'Label'].
|
||||
"""
|
||||
# 1. Open the raster
|
||||
with rasterio.open(tif_path) as src:
|
||||
band = src.read(1)
|
||||
transform = src.transform
|
||||
|
||||
# Compute pixel area
|
||||
pixel_width = transform[0]
|
||||
pixel_height = -transform[4] # Typically negative
|
||||
pixel_area = pixel_width * pixel_height
|
||||
|
||||
# 2. Count unique class values
|
||||
unique_vals, counts = np.unique(band, return_counts=True)
|
||||
|
||||
# 3. Filter classes from 11 to 44
|
||||
valid_mask = (unique_vals >= 11) & (unique_vals <= 44)
|
||||
filtered_classes = unique_vals[valid_mask]
|
||||
filtered_counts = counts[valid_mask]
|
||||
|
||||
# 4. Calculate area per class
|
||||
areas = filtered_counts * pixel_area
|
||||
|
||||
# 5. Create a DataFrame
|
||||
df_report = pd.DataFrame({
|
||||
"Class_Value": filtered_classes,
|
||||
"Pixel_Count": filtered_counts,
|
||||
"Area": areas
|
||||
})
|
||||
|
||||
# 6. Apply the custom mapping function to get a text label (e.g., 'Water -> Agriculture')
|
||||
df_report["Label"] = df_report["Class_Value"].apply(map_two_digit_code)
|
||||
|
||||
# 7. (Optional) sort by Class_Value
|
||||
df_report.sort_values(by="Class_Value", inplace=True)
|
||||
|
||||
# 8. Optionally save the DataFrame to a CSV file
|
||||
if output_csv_path:
|
||||
df_report.to_csv(output_csv_path, index=False)
|
||||
|
||||
return df_report
|
||||
|
||||
# ---------------
|
||||
# Example usage:
|
||||
if __name__ == "__main__":
|
||||
input_tif = "change_detected/change_detection.tif" # Update path as needed
|
||||
report_df = generate_change_detection_report(
|
||||
tif_path=input_tif,
|
||||
output_csv_path="report/change_detection_report.csv"
|
||||
)
|
||||
|
||||
print("Detailed Report (11–44):")
|
||||
print(report_df)
|
||||
|
||||
# Optional: Summarize area by the Label column
|
||||
summary = report_df.groupby("Label")["Area"].sum().reset_index()
|
||||
summary.columns = ["Label", "Total_Area"]
|
||||
print("\nArea Summary by Label:")
|
||||
print(summary)
|
||||
Reference in New Issue
Block a user