Spaces:
Sleeping
Sleeping
| from pathlib import Path | |
| import gradio as gr | |
| import numpy as np | |
| from PIL import Image | |
| from tasks.segmentation.gradio import ( | |
| SegmentationAppBuilder, | |
| SegmentationPageAdapter, | |
| SegmentationTool | |
| ) | |
| from tasks.segmentation.runner import pipeline as task_pipeline | |
| class DummyModel: | |
| def __call__(self, model_input, training=False): | |
| prediction = np.zeros((1, 2, 3, 3), dtype="float32") | |
| prediction[0, :, :, 0] = 0.1 | |
| prediction[0, :, :, 1] = 0.2 | |
| prediction[0, 0, 0, 2] = 0.9 | |
| prediction[0, 1, 2, 1] = 0.8 | |
| return prediction | |
| class DummyArtifact: | |
| def __init__(self): | |
| self.model = DummyModel() | |
| class DummyTool: | |
| def segment(self, image): | |
| return Image.fromarray(np.asarray(image, dtype="uint8")) | |
| class DummyCheckpointLoadRules: | |
| def __init__(self, model_dir: Path): | |
| self.model_dir = model_dir | |
| def resolve_test_rule(self, default_dirs): | |
| return { | |
| "dirs": [self.model_dir], | |
| "suffix": None | |
| } | |
| class DummyModelBuilder: | |
| def load_inference_artifact(self, model_path): | |
| return DummyArtifact() | |
| class DummyPipeline: | |
| def __init__(self, name: str, model_dir: Path): | |
| self.name = name | |
| self.checkpoint_load_rules = DummyCheckpointLoadRules(model_dir) | |
| self.model_builder = DummyModelBuilder() | |
| def create_segmentation_app_builder(tmp_path): | |
| model_dir = tmp_path / "models" / "segmentation_test" | |
| model_dir.mkdir(parents=True) | |
| (model_dir / "model_epoch_001.keras").write_text("stub", encoding="utf-8") | |
| return SegmentationAppBuilder( | |
| pipeline=DummyPipeline("segmentation_test", model_dir), | |
| tool_factory=lambda inference_artifact, resource: DummyTool(), | |
| sample_images=["sample.jpg"], | |
| load_sample_image=lambda sample_name: np.zeros((8, 8, 3), dtype="uint8"), | |
| title="测试分割页面" | |
| ) | |
| def test_segmentation_app_builder_can_create_ui(tmp_path): | |
| """验证分割 Gradio 页面可以创建 Blocks。""" | |
| builder = create_segmentation_app_builder(tmp_path) | |
| demo = builder.create_ui() | |
| assert isinstance(demo, gr.Blocks) | |
| def test_segmentation_app_builder_loads_deployment_model_without_training_data(tmp_path): | |
| """验证分割推理加载只读取部署模型,不读取训练数据目录。""" | |
| builder = create_segmentation_app_builder(tmp_path) | |
| inference_artifact, resource = builder._load_inference_artifact() | |
| assert isinstance(inference_artifact.model, DummyModel) | |
| assert resource is None | |
| def test_segmentation_page_adapter_lists_sample_images(): | |
| """验证分割示例图片列表来自 Oxford Pets 示例图片目录。""" | |
| adapter = SegmentationPageAdapter(task_pipeline) | |
| sample_images = adapter.list_sample_images() | |
| assert len(sample_images) == 10 | |
| assert sample_images[0].endswith(".jpg") | |
| def test_segmentation_page_adapter_loads_rgb_sample_image(): | |
| """验证选择示例图片会读取为 RGB 图片数组。""" | |
| adapter = SegmentationPageAdapter(task_pipeline) | |
| sample_name = adapter.list_sample_images()[0] | |
| image = adapter.load_sample_image(sample_name) | |
| assert image.shape[-1] == 3 | |
| assert image.dtype == np.uint8 | |
| def test_segmentation_tool_converts_prediction_to_gray_mask(): | |
| """验证分割工具会把模型输出按 argmax 乘以 127 转成灰度图片。""" | |
| tool = SegmentationTool(DummyPipeline("unused", Path("unused")), DummyArtifact(), None, (2, 3)) | |
| image = np.zeros((4, 5, 3), dtype="uint8") | |
| result_image = tool.segment(image) | |
| result = np.asarray(result_image) | |
| assert isinstance(result_image, Image.Image) | |
| assert result.shape == (2, 3) | |
| assert result[0, 0] == 254 | |
| assert result[0, 1] == 127 | |
| assert result[1, 2] == 127 | |