Visual algorithm debugging overlays and SVG/HTML report generation for MoonBit.
moon add xlh123jjj/moonbit-visual-debug///|
test "build a visual inspection report" {
let layer = Layer::new(id="detections").add(
BBox(
rect=Rect::new(x=12.0, y=10.0, width=48.0, height=36.0),
label=Some(Label::new(text="part", score=0.91)),
color=Some(Color::rgb(r=39, g=125, b=255)),
),
)
let doc = DebugDocument::new(
title="inspection",
image=ImageSpec::new(width=96, height=64),
).add_layer(layer)
inspect(doc.overlay_count(), content="1")
inspect(doc.to_svg().contains("<svg"), content="true")
inspect(doc.to_html_report().contains("<table>"), content="true")
}moon run --target wasm-gc cmd/main > report.html///|
test "load COCO annotations" {
let source =
#|{"categories":[{"id":1,"name":"part"}],
#|"annotations":[{"id":7,"image_id":1,"category_id":1,
#|"bbox":[10,12,20,16]}]}
match CocoDataset::from_json(source) {
Ok(dataset) => inspect(dataset.to_detections()[0].label, content="part")
Err(_) => fail("expected valid COCO data")
}
}| Component | Responsibility |
|---|---|
| geometry.mbt, color.mbt | Value types and deterministic presentation primitives. |
| overlay.mbt, transform.mbt | Overlay document model, composition, transforms, and bounds. |
| svg.mbt, report.mbt, raster.mbt | SVG, HTML, canvas, and PNG output backends. |
| analysis.mbt, validation.mbt | Detection matching, error overlays, and input diagnostics. |
| dataset.mbt, adapter.mbt | COCO, YOLO, and Pascal VOC interchange. |
| diff.mbt, metrics.mbt, manifest.mbt | CI-ready diffing, evaluation summaries, and stable exports. |
moon bench visual_bench.mbt --target native --release --deny-warnmoon fmt --check
moon check --target wasm-gc --deny-warn
moon test --target wasm-gc --deny-warn
moon check --target native --deny-warn
moon test --target native --deny-warn
moon info --target wasm-gc
git diff --exit-codefn CocoAnnotation::new(id~ : Int, image_id~ : Int, category_id~ : Int, bbox~ : Rect, area? : Double, iscrowd? : Int) -> CocoAnnotationpub(all) struct CocoDataset {
images : Array[CocoImage]
categories : Array[CocoCategory]
annotations : Array[CocoAnnotation]
} derive(ToJson, Debug)fn CocoDataset::new(annotations~ : Array[CocoAnnotation], categories? : Array[CocoCategory], images? : Array[CocoImage]) -> CocoDatasetfn CocoDataset::try_new(annotations~ : Array[CocoAnnotation], categories? : Array[CocoCategory], images? : Array[CocoImage]) -> Result[CocoDataset, CocoError]fn CocoResult::new(image_id~ : Int, category_id~ : Int, bbox~ : Rect, score~ : Double) -> CocoResultpub(all) struct ConfusionMatrix {
labels : Array[String]
cells : Array[ConfusionCell]
} derive(ToJson, Debug)pub(all) struct DetectionMetrics {
iou_threshold : Double
score_threshold : Double
matches : MatchSummary
classes : Array[ClassMetrics]
confusion : ConfusionMatrix
micro : AggregateMetrics
macro_average : AggregateMetrics
} derive(ToJson, Debug)pub(all) struct Diagnostic {
level : DiagnosticLevel
path : String
message : String
} derive(ToJson, Debug)pub(all) struct DocumentDiff {
baseline_title : String
candidate_title : String
baseline_image : ImageSpec
candidate_image : ImageSpec
baseline_image_href : String?
candidate_image_href : String?
title_changed : Bool
image_size_changed : Bool
image_href_changed : Bool
overlay_count_delta : Int
layer_changes : Array[LayerChange]
} derive(ToJson, Debug)pub(all) struct DocumentManifest {
title : String
image_width : Int
image_height : Int
layer_count : Int
visible_layer_count : Int
total_overlay_count : Int
visible_overlay_count : Int
overlays : OverlayKindCounts
visible_overlays : OverlayKindCounts
content_bounds : Rect?
diagnostics : DiagnosticSeverityCounts
is_valid : Bool
layers : Array[LayerManifest]
} derive(ToJson, Debug)pub(all) struct LayerChange {
id : String
kind : LayerChangeKind
baseline_index : Int?
candidate_index : Int?
visibility_changed : Bool
opacity_changed : Bool
overlay_delta : Int
} derive(ToJson, Debug)pub(all) struct LayerManifest {
id : String
visible : Bool
opacity : Double
overlay_count : Int
overlays : OverlayKindCounts
} derive(ToJson, Debug)pub(all) struct MatchSummary {
records : Array[MatchRecord]
true_positive : Int
false_positive : Int
false_negative : Int
label_mismatch : Int
} derive(ToJson, Debug)pub(all) enum Overlay {
BBox(rect~ : Rect, label~ : Label?, color~ : Color?)
Mask(polygons~ : Array[Array[Point]], label~ : Label?, color~ : Color?)
Keypoints(points~ : Array[Keypoint], color~ : Color?)
Trajectory(path~ : Trajectory, color~ : Color?)
Heatmap(cells~ : Array[HeatCell], low~ : Color?, high~ : Color?)
ErrorRegion(rect~ : Rect, expected~ : String, actual~ : String, severity~ : Double)
} derive(ToJson, Debug)pub(all) struct ReportOptions {
svg : SvgOptions
include_metadata : Bool
theme : String
} derive(ToJson, Debug)fn VocAnnotation::new(filename? : String, size~ : ImageSpec, objects~ : Array[VocObject]) -> VocAnnotationfn VocAnnotation::try_new(filename? : String, size~ : ImageSpec, objects~ : Array[VocObject]) -> Result[VocAnnotation, AdapterError]fn YoloBox::from_line(line : String, image~ : ImageSpec, classes~ : Array[String]) -> Result[YoloBox, AdapterError]fn YoloBox::from_rect(class_id~ : Int, rect~ : Rect, image~ : ImageSpec, confidence? : Double) -> Result[YoloBox, AdapterError]fn YoloBox::try_new(class_id~ : Int, center_x~ : Double, center_y~ : Double, width~ : Double, height~ : Double, confidence? : Double) -> Result[YoloBox, AdapterError]fn compare_detections(expected : Array[Detection], actual : Array[Detection], iou_threshold? : Double) -> MatchSummaryfn evaluate_detections(expected : Array[Detection], actual : Array[Detection], iou_threshold? : Double, score_threshold? : Double) -> Result[DetectionMetrics, MetricsError]fn sweep_iou_thresholds(expected : Array[Detection], actual : Array[Detection], thresholds : Array[Double], score_threshold? : Double) -> Result[Array[DetectionMetrics], MetricsError]Visual algorithm debugging overlays and SVG/HTML report generation for MoonBit.