e2cac0ae40
多点标定未测零点时,分析把整帧判无效,原始值与牛顿值都显示"不可用";现按 SDK 标定模型约定只清空该轴牛顿值,并在回放提示与分析设置中说明需要零点。算法版本升为 flow-hhd-contact-2,旧缓存不再复用;新增测试在旧代码上失败、新代码通过,studio/shared 全量与 HEAD 失败集合一致。
85 lines
3.1 KiB
Python
85 lines
3.1 KiB
Python
"""A multi-point calibration with no session zero is explained, before and after a pass."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from types import SimpleNamespace
|
|
|
|
import cv2
|
|
import numpy as np
|
|
from orisys_app_shared.analysis import bare_video
|
|
from orisys_app_shared.i18n import t
|
|
from orisys_app_shared.sensors import scan_sensor_catalog
|
|
|
|
from orisys_studio.replay_controller import newton_missing_reason
|
|
from orisys_studio.ui.video_analysis_dialog import VideoAnalysisDialog
|
|
|
|
|
|
def _reader(**counts) -> SimpleNamespace:
|
|
return SimpleNamespace(meta={"counts": counts})
|
|
|
|
|
|
def test_a_result_without_a_session_zero_names_the_reason():
|
|
reader = _reader(
|
|
force_calibrated_frames=9800, force_newton_frames=0, force_zero_unavailable_frames=9800
|
|
)
|
|
assert newton_missing_reason(reader) == "status.units_zero_missing"
|
|
assert t("status.units_zero_missing") != "status.units_zero_missing"
|
|
|
|
|
|
def test_other_results_keep_the_generic_fallback():
|
|
assert newton_missing_reason(_reader()) == "status.units_raw_fallback"
|
|
assert newton_missing_reason(None) == "status.units_raw_fallback"
|
|
# Some newtons exist: the zero was measured, so "no zero" would be wrong.
|
|
reader = _reader(
|
|
force_calibrated_frames=10, force_newton_frames=4, force_zero_unavailable_frames=2
|
|
)
|
|
assert newton_missing_reason(reader) == "status.units_raw_fallback"
|
|
|
|
|
|
def _finger_dialog(tmp_path, document: dict) -> VideoAnalysisDialog:
|
|
clip = tmp_path / "clip.mp4"
|
|
writer = cv2.VideoWriter(str(clip), cv2.VideoWriter_fourcc(*"mp4v"), 10.0, (32, 24))
|
|
for _ in range(4):
|
|
writer.write(np.zeros((24, 32, 3), dtype=np.uint8))
|
|
writer.release()
|
|
facts = bare_video.probe(bare_video.resolve_video(clip))
|
|
catalog = scan_sensor_catalog()
|
|
finger = next(
|
|
entry
|
|
for entry in catalog.entries
|
|
if str(entry.product_family) == "finger"
|
|
and bare_video.setup_blocked_reason(entry) is None
|
|
)
|
|
path = tmp_path / "DD02-14.json"
|
|
path.write_text(json.dumps(document), encoding="utf-8")
|
|
dialog = VideoAnalysisDialog(video=clip, facts=facts, catalog=catalog)
|
|
assert dialog.select_profile(finger.ref)
|
|
dialog.select_calibration(path)
|
|
return dialog
|
|
|
|
|
|
def test_the_dialog_warns_before_a_model_pass_without_a_session_zero(qt_app, tmp_path):
|
|
dialog = _finger_dialog(
|
|
tmp_path,
|
|
{"schema_version": 3, "identity": {"sensor_type": "finger", "sn": "DD02-14"}},
|
|
)
|
|
try:
|
|
assert dialog.needs_session_zero()
|
|
assert not dialog.unloaded_reference.isChecked()
|
|
assert not dialog.zero_warning.isHidden()
|
|
assert dialog.zero_warning.text() == t("multical.video_zero_needed")
|
|
dialog.unloaded_reference.setChecked(True)
|
|
assert dialog.zero_warning.isHidden()
|
|
finally:
|
|
dialog.close()
|
|
|
|
|
|
def test_a_legacy_calibration_needs_no_session_zero(qt_app, tmp_path):
|
|
dialog = _finger_dialog(tmp_path, {"meta": {"sensor_type": "finger", "sn": "DD02-14"}})
|
|
try:
|
|
assert not dialog.needs_session_zero()
|
|
assert dialog.zero_warning.isHidden()
|
|
finally:
|
|
dialog.close()
|