bevformer-p150 / code /tt_bevformer /tests /test_host_preprocess.py
changh95's picture
tt-model push bevformer-p150 (container)
ddaad99 verified
Raw History Blame Contribute Delete
4.08 kB
# SPDX-License-Identifier: Apache-2.0
"""Host image pre-processing (``host.preprocess``) against the research reference's OpenCV pipeline, the
public-data converter's decoded-image digests and the research golden network input.
TT_VISIBLE_DEVICES=none python -m pytest -q -p fake_ttnn_plugin code/tt_bevformer/tests/test_host_preprocess.py
"""
from __future__ import annotations
import hashlib
import numpy as np
import pytest
from tt_bevformer.host import preprocess as hp
from tt_bevformer.host.inputs import load_frame
from tt_bevformer.reference import config as C
from tt_bevformer.tests import paths
cv2 = pytest.importorskip("cv2")
def _sha(a: np.ndarray) -> str:
return hashlib.sha256(np.ascontiguousarray(a).tobytes()).hexdigest()
@pytest.fixture(scope="module")
def frame30():
paths.need_pandaset()
return load_frame(paths.PANDASET_SAMPLES / "pandaset_019_f30.json")
@pytest.mark.parametrize("frame", paths.SAMPLE_FRAMES)
def test_shipped_images_decode_like_the_converter(frame):
"""OpenCV decode + the node's cv::resize to 1600x900 give exactly the BGR images the public-data converter
hashed (so the stored CPU outputs are bit-for-bit inputs of this host path)."""
paths.need_pandaset()
fr = load_frame(paths.PANDASET_SAMPLES / f"pandaset_019_f{frame}.json")
want = fr.manifest["image_bgr_sha256_1600x900"]
for cam, im in zip(C.CAMERA_ORDER, fr.images_bgr):
assert im.shape == (1080, 1920, 3) and im.dtype == np.uint8
out = hp.node_transport(im)
assert out.shape == (900, 1600, 3)
assert _sha(out) == want[cam], cam
def test_pil_decode_equals_opencv(frame30):
"""The port decodes with PIL (``host.preprocess.decode_bgr``, ``ttaw.io``); the converter and the node use OpenCV
(``cv2.imdecode`` / cv_bridge, BGR): the same pixels on the shipped JPEGs."""
for cam, im in zip(C.CAMERA_ORDER, frame30.images_bgr):
raw = (paths.PANDASET_SAMPLES / frame30.manifest["images"][cam]).read_bytes()
assert np.array_equal(cv2.imdecode(np.frombuffer(raw, np.uint8), cv2.IMREAD_COLOR), im), cam
@pytest.mark.parametrize("hw", [(1080, 1920), (720, 1280), (432, 768), (1200, 1920)])
def test_node_transport(hw):
"""The node's uint8 cv::resize to 1600x900 (the vendored ttaw.image_linear emulation) equals OpenCV."""
rng = np.random.default_rng(hw[0])
im = rng.integers(0, 256, (900, 1600, 3), dtype=np.uint8)
assert hp.node_transport(im) is im # 1600x900 passes through
src = rng.integers(0, 256, hw + (3,), dtype=np.uint8)
assert np.array_equal(hp.node_transport(src), cv2.resize(src, (1600, 900), interpolation=cv2.INTER_LINEAR))
with pytest.raises(ValueError):
hp.node_transport(im.astype(np.float32))
def test_preprocess_matches_research_reference(frame30):
R = paths.import_research()
if R is None:
pytest.skip("research/bevformer not in this workspace")
imgs = [hp.node_transport(im) for im in frame30.images_bgr]
got = hp.preprocess_images(frame30.images_bgr, workers=4)
assert got.shape == (1, 6, 3, 736, 1280) and got.dtype == np.float32
assert np.array_equal(got, R.preprocess_images_bgr(imgs))
out = np.full((1, 6, 3, 736, 1280), 3.0, np.float32)
assert np.array_equal(hp.preprocess_images(frame30.images_bgr, out=out), got)
def test_sample0_golden_input():
"""The research golden ``image`` of the nuScenes key-frame sample0 (internal validation data), bit for bit."""
s0, golden = paths.vendor_sample0(), paths.research_file("golden", "sample0_golden.npz")
if s0 is None or golden is None:
pytest.skip("sample0 or its research golden are not in this workspace")
imgs = [cv2.imread(str(s0 / "imgs" / f"{c}.jpg"), cv2.IMREAD_COLOR) for c in C.CAMERA_ORDER]
with np.load(golden) as z:
want = z["image"]
assert np.array_equal(hp.preprocess_images(imgs, workers=4), want)
def test_preprocess_refuses_bad_inputs(frame30):
with pytest.raises(ValueError):
hp.preprocess_images(frame30.images_bgr[:5])