from PIL import Image def load_and_crop_image(path="Carson_map.png", crop_box=(15, 15, 1000, 950)): img = Image.open(path).convert("RGB") cropped_img = img.crop(crop_box) return cropped_img from sklearn.cluster import KMeans import numpy as np def cluster_image(cropped_img, n_clusters=6): img_array = np.array(cropped_img) pixels = img_array.reshape(-1, 3) kmeans = KMeans(n_clusters=n_clusters, random_state=42).fit(pixels) labels = kmeans.labels_.reshape(img_array.shape[:2]) return labels from collections import Counter import numpy as np def build_parcel_map(clustered_img, grid_size=20): height, width = clustered_img.shape n_rows = height // grid_size n_cols = width // grid_size parcel_map = np.zeros((n_rows, n_cols), dtype=int) for i in range(n_rows): for j in range(n_cols): patch = clustered_img[i*grid_size:(i+1)*grid_size, j*grid_size:(j+1)*grid_size].flatten() dominant = Counter(patch).most_common(1)[0][0] parcel_map[i, j] = dominant return parcel_map, n_rows, n_cols import matplotlib.pyplot as plt import matplotlib.patches as mpatches from matplotlib.colors import ListedColormap def plot_parcel_map(parcel_map, cluster_labels, land_colors, title="25×25 Land Parcels by Land Type"): cmap = ListedColormap(land_colors) plt.figure(figsize=(10, 8)) plt.imshow(parcel_map, cmap=cmap, origin='upper') legend_patches = [mpatches.Patch(color=land_colors[i], label=cluster_labels[i]) for i in cluster_labels] plt.legend(handles=legend_patches, bbox_to_anchor=(1.05, 1), loc='upper left', title="Land Type") plt.title(title) plt.axis('off') plt.tight_layout() plt.show() def plot_parcel_map_to_file(parcel_map, cluster_labels, land_colors, save_path="clustered_map.png", title="25×25 Land Parcels by Land Type"): cmap = ListedColormap(land_colors) fig, ax = plt.subplots(figsize=(10, 8)) cax = ax.imshow(parcel_map, cmap=cmap, origin='upper') legend_patches = [mpatches.Patch(color=land_colors[i], label=cluster_labels[i]) for i in cluster_labels] ax.legend(handles=legend_patches, bbox_to_anchor=(1.05, 1), loc='upper left', title="Land Type") ax.set_title(title) ax.axis('off') plt.tight_layout() plt.savefig(save_path) plt.close(fig) def get_cluster_labels(): return { 0: 'Pasture/Desert', 1: 'Productive Grass', 2: 'Pasture/Desert', 3: 'Riparian Sensitive Zone', 4: 'Rocky Area', 5: 'Water' } def get_land_colors(): return ['#dfb867', '#a0ca76', '#dfb867', '#5b8558', '#888888', '#3a75a8']