Files
orisys-app/apps/autocal/tests/test_calibration_feedback.py
ykcheungab 3304b4eda9 改为按帧自适应显示 Autocal 深度色阶
从有效 UV 区域计算当前帧范围,排除无效值和区域外像素。57 项定向测试及代码、文档检查通过。
2026-10-11 18:14:54 +08:00

116 lines
4.4 KiB
Python

"""Live operator feedback must preserve sample validity and UV orientation."""
from dataclasses import replace
import numpy as np
from orisys_app_shared.acquisition.models import SdkPacket
class Worker:
is_running = True
def __init__(self):
self.sinks = []
def add_sink(self, sink):
self.sinks.append(sink)
def remove_sink(self, sink):
self.sinks.remove(sink)
def packet(**values):
image = np.full((64, 80, 3), (10, 20, 30), dtype=np.uint8)
base = SdkPacket(raw_frame=image.copy(), processed_frame=image,
timestamp=100, mono_t=1, fps=30, process_ms=1,
session_id=1, frame_id=1, normal_force_raw=12,
shear_x_raw=2, shear_y_raw=-3)
return replace(base, **values)
def test_force_feedback_consumes_every_sample_and_breaks_invalid_gaps(qt_app):
from orisys_autocal.ui.live_force_view import LiveForceView
worker = Worker()
view = LiveForceView(worker)
for item in (packet(), packet(frame_id=2, mono_t=1.1, stale_forces=True),
packet(frame_id=3, mono_t=1.2, normal_force_raw=20)):
worker.sinks[0](item)
view.refresh()
assert view.history.sample_count == 3
x, y = view.curves[0].getData()
np.testing.assert_allclose(x, [0, .1, .2])
assert y[0] == 12 and np.isnan(y[1]) and y[2] == 20
assert "20 raw" in view.readings.text()
assert "20.000 N" not in view.readings.text()
view.on_packet(packet(session_id=2, normal_force=4, force_calibrated=True,
calibrated_axes=("fn",)))
view.refresh()
assert view.history.sample_count == 1
assert "4.000 N" in view.readings.text()
assert "2.000 N" not in view.readings.text()
worker.is_running = False
view.refresh()
assert view.state.text()
view.shutdown()
assert not worker.sinks
def test_display_toggles_redraw_same_frame_without_mutating_measurements(qt_app, monkeypatch):
from orisys_autocal.ui import finger_source_panel
panel = finger_source_panel.FingerSourcePanel()
item = packet(flow=np.full((64, 80, 2), 2., dtype=float),
depth=np.full((64, 80), .5), valid_mask=np.ones((64, 80), bool),
flow_valid=True, flow_frame_id=1, depth_valid=True, depth_frame_id=1)
original = item.processed_frame.copy()
panel._last_packet = item
frames = []
monkeypatch.setattr(panel, "_show_frame", lambda frame: frames.append(frame.copy()))
panel._redraw()
np.testing.assert_array_equal(frames[-1], original)
panel.background_check.setChecked(False)
assert not np.array_equal(frames[-1], original)
solid = frames[-1]
panel.depth_check.setChecked(True)
assert not np.array_equal(frames[-1], solid)
depth = frames[-1]
panel.arrows_check.setChecked(True)
assert not np.array_equal(frames[-1], depth)
assert frames[-1].shape == original.shape
np.testing.assert_array_equal(item.processed_frame, original)
assert np.all(item.flow == 2)
panel._last_packet = replace(item, flow_valid=False, depth_frame_id=0)
panel._redraw()
assert panel.display_note.text()
np.testing.assert_array_equal(frames[-1], solid)
panel.shutdown()
def test_depth_range_adapts_per_frame_and_excludes_invalid_uv_pixels(qt_app, monkeypatch):
from orisys_autocal.ui import finger_source_panel
panel = finger_source_panel.FingerSourcePanel()
panel.background_check.setChecked(False)
panel.depth_check.setChecked(True)
mask = np.zeros((64, 80), dtype=bool)
mask[10:30, 20:40] = True
depth = np.full((64, 80), 1e6)
depth[mask] = np.linspace(2, 4, mask.sum())
depth[10, 20] = np.nan
frames = []
monkeypatch.setattr(panel, "_show_frame", lambda frame: frames.append(frame.copy()))
panel._last_packet = packet(depth=depth, valid_mask=mask,
depth_valid=True, depth_frame_id=1)
panel._redraw()
first = frames[-1]
assert "4" in panel.display_note.text()
panel._last_packet = replace(panel._last_packet, depth=depth * 10 + 5)
panel._redraw()
# A different numerical range spans the same colour ramp in the next frame.
np.testing.assert_array_equal(frames[-1], first)
assert "45" in panel.display_note.text()
panel._last_packet = replace(panel._last_packet, depth=np.full_like(depth, np.nan))
panel._redraw()
assert panel.display_note.text()
assert not np.array_equal(frames[-1], first)
panel.shutdown()