mirror of
https://github.com/lllyasviel/Fooocus.git
synced 2026-08-16 13:13:16 +02:00
wip: add adetailer
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import cv2
|
||||
from PIL import Image
|
||||
from torchvision.transforms.functional import to_pil_image
|
||||
|
||||
from extras.adetailer.common import PredictOutput, create_mask_from_bbox
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import torch
|
||||
from ultralytics import YOLO, YOLOWorld
|
||||
|
||||
|
||||
def ultralytics_predict(
|
||||
model_path: str | Path,
|
||||
image: Image.Image,
|
||||
confidence: float = 0.3,
|
||||
device: str = "",
|
||||
classes: str = "",
|
||||
) -> PredictOutput[float]:
|
||||
from ultralytics import YOLO
|
||||
|
||||
model = YOLO(model_path)
|
||||
apply_classes(model, model_path, classes)
|
||||
pred = model(image, conf=confidence, device=device)
|
||||
|
||||
bboxes = pred[0].boxes.xyxy.cpu().numpy()
|
||||
if bboxes.size == 0:
|
||||
return PredictOutput()
|
||||
bboxes = bboxes.tolist()
|
||||
|
||||
if pred[0].masks is None:
|
||||
masks = create_mask_from_bbox(bboxes, image.size)
|
||||
else:
|
||||
masks = mask_to_pil(pred[0].masks.data, image.size)
|
||||
preview = pred[0].plot()
|
||||
preview = cv2.cvtColor(preview, cv2.COLOR_BGR2RGB)
|
||||
preview = Image.fromarray(preview)
|
||||
|
||||
return PredictOutput(bboxes=bboxes, masks=masks, preview=preview)
|
||||
|
||||
|
||||
def apply_classes(model: YOLO | YOLOWorld, model_path: str | Path, classes: str):
|
||||
if not classes or "-world" not in Path(model_path).stem:
|
||||
return
|
||||
parsed = [c.strip() for c in classes.split(",") if c.strip()]
|
||||
if parsed:
|
||||
model.set_classes(parsed)
|
||||
|
||||
|
||||
def mask_to_pil(masks: torch.Tensor, shape: tuple[int, int]) -> list[Image.Image]:
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
masks: torch.Tensor, dtype=torch.float32, shape=(N, H, W).
|
||||
The device can be CUDA, but `to_pil_image` takes care of that.
|
||||
|
||||
shape: tuple[int, int]
|
||||
(W, H) of the original image
|
||||
"""
|
||||
n = masks.shape[0]
|
||||
return [to_pil_image(masks[i], mode="L").resize(shape) for i in range(n)]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user