venture-studio / studio /rigging /overlay.py
AlterProgramming's picture
add txt2img tab + infer_txt2img endpoint (SD 1.5)
7faaef2 verified
Raw
History Blame Contribute Delete
2.4 kB
"""studio.rigging.overlay — numpy + PIL debug overlay renderer.
Composites: source image → mask-edge ring → bones (cyan) → joints (red dots).
Output is a PIL.Image in RGBA, ready to save as PNG.
"""
from __future__ import annotations
import numpy as np
from PIL import Image, ImageDraw
from scipy.ndimage import binary_erosion
from pixel_cursor.rigging import BONES, JOINT_NAMES, Skeleton
JOINT_COLOR = (255, 80, 80, 255)
JOINT_OUTLINE = (0, 0, 0, 255)
BONE_COLOR = (60, 200, 255, 255)
MASK_EDGE_COLOR = (255, 255, 0, 200)
JOINT_RADIUS = 4
BONE_WIDTH = 2
def render_overlay(
image: np.ndarray,
mask: np.ndarray,
skeleton: Skeleton,
*,
show_labels: bool = False,
) -> Image.Image:
if image.ndim == 2:
rgba = np.stack(
[image, image, image, np.full_like(image, 255)],
axis=-1,
)
elif image.shape[-1] == 3:
rgba = np.concatenate(
[image, np.full(image.shape[:2] + (1,), 255, dtype=np.uint8)],
axis=-1,
)
elif image.shape[-1] == 4:
rgba = image.copy()
else:
raise ValueError(f"unsupported image shape {image.shape}")
H, W = rgba.shape[:2]
mask_bool = mask.astype(bool)
edge = mask_bool & ~binary_erosion(mask_bool, iterations=1, border_value=0)
edge_layer_arr = np.zeros((H, W, 4), dtype=np.uint8)
edge_layer_arr[edge] = MASK_EDGE_COLOR
canvas = Image.alpha_composite(
Image.fromarray(rgba, mode="RGBA"),
Image.fromarray(edge_layer_arr, mode="RGBA"),
)
draw = ImageDraw.Draw(canvas)
for parent_idx, child_idx in BONES:
py, px = skeleton.positions[parent_idx]
cy, cx = skeleton.positions[child_idx]
draw.line(
[(float(px), float(py)), (float(cx), float(cy))],
fill=BONE_COLOR,
width=BONE_WIDTH,
)
for i in range(skeleton.positions.shape[0]):
y, x = skeleton.positions[i]
r = JOINT_RADIUS
draw.ellipse(
[(float(x) - r, float(y) - r), (float(x) + r, float(y) + r)],
fill=JOINT_COLOR,
outline=JOINT_OUTLINE,
width=1,
)
if show_labels:
draw.text(
(float(x) + r + 2, float(y) - r),
JOINT_NAMES[i],
fill=(255, 255, 255, 255),
)
return canvas
__all__ = ["render_overlay"]