Files
AnyImage/tests/anyimage/server/test_model_inference.py
nan 938d95db0f Add new functionality for image rectification and depth metadata handling
- Implemented a preview tool for rectifying images with interactive aspect controls in `preview.py`.
- Added tests for depth metadata loading to ensure consistent schema usage in `test_depth_metadata.py`.
- Developed comprehensive tests for cutout calibration processes in `test_cutout_calibration.py`, including stability checks and depth calibration.
- Created tests for frame compositing operations in `test_frame_compositing.py`, ensuring correct handling of depth and transparency.
- Introduced material slot inheritance functionality in `material_slots.py` to manage geometry material assignments.
- Built shared shader nodes for material processing in `shader.py`, including roughness and bump mapping setups.
2026-09-12 19:20:06 +08:00

106 lines
3.9 KiB
Python

import tempfile
import unittest
from pathlib import Path
from types import SimpleNamespace
from unittest.mock import patch
import numpy as np
import pytest
from PIL import Image
from tests.anyimage.server.support import load_server_module, FakeModels
class ModelInferenceTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.moge2_model = load_server_module("models.moge")
cls.upscale_model = load_server_module("models.upscale")
cls.onnx_upscale = load_server_module("models.onnx_upscale")
def test_moge2_infers_one_geometry_frame(self):
prediction = {
"points": np.ones((2, 2, 3), dtype=np.float32),
"depth": np.ones((2, 2), dtype=np.float32),
"normal": np.ones((2, 2, 3), dtype=np.float32),
"mask": np.ones((2, 2), dtype=bool),
"intrinsics": np.eye(3, dtype=np.float32),
}
with patch.object(
self.moge2_model,
"infer_one",
return_value=prediction,
) as infer_one:
frame = self.moge2_model.infer(
FakeModels(),
{"model": "MOGE2_VITS_NORMAL", "device": "cpu"},
Path("input.png"),
include_points=True,
)
self.assertEqual(frame.depth.shape, (2, 2))
infer_one.assert_called_once()
def test_upscale_resource_error_releases_session_and_is_readable(self):
from PIL import Image
class Models:
def __init__(self, directory):
self.model_directory = directory
self.released = False
def directory(self, _model):
return self.model_directory
def get_upscale(self, _directory, _device):
return object()
def release_upscale(self):
self.released = True
with tempfile.TemporaryDirectory() as directory:
path = Path(directory) / "input.png"
Image.new("RGB", (8, 8)).save(path)
models = Models(Path(directory))
with patch.object(
self.onnx_upscale,
"infer",
side_effect=self.onnx_upscale.UpscaleResourceError(
"provider memory exhausted"
),
):
with self.assertRaisesRegex(
RuntimeError,
"Reduce Maximum AI Input Size or select CPU",
):
self.upscale_model.infer_one(
models,
{
"model": "REALESRGAN_GENERAL_WDN_X4V3",
"device": "directml",
"max_input_size": 2048,
},
path,
)
self.assertTrue(models.released)
upscale = load_server_module("models.upscale")
@pytest.mark.parametrize("key", ["REALESRGAN_GENERAL_WDN_X4V3", "HAT_GAN_X4_SHARPER", "REALESRGAN_X4PLUS"])
def test_upscale_models_resize_prediction_then_restore_alpha(tmp_path, key):
rng = np.random.default_rng(1)
source = Image.fromarray(rng.integers(0,256,(5,7,4),dtype=np.uint8))
path = tmp_path / "source.png"
source.save(path)
prediction = Image.fromarray(rng.integers(0,256,(20,28,3),dtype=np.uint8))
manager = SimpleNamespace(directory=lambda _: tmp_path, get_upscale=lambda *args: object())
with patch("server.models.onnx_upscale.infer", return_value=prediction) as infer:
output = upscale.infer_one(manager, {"model":key,"device":"cpu"}, path)
assert infer.call_args.kwargs["tile_border"] == (48 if key == "HAT_GAN_X4_SHARPER" else 16)
np.testing.assert_array_equal(output.convert("RGB"), prediction.resize((14,10), Image.Resampling.LANCZOS))
np.testing.assert_array_equal(output.getchannel("A"), source.getchannel("A").resize((14,10), Image.Resampling.LANCZOS))