Add comprehensive tests for image processing and mask functionalities

- Introduced tests for color image handling, ensuring source preservation and premultiplied alpha usage.
- Implemented tests for brush stroke operations, validating segment boundaries and brush anti-aliasing.
- Added tests for frame anti-aliasing, confirming correct rendering behavior with various alpha values and depth settings.
- Created tests for frame projection, ensuring accurate overlap calculations and half-plane clipping.
- Developed tests for image premultiplied retention, verifying behavior during loading and packing processes.
- Added undo functionality tests for mask operations, ensuring single transaction behavior during edits.
This commit is contained in:
2026-09-05 21:33:11 +08:00
parent bbaa4bff46
commit 1994d38ccd
111 changed files with 7691 additions and 2341 deletions

View File

@@ -16,7 +16,6 @@ from .jobs.debug_predictions import (
)
from .jobs.cutout import run as _generate_cutout_artifacts
from .jobs.depth_plane import run as _generate_depth_plane_geometry
from .jobs.refine_image_selection import run as _refine_image_selection
from .jobs.remove_background import run as _remove_background
from .jobs.upscale import run as _upscale_image
from .model_manager import ModelManager
@@ -41,11 +40,6 @@ def download_required_models(context, parameters):
return manager.download_missing(context, parameters["models"])
@server.job("refine-image-selection")
def refine_image_selection(context, parameters):
return _refine_image_selection(context, parameters)
@server.job("remove-background")
def remove_background(context, parameters):
return _remove_background(context, parameters)

View File

@@ -40,15 +40,9 @@ def write_camera_normal_texture(
if visibility.shape != normal.shape[:2]:
visibility = resized_visibility(visibility, normal.shape[:2])
normal_mode = str(normal_mode).upper()
if normal_mode == "TANGENT":
if normal_mode in {"TANGENT", "OBJECT"}:
converted = normal * np.asarray((1.0, -1.0, -1.0), dtype=np.float32)
empty_normal = (128, 128, 255)
elif normal_mode == "OBJECT":
converted = normal[..., (2, 0, 1)] * np.asarray(
(1.0, -1.0, -1.0),
dtype=np.float32,
)
empty_normal = (0, 128, 128)
else:
raise ValueError(f"Unsupported normal mode: {normal_mode}")
encoded = np.clip(

View File

@@ -3,33 +3,20 @@
from pathlib import Path
from ..geometry.prediction_artifacts import generate_moge2_artifacts
from ..selection import refine_selection
def run(context, parameters):
context.progress(0.05, "Preparing Cutout Selection")
context.directory.mkdir(parents=True, exist_ok=True)
input_path = Path(parameters["input"])
selection_image_path = input_path
result = {}
if parameters.get("refine_selection"):
context.progress(0.2, "Refining Selection")
selection_image_path = refine_selection(
context,
input_path,
parameters["refine_model"],
parameters["device"],
context.directory / "selection.png",
)
result["selection_image"] = selection_image_path.name
depth_mode = str(parameters.get("depth_mode", "NONE"))
normal_mode = str(parameters.get("normal_mode", "NONE"))
if depth_mode != "NONE" or normal_mode != "NONE":
artifacts = generate_moge2_artifacts(
context,
parameters,
selection_image_path,
input_path,
depth_mode=depth_mode,
normal_mode=normal_mode,
)

View File

@@ -1,24 +0,0 @@
import time
from ..selection import refine_selection
def run(context, parameters):
"""Refine foreground Alpha while preserving the submitted bounds canvas."""
started = time.perf_counter()
context.progress(0.05, "Preparing image Selection")
context.check_cancelled()
output_directory = context.directory
output_directory.mkdir(parents=True, exist_ok=True)
context.progress(0.2, f"Loading BEN2 for {parameters['device'].upper()}")
output_path = refine_selection(
context,
parameters["input"],
parameters["model"],
parameters["device"],
output_directory / "image.png",
)
elapsed_ms = (time.perf_counter() - started) * 1000.0
message = f"Image Selection refined in {elapsed_ms:.0f} ms"
context.progress(1.0, message)
return {"selection_image": output_path.name}

View File

@@ -1,5 +0,0 @@
"""AI generation for rasterized image Selections."""
from .refine_selection import refine_selection
__all__ = ("refine_selection",)

View File

@@ -1,23 +0,0 @@
from ..models.ben2 import infer_foreground
def refine_selection(
context,
input_path,
model,
device,
output_path,
):
"""Refine foreground Alpha within one rectangular Selection context."""
model_manager = context.resource("model_manager")
foreground, _load_ms, _inference_ms = infer_foreground(
input_path,
model_manager.directory(model),
device,
model_cache=model_manager,
cancel_check=context.check_cancelled,
preserve_input_alpha=True,
)
context.check_cancelled()
foreground.convert("RGBA").save(output_path, format="PNG", compress_level=1)
return output_path