Commit c3b348a7 authored by narugo1992's avatar narugo1992
Browse files

dev(narugo): save the yolo seg inference code

parent 8bdd4b2c
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
from typing import Tuple

import numpy as np

BBoxTyping = Tuple[float, float, float, float]
BBoxWithScoreAndLabel = Tuple[BBoxTyping, str, float]
MaskWithScoreAndLabel = Tuple[BBoxTyping, str, float, np.ndarray]
+32 −8
Original line number Diff line number Diff line
@@ -10,12 +10,14 @@ Overview:
    See :func:`imgutils.detect.head.detect_heads` and :func:`imgutils.detect.person.detect_person` for examples.
"""
import math
from typing import List, Tuple, Optional
from typing import List, Optional, Union

from PIL import ImageFont, ImageDraw
import numpy as np
from PIL import ImageFont, ImageDraw, Image
from hbutils.color import rnd_colors, Color

from imgutils.data import ImageTyping, load_image
from .base import BBoxWithScoreAndLabel, MaskWithScoreAndLabel
from ..data import ImageTyping, load_image


def _try_get_font_from_matplotlib(fp=None, fontsize: int = 12):
@@ -42,9 +44,10 @@ def _try_get_font_from_matplotlib(fp=None, fontsize: int = 12):
        return ImageFont.truetype(font, fontsize)


def detection_visualize(image: ImageTyping, detection: List[Tuple[Tuple[float, float, float, float], str, float]],
def detection_visualize(image: ImageTyping, detection: List[Union[BBoxWithScoreAndLabel, MaskWithScoreAndLabel]],
                        labels: Optional[List[str]] = None, text_padding: int = 6, fontsize: int = 12,
                        max_short_edge_size: Optional[int] = None, fp=None, no_label: bool = False):
                        max_short_edge_size: Optional[int] = None, mask_alpha: float = 0.5,
                        fp=None, no_label: bool = False):
    """
    Visualize object detection results by drawing bounding boxes and labels on an image.

@@ -52,7 +55,7 @@ def detection_visualize(image: ImageTyping, detection: List[Tuple[Tuple[float, f
    :type image: ImageTyping
    :param detection: List of detection results, each containing ((x0, y0, x1, y1), label, confidence_score).
        Coordinates should be in pixels, not normalized.
    :type detection: List[Tuple[Tuple[float, float, float, float], str, float]]
    :type detection: List[Union[Tuple[Tuple[float, float, float, float], str, float], Tuple[Tuple[float, float, float, float], str, float, np.ndarray]]
    :param labels: List of predefined labels. If None, labels will be extracted from detection results.
    :type labels: Optional[List[str]]
    :param text_padding: Padding around label text in pixels.
@@ -95,15 +98,36 @@ def detection_visualize(image: ImageTyping, detection: List[Tuple[Tuple[float, f
    draw = ImageDraw.Draw(visual_image, mode='RGBA')
    font = _try_get_font_from_matplotlib(fp, fontsize) or ImageFont.load_default()

    labels = sorted(labels or {label for _, label, _ in detection})
    labels = sorted(labels or {label for _, label, *_ in detection})
    _colors = list(map(str, rnd_colors(len(labels))))
    _color_map = dict(zip(labels, _colors))
    for _, ((x0, y0, x1, y1), label, score) in sorted(enumerate(detection), key=lambda x: (x[1][2], x[0])):
    for _, detect_item in sorted(enumerate(detection), key=lambda x: (x[1][2], x[0])):
        if len(detect_item) == 3:
            (x0, y0, x1, y1), label, score = detect_item
            mask = None
        else:
            (x0, y0, x1, y1), label, score, mask = detect_item
        x0, y0 = int(x0 * new_width / original_width), int(y0 * new_height / original_height)
        x1, y1 = int(x1 * new_width / original_width), int(y1 * new_height / original_height)
        box_color = _color_map[label]
        draw.rectangle((x0, y0, x1, y1), outline=box_color, width=2)

        if mask is not None:
            if mask.shape[0] != new_height or mask.shape[1] != new_width:
                mask_pil = Image.fromarray((mask * 255).astype(np.uint8))
                mask_pil = mask_pil.resize((new_width, new_height), Image.BILINEAR)
                mask = np.array(mask_pil) / 255.0

            color = Color(box_color)
            overlay = np.zeros((new_height, new_width, 4), dtype=np.uint8)
            overlay[..., 0] = int(color.rgb.red * 255)
            overlay[..., 1] = int(color.rgb.green * 255)
            overlay[..., 2] = int(color.rgb.blue * 255)
            overlay[..., 3] = (mask * mask_alpha * 255).astype(np.uint8)

            overlay_pil = Image.fromarray(overlay)
            visual_image.paste(overlay_pil, (0, 0), overlay_pil)

        if not no_label:
            label_text = f'{label}: {score * 100:.2f}%'
            _t_x0, _t_y0, _t_x1, _t_y1 = draw.textbbox((x0, y0), label_text, font=font)
+1 −0
Original line number Diff line number Diff line
@@ -9,3 +9,4 @@ from .enhance import *
from .multilabel_timm import *
from .siglip import *
from .yolo import *
from .yoloseg import *
+481 −0

File added.

Preview size limit exceeded, changes collapsed.