///|
pub(all) enum IssueSeverity {
Info
Warning
Error
} derive(Debug, Eq, ToJson)
///|
pub(all) struct QualityIssue {
severity : IssueSeverity
source : String
message : String
} derive(Debug, Eq, ToJson)
///|
pub(all) struct DatasetQualityReport {
issues : Array[QualityIssue]
} derive(Debug, Eq, ToJson)
///|
fn issue(
severity : IssueSeverity,
source : String,
message : String,
) -> QualityIssue {
{ severity, source, message }
}
///|
pub fn DatasetQualityReport::is_clean(self : DatasetQualityReport) -> Bool {
self.issues.all(fn(item) { item.severity != Error })
}
///|
pub fn DatasetQualityReport::summary(self : DatasetQualityReport) -> String {
let errors = self.issues.count_if(fn(item) { item.severity == Error })
let warnings = self.issues.count_if(fn(item) { item.severity == Warning })
let infos = self.issues.count_if(fn(item) { item.severity == Info })
"errors=\{errors}, warnings=\{warnings}, info=\{infos}"
}
///|
pub fn inspect_stream_quality(
images : ArrayView[ImageFrameRef],
camera : CameraIntrinsics?,
trajectory : ArrayView[TrajectorySample],
depth : ArrayView[DepthMetadata],
annotations : ArrayView[Annotation],
) -> DatasetQualityReport {
let issues = Array::new()
if images.is_empty() {
issues.push(issue(Error, "image", "no image frames"))
}
if trajectory.is_empty() {
issues.push(issue(Warning, "trajectory", "no trajectory samples"))
}
if depth.is_empty() {
issues.push(issue(Info, "depth", "no depth metadata"))
}
match camera {
Some(cam) => {
if cam.width <= 0 || cam.height <= 0 {
issues.push(issue(Error, "camera", "invalid image size"))
}
if cam.k.length() != 9 {
issues.push(issue(Error, "camera", "camera_matrix must have 9 values"))
}
if cam.p.length() != 12 {
issues.push(
issue(Error, "camera", "projection_matrix must have 12 values"),
)
}
}
None => issues.push(issue(Warning, "camera", "missing camera calibration"))
}
for item in depth {
validate_depth_metadata(item) catch {
err => issues.push(issue(Error, "depth", "\{Repr(err)}"))
}
}
for ann in annotations {
if ann.confidence < 0.0 || ann.confidence > 1.0 {
issues.push(issue(Error, "annotation", "confidence outside [0, 1]"))
}
}
{ issues, }
}
///|
pub fn[T] timestamp_span_ns(
items : ArrayView[T],
stamp_of : (T) -> Stamp,
) -> Int64 {
if items.length() < 2 {
0L
} else {
stamp_of(items[0]).delta_ns(stamp_of(items[items.length() - 1]))
}
}