#pragma once #include "frame_result.hpp" #include "door_risk.hpp" namespace cms { template inline std::optional optionalField(Json const& j,char const* key) { auto it=j.find(key);return it==j.end()||it->is_null()?std::nullopt:std::optional(it->get()); } inline RiskResult parseRisk(Json const& j) { RiskResult r;r.status=j.at("status");r.risk_score=optionalField(j,"risk_score");r.risk_level=j.at("risk_level");r.decision=j.at("decision"); r.risk_type=j.value("risk_type",std::string());r.door_id=optionalField(j,"door_id"); r.source=optionalField(j,"source");r.track_id=optionalField(j,"track_id");r.side=optionalField(j,"side"); if(j.contains("door_mask")) {auto const& d=j.at("door_mask");r.door_mask={d.at("status"),d.at("annotation_index"),optionalField(d,"path"),d.at("format"),d.at("area_px")};} r.warning_distance_relative=j.value("warning_distance_relative",.30);r.release_distance_relative=j.value("release_distance_relative",.45); for(auto const& x:j.at("regions")) { RegionRisk v;v.status=x.at("status");v.risk_score=optionalField(x,"risk_score");v.risk_level=x.at("risk_level");v.decision=x.at("decision");v.source=x.at("source"); v.track_id=x.at("track_id");v.side=x.at("side");v.state=optionalField(x,"state");v.door_zone=x.value("door_zone",std::string()); v.region_area_px=optionalField(x,"region_area_px");v.door_overlap_px=optionalField(x,"door_overlap_px"); v.region_overlap_ratio=optionalField(x,"region_overlap_ratio");v.min_distance_px=optionalField(x,"min_distance_px"); v.region_scale_px=optionalField(x,"region_scale_px");v.distance_relative=optionalField(x,"distance_relative");r.regions.push_back(std::move(v)); } return r; } inline DoorAssignment parseAssignment(Json const& j) { DoorAssignment a;a.track_id=j.at("track_id");a.person_index=j.at("person_index");a.door_zone=j.at("door_zone");a.raw_door_zone=j.at("raw_door_zone"); a.front_probability=j.at("front_probability");a.smoothed_front_probability=j.at("smoothed_front_probability");a.confidence=j.at("confidence");a.evidence_source=j.at("evidence_source"); a.pose_feature_count=j.at("pose_feature_count");a.history_frames=j.at("history_frames");a.features=j.at("features").get>();a.feature_frontness=j.at("feature_frontness").get>();return a; } inline FrameResult makeFrameResult(Json const& record,Json const& raw,CaptureMetadata capture) { FrameResult r;r.frame_index=record.at("frame_index");r.track_ids=record.at("track_ids").get>();r.boxes=record.at("boxes").get>>();r.capture=capture;r.ungated_risk=parseRisk(raw);return r; } }