Refactor Cutout and Image Editing Logic
- Renamed "Base Plane Depth" to "Reference Depth" across validate_cutout.py for consistency. - Introduced a new specification for Cutout mesh sampling to ensure source pixel spacing is preserved and limits are applied correctly. - Unified naming conventions for image editing results to maintain consistency across Remove Background, Upscale, and Crop operations. - Updated the handling of Refine Selection to ensure it retains the original bounds and does not apply unnecessary cropping. - Enhanced material generation logic to connect image color directly to IOR Level, improving the rendering of dark areas. - Established clear requirements for geometry depth controls and image result materials to ensure consistent behavior across different components. - Removed outdated logic and ensured all changes are documented and tested for regression.
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
"""Generate optional AI files from one rectangular Cutout image input."""
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from ..geometry.prediction_artifacts import generate_moge2_artifacts
|
||||
@@ -15,22 +14,14 @@ def run(context, parameters):
|
||||
result = {}
|
||||
if parameters.get("refine_selection"):
|
||||
context.progress(0.2, "Refining Selection")
|
||||
selection_image_path, bounds = refine_selection(
|
||||
selection_image_path = refine_selection(
|
||||
context,
|
||||
input_path,
|
||||
parameters["refine_model"],
|
||||
parameters["device"],
|
||||
context.directory / "selection.png",
|
||||
)
|
||||
bounds_path = context.directory / "selection_bounds.json"
|
||||
bounds_path.write_text(
|
||||
json.dumps(bounds, separators=(",", ":")),
|
||||
encoding="utf-8",
|
||||
)
|
||||
result.update(
|
||||
selection_image=selection_image_path.name,
|
||||
selection_bounds=bounds_path.name,
|
||||
)
|
||||
result["selection_image"] = selection_image_path.name
|
||||
|
||||
depth_mode = str(parameters.get("depth_mode", "NONE"))
|
||||
normal_mode = str(parameters.get("normal_mode", "NONE"))
|
||||
|
||||
@@ -1,27 +1,24 @@
|
||||
import json
|
||||
import time
|
||||
|
||||
from ..selection import refine_selection
|
||||
|
||||
|
||||
def run(context, parameters):
|
||||
"""Refine a gesture mask with BEN2 and return its source-image bounds."""
|
||||
"""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, bounds = refine_selection(
|
||||
output_path = refine_selection(
|
||||
context,
|
||||
parameters["input"],
|
||||
parameters["model"],
|
||||
parameters["device"],
|
||||
output_directory / "image.png",
|
||||
)
|
||||
bounds_path = output_directory / "bounds.json"
|
||||
bounds_path.write_text(json.dumps(bounds, separators=(",", ":")), encoding="utf-8")
|
||||
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, "selection_bounds": bounds_path.name}
|
||||
return {"selection_image": output_path.name}
|
||||
|
||||
@@ -1,24 +1,6 @@
|
||||
from ..models.ben2 import infer_foreground
|
||||
|
||||
|
||||
def _crop_to_alpha(image):
|
||||
import numpy as np
|
||||
|
||||
pixels = np.asarray(image.convert("RGBA"), dtype=np.uint8)
|
||||
visible = pixels[:, :, 3] > 0
|
||||
visible_y = np.flatnonzero(np.any(visible, axis=1))
|
||||
visible_x = np.flatnonzero(np.any(visible, axis=0))
|
||||
if not len(visible_x):
|
||||
raise ValueError("The generated Selection contains no visible pixels")
|
||||
bounds = (
|
||||
int(visible_x[0]),
|
||||
int(visible_y[0]),
|
||||
int(visible_x[-1]) + 1,
|
||||
int(visible_y[-1]) + 1,
|
||||
)
|
||||
return image.crop(bounds), bounds
|
||||
|
||||
|
||||
def refine_selection(
|
||||
context,
|
||||
input_path,
|
||||
@@ -37,6 +19,5 @@ def refine_selection(
|
||||
preserve_input_alpha=True,
|
||||
)
|
||||
context.check_cancelled()
|
||||
output, bounds = _crop_to_alpha(foreground)
|
||||
output.save(output_path, format="PNG", compress_level=1)
|
||||
return output_path, bounds
|
||||
foreground.convert("RGBA").save(output_path, format="PNG", compress_level=1)
|
||||
return output_path
|
||||
|
||||
Reference in New Issue
Block a user