Разработка AI-системы виртуальной расстановки мебели
AI virtual staging и furniture placement позволяют увидеть мебель в реальном интерьере без физической доставки. Применяется в мебельных магазинах, приложениях для дизайна интерьера (аналог IKEA Place), платформах недвижимости.
Архитектура системы
Фото комнаты пользователя
↓ Глубинное картирование (Depth Estimation)
↓ Определение плоскостей (пол, стены) — ARKit/ARCore/ML
↓ Детекция пустых зон
↓ Рендеринг мебели (3D модель → AI texture blending)
↓ Освещение и тени (согласование с комнатой)
↓ Финальный composite
MiDaS для глубинного картирования
from transformers import DPTForDepthEstimation, DPTFeatureExtractor
import torch
import numpy as np
from PIL import Image
class RoomAnalyzer:
def __init__(self):
self.depth_model = DPTForDepthEstimation.from_pretrained("Intel/dpt-large")
self.feature_extractor = DPTFeatureExtractor.from_pretrained("Intel/dpt-large")
def estimate_depth(self, room_image: Image.Image) -> np.ndarray:
inputs = self.feature_extractor(images=room_image, return_tensors="pt")
with torch.no_grad():
outputs = self.depth_model(**inputs)
depth = outputs.predicted_depth.squeeze().numpy()
# Нормализуем до [0, 1]
depth = (depth - depth.min()) / (depth.max() - depth.min())
return depth
def detect_floor_plane(self, room_image: Image.Image, depth_map: np.ndarray) -> dict:
"""Определяем положение пола для размещения мебели"""
h, w = depth_map.shape
# Нижняя треть изображения обычно содержит пол
floor_region = depth_map[int(h * 0.6):, :]
floor_depth_mean = floor_region.mean()
# Гомография для 3D-2D проекции мебели
floor_corners_2d = np.array([
[0, int(h * 0.6)], [w, int(h * 0.6)],
[w, h], [0, h]
], dtype=np.float32)
return {
"floor_y_start": int(h * 0.6),
"floor_depth": float(floor_depth_mean),
"floor_corners": floor_corners_2d
}
AI-генеративное размещение (SD inpainting)
from diffusers import StableDiffusionXLInpaintPipeline
import torch
class FurniturePlacer:
def __init__(self):
self.pipe = StableDiffusionXLInpaintPipeline.from_pretrained(
"diffusers/stable-diffusion-xl-1.0-inpainting-0.1",
torch_dtype=torch.float16
).to("cuda")
def place_furniture_ai(
self,
room_image: bytes,
placement_mask: bytes, # Зона размещения
furniture_description: str,
room_style: str = "modern"
) -> bytes:
room_pil = Image.open(io.BytesIO(room_image)).convert("RGB")
mask_pil = Image.open(io.BytesIO(placement_mask)).convert("L")
prompt = (
f"{furniture_description}, {room_style} interior design, "
"photorealistic, matching room lighting, professional interior photography"
)
result = self.pipe(
prompt=prompt,
negative_prompt="floating, unrealistic scale, wrong perspective, cartoon",
image=room_pil,
mask_image=mask_pil,
strength=0.95,
guidance_scale=9.0,
num_inference_steps=40
).images[0]
buf = io.BytesIO()
result.save(buf, format="PNG")
return buf.getvalue()
3D рендеринг через Three.js (для AR в браузере)
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
import { ARButton } from 'three/examples/jsm/webxr/ARButton';
class FurnitureARApp {
constructor() {
this.scene = new THREE.Scene();
this.camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 20);
this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
this.renderer.xr.enabled = true;
this.loader = new GLTFLoader();
}
async loadFurnitureModel(modelUrl) {
return new Promise((resolve) => {
this.loader.load(modelUrl, (gltf) => resolve(gltf.scene));
});
}
setupHitTesting() {
// WebXR Hit Testing для позиционирования на плоскости пола
this.renderer.xr.addEventListener('sessionstart', async (event) => {
const session = event.target.getSession();
this.hitTestSource = await session.requestHitTestSource({
space: await session.requestReferenceSpace('viewer')
});
});
}
onSelect(furniture) {
// Размещаем мебель на поверхности по клику
if (this.hitTestSource) {
const clone = furniture.clone();
this.scene.add(clone);
}
}
}
Virtual Staging для недвижимости
class VirtualStagingService:
"""Расстановка мебели в пустых комнатах для листингов недвижимости"""
ROOM_STYLES = {
"modern": "contemporary furniture, clean lines, neutral colors",
"scandinavian": "minimalist, natural wood, white and gray palette",
"classic": "traditional furniture, warm tones, decorative elements",
"industrial": "metal accents, exposed brick, dark tones",
}
async def stage_empty_room(
self,
empty_room_photo: bytes,
room_type: str, # "living_room", "bedroom", "dining_room"
style: str = "modern"
) -> bytes:
style_desc = self.ROOM_STYLES[style]
room_furniture = {
"living_room": "sofa, coffee table, armchair, TV unit, decorative items",
"bedroom": "king bed, nightstands, wardrobe, floor lamp",
"dining_room": "dining table, chairs, sideboard, pendant light"
}
mask = self.create_full_room_mask(empty_room_photo)
return self.placer.place_furniture_ai(
empty_room_photo,
mask,
furniture_description=f"{room_furniture[room_type]}, {style_desc}",
room_style=style
)
Сроки: AI-генеративный virtual staging (SD inpainting) — 2–3 недели. Браузерное AR-приложение с WebXR hit testing для размещения 3D мебели — 6–8 недель. Полноценное мобильное приложение с каталогом мебели — 3–4 месяца.







