Multimodal inspection / Guide 84
Wind Turbine Blade Mapping Without False Defect Growth
Map wind turbine blade observations with explicit blade identity, span coordinates, scale uncertainty, and repeat-inspection registration before human review.
Illustrative engineering guide. Examples are not client deployments, production-ready integrations, or evidence of measured results. Validate the design with your domain and security owners.

A hypothetical wind operator compares two drone visits and receives an alarming claim: a blade marking has doubled in length. The earlier image was captured farther away, the later crop was enlarged, and the photographs show different blades. The apparent growth is a combination of display scale and identity mismatch. No amount of confident narrative can repair a comparison whose observations do not refer to the same physical feature.
Treat repeat inspection as an evidence-matching problem before treating it as change detection. The output is a bounded packet for a qualified blade specialist, with candidate appearance, localization, coverage, and uncertainty. It does not establish internal laminate condition, structural integrity, temperature, or the cause of a surface mark. It should not instruct technicians to repair a blade from RGB appearance alone.
Anchor Every Mark to a Blade Frame
Require turbine identifier, blade serial or verified installed position, blade configuration revision, inspection session, capture time, and source image digest. Record rotor pose and the convention used to name blade positions. A rotor rotation can make a clock-position label refer to a different blade at the next visit, so clock position is not a stable asset identity.
Define span in meters from the blade root and chordwise position in a documented local surface frame. Identify pressure side, suction side, leading edge, and trailing edge explicitly. Store image regions in pixels with an upper-left origin, then retain the registration transform that maps them to the blade reference. Normalized span is dimensionless and must not be confused with meters.
The W3C provenance overview separates artifacts from the activities that derive them. That is useful for tracking a source photograph, a rectified crop, a feature association, and a reviewer correction. Revising the association should create a new record rather than silently move the old mark to a different blade.
Use a Specialist Measurement, Not Crop Width
Let the candidate generator identify a visible contrast feature and propose a matching region from the previous visit. A measurement specialist must validate physical scale, viewing geometry, and feature endpoints before estimating length. Curved surfaces and oblique views make a single pixels-per-millimeter factor unsafe unless its limited applicability has been demonstrated.
OpenCV’s camera calibration tutorial explains intrinsic parameters, distortion, and coordinate transformations from known object points. These techniques support a measurement pipeline, but calibration does not itself solve blade deformation, poor surface texture, or missing viewpoints. Any geometry engine returns computed measurements subject to those assumptions, not infallible physical ground truth.
Keep a length uncertainty bound for each visit and a separate localization bound for matching the feature. Comparing only the central estimates can manufacture growth near the resolution limit. NIST’s combined uncertainty guidance discusses covariance and systematic effects. Shared scale errors require explicit treatment; two measurements are not independent just because they were exported in separate files.
Test the Growth Gate
This Python example tests the HARNESS using synthetic structured measurements. It is not a trained vision model, camera, CAD engine, or real inspection-performance evaluation. Supplied bounds are conservative interval assumptions, not confidence intervals. The growth margin and matching tolerance are illustrative workflow policy values, not maintenance standards.
from math import isfinite
old = dict(blade="WT7-B2", revision=4, side="pressure",
span_m=12.0, frame="root-span-m", time_s=100,
image="synthetic-old", length_mm=20.0, bound_mm=3.0,
registration_m=0.1, visible=True)
new = dict(old, time_s=200, image="synthetic-new", length_mm=24.0)
def compare(a, b):
for key in ("blade", "revision", "side", "frame"):
if a[key] != b[key]:
return "abstain:association"
for m in (a, b):
if not m["visible"] or not m["image"]:
return "abstain:coverage"
if not all(isfinite(m[k]) and m[k] >= 0 for k in
("length_mm", "bound_mm", "registration_m", "span_m")):
return "abstain:measurement"
if (not all(isfinite(m["time_s"]) for m in (a, b))
or b["time_s"] <= a["time_s"]):
return "abstain:chronology"
if abs(a["span_m"] - b["span_m"]) + a["registration_m"] + b["registration_m"] > 0.5:
return "abstain:location"
lower_growth = b["length_mm"] - b["bound_mm"] - a["length_mm"] - a["bound_mm"]
return "review-growth" if lower_growth > 2 else "review-inconclusive"
assert compare(old, new) == "review-inconclusive"
assert compare(old, dict(new, length_mm=32)) == "review-growth"
assert compare(old, dict(new, blade="WT7-B3")) == "abstain:association"
assert compare(old, dict(new, visible=False)) == "abstain:coverage"
assert compare(old, dict(new, time_s=90)) == "abstain:chronology"
growth = dict(new, length_mm=32)
for invalid in (float("nan"), float("inf"), float("-inf")):
assert compare(dict(old, time_s=invalid), growth) == "abstain:chronology"
assert compare(old, dict(growth, time_s=invalid)) == "abstain:chronology"
assert compare(dict(old, time_s=invalid), dict(growth, time_s=invalid)) == "abstain:chronology"
assert compare(old, dict(growth, time_s=100)) == "abstain:chronology"
assert compare(old, dict(growth, time_s=101)) == "review-growth"
print("blade comparison harness: synthetic assertions passed")
The four-millimeter central difference remains inconclusive under the supplied bounds. A larger interval-separated difference becomes a growth review candidate, not a confirmed defect progression. Both visit timestamps must be finite and strictly ordered; unknown chronology blocks even a large apparent growth. The matching test is deliberately conservative and incomplete: real association must account for chordwise location, surface shape, pose, and feature identity. The snippet checks already supplied measurements rather than implementing full three-dimensional reconstruction.
Do Not Lose the Unseen Surface
Track coverage by blade, side, and span segment, with visibility and effective measurement scale. A beautiful leading-edge pass does not inspect the suction side. When one visit misses a segment, report that the comparison is unavailable there. Never draw a zero-change map over unobserved surface simply because the candidate matcher returned no feature.
Repeated frames from the same hover are correlated. Select useful viewpoints for coverage, but do not multiply confidence by the number of nearly identical crops. Different agents looking at those crops do not create independent evidence either. A specialist component earns its complexity when it validates registration or supplies another measurement method, not when it paraphrases a surface description.
The aircraft surface evidence exercise shares the requirement to separate installed-part identity from appearance. The broader manufacturing maintenance workflow addresses the downstream ownership and scheduling concerns once a qualified person decides what follow-up is appropriate.
Keep Corrections and Tickets Traceable
Server-side authorization should restrict access by tenant and wind asset portfolio. Treat markings, filenames, and OCR instructions as untrusted media content. Keep source images immutable and version reviewer corrections. If a blade is replaced, close the comparison lineage at the replacement event rather than interpreting a new surface as sudden healing.
The fixture omits authentication, trusted asset registries, calibration verification, durable approvals, database transactions, and maintenance-provider semantics. An approved inspection request should use a stable idempotency key containing blade, paired sessions, feature association, and policy version. A timeout means unknown creation status; reconcile with the authoritative system before retrying. No model caption should carry permission to issue a physical intervention.
Acceptance Tests and Evaluation
- Pair different blade identifiers with similar-looking marks; require association abstention despite a high visual score.
- Enlarge a crop without updating its transform; reject physical-length comparison until scale lineage is restored.
- Compare overlapping length intervals; report inconclusive growth rather than selecting the larger central estimate.
- Remove suction-side coverage from one visit; leave that region unknown in the change map.
- Reverse inspection timestamps, supply NaN or infinity for either visit, or replace the blade revision; prevent a misleading longitudinal comparison.
- Replay an approved follow-up request after timeout; reconcile one ticket with both evidence sessions attached.
Evaluate against expert-adjudicated pairs of inspection sessions. Measure correct feature associations divided by all attempted associations, false growth flags divided by all adjudicated non-growth pairs, and comparable surface segments divided by all planned segments. Publish abstention reasons and uncertainty distributions. Randomly splitting neighboring images between training and evaluation would overstate independence; hold out turbines or visits instead.
Start with one blade family and offline comparisons under mandatory human review. Measure reviewer effort and association corrections before enabling ticket drafts. AI systems engineering should make the comparison contract the first milestone. A useful system knows when two photographs cannot support a growth claim, even when the pictures look convincingly different.