import numpy as np import cv2 from skimage.morphology import skeletonize def crack_metrics(mask: np.ndarray): # mask: [H,W] 0/1 area_px = int(mask.sum()) # largest connected component num_labels, labels, stats, _ = cv2.connectedComponentsWithStats(mask.astype(np.uint8), connectivity=8) largest_cc = 0 if num_labels > 1: # ignore background label 0 largest_cc = int(stats[1:, cv2.CC_STAT_AREA].max()) # length estimate via skeletonization skel = skeletonize(mask.astype(bool)) length_px = int(skel.sum()) return { "area_px": area_px, "length_px": length_px, "largest_component_px": largest_cc, } def severity_from_metrics(m): # Tune these thresholds on your validation set area = m["area_px"] length = m["length_px"] largest = m["largest_component_px"] score = 0 if area > 1500: score += 1 if area > 6000: score += 1 if length > 600: score += 1 if length > 2000: score += 1 if largest > 2500: score += 1 if score >= 4: return "High" if score >= 2: return "Medium" return "Low"