Johnntirs's picture
Room Visualizer backend (Docker)
0cdb4e8
Raw
History Blame Contribute Delete
1.34 kB
"""Inpaint mask construction from a floor footprint + item height (stage 5).
The mask is the silhouette of the item's 3D bounding box: the floor footprint
quad plus the same quad raised by the item's pixel height. The image-conditioned
inpaint then paints the reference furniture into exactly this region.
"""
from __future__ import annotations
from PIL import Image, ImageDraw, ImageFilter
from shapely.geometry import Polygon
def build_mask(
image_size: tuple[int, int],
footprint_quad: list[list[float]],
height_px: float,
feather: int = 6,
) -> tuple[Image.Image, tuple[int, int, int, int]]:
"""Return (mask, bbox). ``mask`` is an 'L' image, 255 = region to inpaint."""
w, h = image_size
pts = [(float(x), float(y)) for x, y in footprint_quad]
raised = [(x, y - height_px) for x, y in pts]
hull = Polygon(pts + raised).convex_hull
coords = [(float(x), float(y)) for x, y in hull.exterior.coords]
mask = Image.new("L", (w, h), 0)
ImageDraw.Draw(mask).polygon(coords, fill=255)
if feather > 0:
mask = mask.filter(ImageFilter.GaussianBlur(feather))
xs = [c[0] for c in coords]
ys = [c[1] for c in coords]
bbox = (
max(0, int(min(xs))),
max(0, int(min(ys))),
min(w, int(max(xs))),
min(h, int(max(ys))),
)
return mask, bbox