接入力标定 schema 3 与多点空间增益模型
保留旧格式和 cal_path,校验 SN、特征身份及坐标附件,按帧返回逐轴状态。相关测试 263 项通过,已核对存量预测并实测 180 帧录像。
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
"""Measurement identities shared by SDK runtime and offline calibration exporters."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
import numpy as np
|
||||
|
||||
from .calibration import filters_fingerprint
|
||||
|
||||
|
||||
def sha256_file(path) -> str:
|
||||
return hashlib.sha256(Path(path).read_bytes()).hexdigest()
|
||||
|
||||
|
||||
def domain_fingerprint(domain) -> str:
|
||||
"""Bind a coordinate lookup to the actual unroll, not just its dimensions."""
|
||||
data = domain.to_dict() if hasattr(domain, "to_dict") else domain
|
||||
digest = hashlib.sha256()
|
||||
for key, dtype in (("map_x", "<f4"), ("map_y", "<f4"), ("valid_mask", "u1"), ("world_xyz", "<f4")):
|
||||
array = np.ascontiguousarray(data[key], dtype=dtype)
|
||||
digest.update(key.encode("ascii"))
|
||||
digest.update(str(array.shape).encode("ascii"))
|
||||
digest.update(array.tobytes())
|
||||
return digest.hexdigest()
|
||||
|
||||
|
||||
def build_context(config, filters=None, *, geometry_sha256=None, source_scale=None,
|
||||
coordinates=None, output_domain_sha256=None, processing_backend=None,
|
||||
preprocessing=None) -> dict:
|
||||
"""Build the closed v1 feature identity from effective values, excluding readout filters."""
|
||||
camera = config.get("camera", {})
|
||||
tracker = dict(config.get("tracker", {}))
|
||||
raw_downsample = tracker.get("hhd_downsample", 1)
|
||||
try:
|
||||
downsample = max(1, int(raw_downsample)) if raw_downsample is not None else 1
|
||||
except (TypeError, ValueError):
|
||||
downsample = 1
|
||||
tracker["hhd_downsample"] = downsample
|
||||
if source_scale is not None:
|
||||
source_scale = float(source_scale)
|
||||
measurement = filters_fingerprint(config.get("filters", {}) if filters is None else filters).get("measurement", {})
|
||||
# A missing EMA setting has the same effective meaning as the SDK default.
|
||||
measurement.setdefault("flow_ema_alpha", 1.0)
|
||||
result = {
|
||||
"stitch_resolution": camera.get("resolution_stitch"),
|
||||
"dis_mode": tracker.get("dis_mode"),
|
||||
"hhd_downsample": downsample,
|
||||
"filters": {"measurement": measurement},
|
||||
}
|
||||
if geometry_sha256 is not None:
|
||||
result["geometry_sha256"] = geometry_sha256
|
||||
if source_scale is not None:
|
||||
result["source_scale"] = float(source_scale)
|
||||
if coordinates is not None:
|
||||
result["coordinates"] = coordinates
|
||||
if output_domain_sha256 is not None:
|
||||
result["output_domain_sha256"] = output_domain_sha256
|
||||
effective = {
|
||||
"feature_version": "orisys_hhd_raw/1",
|
||||
"processing_backend": processing_backend or config.get("type", "compound_eye"),
|
||||
"camera": {key: camera.get(key) for key in ("resolution_raw", "resolution_stitch")},
|
||||
"tracker": tracker,
|
||||
"contact": config.get("contact", {}),
|
||||
"measurement": measurement,
|
||||
"geometry_sha256": geometry_sha256,
|
||||
"output_domain_sha256": output_domain_sha256,
|
||||
"source_scale": source_scale,
|
||||
"preprocessing": preprocessing or {},
|
||||
}
|
||||
encoded = json.dumps(effective, sort_keys=True, separators=(",", ":"), allow_nan=False)
|
||||
result["feature_signature_sha256"] = hashlib.sha256(encoded.encode("utf-8")).hexdigest()
|
||||
return result
|
||||
Reference in New Issue
Block a user