Skip to main content

Autoplotter With Road Estimator Crack Info

| Platform | Strength | Typical Stack | |----------|----------|---------------| | Apache Airflow | Mature DAG visualisation, retry policies. | DockerOperator → autoplotterroad_estimator. | | Prefect Cloud | Serverless, easy Python‑first syntax. | @task decorators, async execution on Fargate. | | AWS Step Functions | Tight integration with S3, Lambda, Batch. | Lambda for vectorization, Batch for crack inference. | | Kubernetes (Kubeflow Pipelines) | Scalable GPU jobs, experiment tracking. | Pods: autoplotter-job, estimator-job. |

Best practice: Keep the road vector as a single source of truth (e.g., a PostGIS table with a primary key). All downstream crack‑maps reference that key; when the road network is refreshed, you can simply re‑run the crack estimator without re‑segmenting.


| Metric | How to compute | Target (typical) | |--------|----------------|------------------| | Precision / Recall (crack detection) | Compare model output to a hand‑annotated validation set (IoU ≥ 0.5). | Precision ≥ 0.90, Recall ≥ 0.85 | | Geometric error (centroid distance) | Distance between estimated crack line and ground‑truth line. | ≤ 0.15 m (for UAV 0.05 m/px) | | Attribute consistency | Verify that every crack polygon has a matching road_id. | 100 % | | Temporal stability | Run on two images captured a month apart; < 5 % change on unchanged sections. | ≤ 5 % false change | | Processing time | Tile‑level runtime (seconds) × number of tiles. | ≤ 30 s per 1 km² tile (GPU) | autoplotter with road estimator crack

Automated QC dashboard (e.g., Streamlit or Grafana) can surface:


  • Output: Generation of a geo-referenced database highlighting distress locations, types, and severities, ready for maintenance planning.

  • from cracknet import DeepCrack
    model = DeepCrack("weights/deepcrack_resnet.pth")
    model.eval()
    def infer_crack(chip):
        prob = model.predict(chip)          # (H, W) probability map
        binary = prob > 0.5                 # threshold
        # Morphological clean‑up
        cleaned = binary_opening(binary, disk(2))
        # Vectorize cracks (thin → skeleton → polygonize)
        cracks = rasterio.features.shapes(cleaned.astype('uint8'), transform=transform)
        # Convert to GeoDataFrame
        gdf = gpd.GeoDataFrame([
            "road_id": rid, "geometry": shape, "prob": prob.mean()
            for shape, value in cracks if value == 1
        ], crs="EPSG:3857")
        return gdf
    

    Key post‑processing steps

    | Step | Reason | |------|--------| | Morphological opening/closing | Removes spurious speckles, bridges tiny gaps (< 0.1 m). | | Skeletonization + line‑simplification | Produces clean polylines suitable for GIS. | | Confidence‑weighted filtering | Keeps only segments where prob > 0.7 or where the model’s uncertainty (Monte‑Carlo dropout) is low. | | Spatial join to road vector | Ensures each crack inherits road_id, lane_count, surface_type. |


    | Component | Core Function | Typical Input | Typical Output | |-----------|---------------|---------------|----------------| | Autoplotter | High‑throughput raster → vector conversion, geometric cleaning, and map‑ready rendering. | Orthophotos, LiDAR‐derived DEMs, satellite imagery (GeoTIFF, Cloud‑Optimized GeoTIFF). | GeoJSON / Shapefile road network, lane centrelines, shoulder polygons, attribute tables. | | Road‑Estimator | Machine‑learning based road‑surface condition estimator (roughness, texture, and especially crack detection). | Aligned road‑centerline vectors + high‑resolution surface imagery (e.g., 0.05 m/pixel UAV orthophotos). | Per‑segment crack probability, crack geometry (polylines), severity scores, confidence intervals. | | Integration Layer | Orchestrates data flow, spatial joins, and quality‑control (QC) reporting. | Outputs from the two modules above. | Final “crack‑map” product ready for GIS, asset‑management, or autonomous‑vehicle (AV) simulation. | | Platform | Strength | Typical Stack |

    Bottom line: By feeding the clean, topology‑aware road vectors from Autoplotter into a Road‑Estimator model, you get pixel‑accurate crack geometries that are automatically linked to the underlying road network. The result is a single, up‑to‑date geospatial dataset that can feed maintenance planning, budgeting, and AI‑driven driving‑simulation pipelines.


    import rasterio as rio
    import torch
    from autoplotter import RoadVectorizer, Preprocessor, SegModel
    # 1️⃣ Load a COG tile (256 Mpx max per job)
    with rio.open("s3://my-bucket/ortho/2025-06/region_01.tif") as src:
        img = src.read(window=rio.windows.Window(col_off=0, row_off=0, width=1024, height=1024))
        transform = src.window_transform(rio.windows.Window(0,0,1024,1024))
    # 2️⃣ Pre‑process (normalize + DEM flatten)
    proc = Preprocessor()
    img_norm = proc.normalize(img)
    # 3️⃣ Predict road mask
    model = SegModel("weights/deeplabv3_asphalt.pth")
    with torch.no_grad():
        mask = model.predict(img_norm)   # shape (H, W), binary road mask
    # 4️⃣ Vectorize
    vectorizer = RoadVectorizer(mask, transform)
    gdf = vectorizer.extract_vectors(min_length=2.0, simplify_tol=0.5)
    # 5️⃣ Save
    gdf.to_file("output/road_vectors.gpkg", driver="GPKG")
    

    Tip: Deploy the above as a AWS Lambda or Google Cloud Function triggered by new COG uploads. The function returns a signed URL to the generated vector file, enabling downstream pipelines to start immediately. Best practice: Keep the road vector as a