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:
@@ -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)
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
|
||||
@@ -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}
|
||||
@@ -1,5 +0,0 @@
|
||||
"""AI generation for rasterized image Selections."""
|
||||
|
||||
from .refine_selection import refine_selection
|
||||
|
||||
__all__ = ("refine_selection",)
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user