分析结果在缺少会话零点时保留原始力值并说明原因
多点标定未测零点时,分析把整帧判无效,原始值与牛顿值都显示"不可用";现按 SDK 标定模型约定只清空该轴牛顿值,并在回放提示与分析设置中说明需要零点。算法版本升为 flow-hhd-contact-2,旧缓存不再复用;新增测试在旧代码上失败、新代码通过,studio/shared 全量与 HEAD 失败集合一致。
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
"""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()
|
||||
Reference in New Issue
Block a user