feat(selection): separate selection geometry from image content processing
- Introduced a new design for selection rasterization that decouples the selection geometry from the image content, ensuring that the SelectionMask is independent of the source image's alpha and color. - Updated the `rasterize_selection_path` function to only accept selection paths and image dimensions, removing parameters related to source alpha and alpha thresholds. - Implemented a new approach for handling selection paths using non-zero winding fill, ensuring overlapping areas are preserved. - Enhanced performance by utilizing a scanline algorithm for rasterization, significantly reducing processing time for high-resolution images. - Updated internal documentation and added comprehensive tests to validate the new behavior and performance improvements. - Ensured backward compatibility by maintaining existing interfaces where necessary while introducing breaking changes in the selection processing logic.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
"""Generate optional AI files for one Blender-rasterized Cutout Selection."""
|
||||
"""Generate optional AI files from one rectangular Cutout image input."""
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
@@ -16,6 +16,7 @@ def run(context, parameters):
|
||||
parameters,
|
||||
images[0],
|
||||
depth_mode="Z",
|
||||
normal_mode="TANGENT",
|
||||
)
|
||||
context.check_cancelled()
|
||||
context.progress(1.0, "Depth Plane data is ready")
|
||||
|
||||
@@ -5,14 +5,16 @@ def _crop_to_alpha(image):
|
||||
import numpy as np
|
||||
|
||||
pixels = np.asarray(image.convert("RGBA"), dtype=np.uint8)
|
||||
visible_y, visible_x = np.nonzero(pixels[:, :, 3] > 0)
|
||||
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.min()),
|
||||
int(visible_y.min()),
|
||||
int(visible_x.max()) + 1,
|
||||
int(visible_y.max()) + 1,
|
||||
int(visible_x[0]),
|
||||
int(visible_y[0]),
|
||||
int(visible_x[-1]) + 1,
|
||||
int(visible_y[-1]) + 1,
|
||||
)
|
||||
return image.crop(bounds), bounds
|
||||
|
||||
@@ -24,7 +26,7 @@ def refine_selection(
|
||||
device,
|
||||
output_path,
|
||||
):
|
||||
"""Refine an image Selection from an already rasterized Selection."""
|
||||
"""Refine foreground Alpha within one rectangular Selection context."""
|
||||
model_manager = context.resource("model_manager")
|
||||
foreground, _load_ms, _inference_ms = infer_foreground(
|
||||
input_path,
|
||||
|
||||
Reference in New Issue
Block a user