跳至内容

参考资料 ultralytics/engine/results.py

备注

该文件可在https://github.com/ultralytics/ultralytics/blob/main/ ultralytics/engine/results .py。如果您发现问题,请通过提交 Pull Request🛠️ 帮助修复。谢谢🙏!



ultralytics.engine.results.BaseTensor

垒球 SimpleClass

tensor 基类,带有便于操作和设备处理的附加方法。

源代码 ultralytics/engine/results.py
class BaseTensor(SimpleClass):
    """Base tensor class with additional methods for easy manipulation and device handling."""

    def __init__(self, data, orig_shape) -> None:
        """
        Initialize BaseTensor with data and original shape.

        Args:
            data (torch.Tensor | np.ndarray): Predictions, such as bboxes, masks and keypoints.
            orig_shape (tuple): Original shape of image.
        """
        assert isinstance(data, (torch.Tensor, np.ndarray))
        self.data = data
        self.orig_shape = orig_shape

    @property
    def shape(self):
        """Return the shape of the data tensor."""
        return self.data.shape

    def cpu(self):
        """Return a copy of the tensor on CPU memory."""
        return self if isinstance(self.data, np.ndarray) else self.__class__(self.data.cpu(), self.orig_shape)

    def numpy(self):
        """Return a copy of the tensor as a numpy array."""
        return self if isinstance(self.data, np.ndarray) else self.__class__(self.data.numpy(), self.orig_shape)

    def cuda(self):
        """Return a copy of the tensor on GPU memory."""
        return self.__class__(torch.as_tensor(self.data).cuda(), self.orig_shape)

    def to(self, *args, **kwargs):
        """Return a copy of the tensor with the specified device and dtype."""
        return self.__class__(torch.as_tensor(self.data).to(*args, **kwargs), self.orig_shape)

    def __len__(self):  # override len(results)
        """Return the length of the data tensor."""
        return len(self.data)

    def __getitem__(self, idx):
        """Return a BaseTensor with the specified index of the data tensor."""
        return self.__class__(self.data[idx], self.orig_shape)

shape property

返回数据的形状tensor 。

__getitem__(idx)

返回具有指定数据索引的 BaseTensortensor 。

源代码 ultralytics/engine/results.py
def __getitem__(self, idx):
    """Return a BaseTensor with the specified index of the data tensor."""
    return self.__class__(self.data[idx], self.orig_shape)

__init__(data, orig_shape)

使用数据和原始形状初始化 BaseTensor。

参数

名称 类型 说明 默认值
data Tensor | ndarray

预测,如 bboxes、掩码和关键点。

所需
orig_shape tuple

图像的原始形状。

所需
源代码 ultralytics/engine/results.py
def __init__(self, data, orig_shape) -> None:
    """
    Initialize BaseTensor with data and original shape.

    Args:
        data (torch.Tensor | np.ndarray): Predictions, such as bboxes, masks and keypoints.
        orig_shape (tuple): Original shape of image.
    """
    assert isinstance(data, (torch.Tensor, np.ndarray))
    self.data = data
    self.orig_shape = orig_shape

__len__()

返回数据的长度tensor 。

源代码 ultralytics/engine/results.py
def __len__(self):  # override len(results)
    """Return the length of the data tensor."""
    return len(self.data)

cpu()

返回 CPU 内存中tensor 的副本。

源代码 ultralytics/engine/results.py
def cpu(self):
    """Return a copy of the tensor on CPU memory."""
    return self if isinstance(self.data, np.ndarray) else self.__class__(self.data.cpu(), self.orig_shape)

cuda()

返回 GPU 内存中tensor 的副本。

源代码 ultralytics/engine/results.py
def cuda(self):
    """Return a copy of the tensor on GPU memory."""
    return self.__class__(torch.as_tensor(self.data).cuda(), self.orig_shape)

numpy()

以 numpy 数组形式返回tensor 的副本。

源代码 ultralytics/engine/results.py
def numpy(self):
    """Return a copy of the tensor as a numpy array."""
    return self if isinstance(self.data, np.ndarray) else self.__class__(self.data.numpy(), self.orig_shape)

to(*args, **kwargs)

使用指定的设备和 dtype 返回tensor 的副本。

源代码 ultralytics/engine/results.py
def to(self, *args, **kwargs):
    """Return a copy of the tensor with the specified device and dtype."""
    return self.__class__(torch.as_tensor(self.data).to(*args, **kwargs), self.orig_shape)



ultralytics.engine.results.Results

垒球 SimpleClass

用于存储和处理推理结果的类。

属性

名称 类型 说明
orig_img ndarray

原始图像的 numpy 数组。

orig_shape tuple

原始图像的形状,格式为(高、宽)。

boxes Boxes

包含检测边界框的对象。

masks Masks

包含检测掩码的对象。

probs Probs

包含分类任务中类别概率的对象。

keypoints Keypoints

包含每个对象的检测关键点的对象。

speed dict

预处理、推理和后处理速度词典(毫秒/图像)。

names dict

类名词典

path str

图像文件的路径。

方法

名称 说明
update

根据新的检测结果更新对象属性。

cpu

返回包含 CPU 内存中所有张量的 Results 对象副本。

numpy

返回结果对象的副本,其中所有张量均为 numpy 数组。

cuda

返回包含 GPU 内存中所有张量的 Results 对象副本。

to

返回带有指定设备和 dtype 上张量的 Results 对象副本。

new

返回一个具有相同图像、路径和名称的新结果对象。

plot

将检测结果绘制在输入图像上,并返回注释图像。

show

在屏幕上显示带注释的结果。

save

将注释结果保存到文件中。

verbose

返回每个任务的日志字符串,详细说明检测和分类情况。

save_txt

将检测结果保存到文本文件中。

save_crop

保存裁剪后的检测图像。

tojson

将检测结果转换为 JSON 格式。

源代码 ultralytics/engine/results.py
class Results(SimpleClass):
    """
    A class for storing and manipulating inference results.

    Attributes:
        orig_img (numpy.ndarray): Original image as a numpy array.
        orig_shape (tuple): Original image shape in (height, width) format.
        boxes (Boxes, optional): Object containing detection bounding boxes.
        masks (Masks, optional): Object containing detection masks.
        probs (Probs, optional): Object containing class probabilities for classification tasks.
        keypoints (Keypoints, optional): Object containing detected keypoints for each object.
        speed (dict): Dictionary of preprocess, inference, and postprocess speeds (ms/image).
        names (dict): Dictionary of class names.
        path (str): Path to the image file.

    Methods:
        update(boxes=None, masks=None, probs=None, obb=None): Updates object attributes with new detection results.
        cpu(): Returns a copy of the Results object with all tensors on CPU memory.
        numpy(): Returns a copy of the Results object with all tensors as numpy arrays.
        cuda(): Returns a copy of the Results object with all tensors on GPU memory.
        to(*args, **kwargs): Returns a copy of the Results object with tensors on a specified device and dtype.
        new(): Returns a new Results object with the same image, path, and names.
        plot(...): Plots detection results on an input image, returning an annotated image.
        show(): Show annotated results to screen.
        save(filename): Save annotated results to file.
        verbose(): Returns a log string for each task, detailing detections and classifications.
        save_txt(txt_file, save_conf=False): Saves detection results to a text file.
        save_crop(save_dir, file_name=Path("im.jpg")): Saves cropped detection images.
        tojson(normalize=False): Converts detection results to JSON format.
    """

    def __init__(self, orig_img, path, names, boxes=None, masks=None, probs=None, keypoints=None, obb=None) -> None:
        """
        Initialize the Results class.

        Args:
            orig_img (numpy.ndarray): The original image as a numpy array.
            path (str): The path to the image file.
            names (dict): A dictionary of class names.
            boxes (torch.tensor, optional): A 2D tensor of bounding box coordinates for each detection.
            masks (torch.tensor, optional): A 3D tensor of detection masks, where each mask is a binary image.
            probs (torch.tensor, optional): A 1D tensor of probabilities of each class for classification task.
            keypoints (torch.tensor, optional): A 2D tensor of keypoint coordinates for each detection.
            obb (torch.tensor, optional): A 2D tensor of oriented bounding box coordinates for each detection.
        """
        self.orig_img = orig_img
        self.orig_shape = orig_img.shape[:2]
        self.boxes = Boxes(boxes, self.orig_shape) if boxes is not None else None  # native size boxes
        self.masks = Masks(masks, self.orig_shape) if masks is not None else None  # native size or imgsz masks
        self.probs = Probs(probs) if probs is not None else None
        self.keypoints = Keypoints(keypoints, self.orig_shape) if keypoints is not None else None
        self.obb = OBB(obb, self.orig_shape) if obb is not None else None
        self.speed = {"preprocess": None, "inference": None, "postprocess": None}  # milliseconds per image
        self.names = names
        self.path = path
        self.save_dir = None
        self._keys = "boxes", "masks", "probs", "keypoints", "obb"

    def __getitem__(self, idx):
        """Return a Results object for the specified index."""
        return self._apply("__getitem__", idx)

    def __len__(self):
        """Return the number of detections in the Results object."""
        for k in self._keys:
            v = getattr(self, k)
            if v is not None:
                return len(v)

    def update(self, boxes=None, masks=None, probs=None, obb=None):
        """Update the boxes, masks, and probs attributes of the Results object."""
        if boxes is not None:
            self.boxes = Boxes(ops.clip_boxes(boxes, self.orig_shape), self.orig_shape)
        if masks is not None:
            self.masks = Masks(masks, self.orig_shape)
        if probs is not None:
            self.probs = probs
        if obb is not None:
            self.obb = OBB(obb, self.orig_shape)

    def _apply(self, fn, *args, **kwargs):
        """
        Applies a function to all non-empty attributes and returns a new Results object with modified attributes. This
        function is internally called by methods like .to(), .cuda(), .cpu(), etc.

        Args:
            fn (str): The name of the function to apply.
            *args: Variable length argument list to pass to the function.
            **kwargs: Arbitrary keyword arguments to pass to the function.

        Returns:
            Results: A new Results object with attributes modified by the applied function.
        """
        r = self.new()
        for k in self._keys:
            v = getattr(self, k)
            if v is not None:
                setattr(r, k, getattr(v, fn)(*args, **kwargs))
        return r

    def cpu(self):
        """Return a copy of the Results object with all tensors on CPU memory."""
        return self._apply("cpu")

    def numpy(self):
        """Return a copy of the Results object with all tensors as numpy arrays."""
        return self._apply("numpy")

    def cuda(self):
        """Return a copy of the Results object with all tensors on GPU memory."""
        return self._apply("cuda")

    def to(self, *args, **kwargs):
        """Return a copy of the Results object with tensors on the specified device and dtype."""
        return self._apply("to", *args, **kwargs)

    def new(self):
        """Return a new Results object with the same image, path, and names."""
        return Results(orig_img=self.orig_img, path=self.path, names=self.names)

    def plot(
        self,
        conf=True,
        line_width=None,
        font_size=None,
        font="Arial.ttf",
        pil=False,
        img=None,
        im_gpu=None,
        kpt_radius=5,
        kpt_line=True,
        labels=True,
        boxes=True,
        masks=True,
        probs=True,
        show=False,
        save=False,
        filename=None,
    ):
        """
        Plots the detection results on an input RGB image. Accepts a numpy array (cv2) or a PIL Image.

        Args:
            conf (bool): Whether to plot the detection confidence score.
            line_width (float, optional): The line width of the bounding boxes. If None, it is scaled to the image size.
            font_size (float, optional): The font size of the text. If None, it is scaled to the image size.
            font (str): The font to use for the text.
            pil (bool): Whether to return the image as a PIL Image.
            img (numpy.ndarray): Plot to another image. if not, plot to original image.
            im_gpu (torch.Tensor): Normalized image in gpu with shape (1, 3, 640, 640), for faster mask plotting.
            kpt_radius (int, optional): Radius of the drawn keypoints. Default is 5.
            kpt_line (bool): Whether to draw lines connecting keypoints.
            labels (bool): Whether to plot the label of bounding boxes.
            boxes (bool): Whether to plot the bounding boxes.
            masks (bool): Whether to plot the masks.
            probs (bool): Whether to plot classification probability
            show (bool): Whether to display the annotated image directly.
            save (bool): Whether to save the annotated image to `filename`.
            filename (str): Filename to save image to if save is True.

        Returns:
            (numpy.ndarray): A numpy array of the annotated image.

        Example:
            ```python
            from PIL import Image
            from ultralytics import YOLO

            model = YOLO('yolov8n.pt')
            results = model('bus.jpg')  # results list
            for r in results:
                im_array = r.plot()  # plot a BGR numpy array of predictions
                im = Image.fromarray(im_array[..., ::-1])  # RGB PIL image
                im.show()  # show image
                im.save('results.jpg')  # save image
            ```
        """
        if img is None and isinstance(self.orig_img, torch.Tensor):
            img = (self.orig_img[0].detach().permute(1, 2, 0).contiguous() * 255).to(torch.uint8).cpu().numpy()

        names = self.names
        is_obb = self.obb is not None
        pred_boxes, show_boxes = self.obb if is_obb else self.boxes, boxes
        pred_masks, show_masks = self.masks, masks
        pred_probs, show_probs = self.probs, probs
        annotator = Annotator(
            deepcopy(self.orig_img if img is None else img),
            line_width,
            font_size,
            font,
            pil or (pred_probs is not None and show_probs),  # Classify tasks default to pil=True
            example=names,
        )

        # Plot Segment results
        if pred_masks and show_masks:
            if im_gpu is None:
                img = LetterBox(pred_masks.shape[1:])(image=annotator.result())
                im_gpu = (
                    torch.as_tensor(img, dtype=torch.float16, device=pred_masks.data.device)
                    .permute(2, 0, 1)
                    .flip(0)
                    .contiguous()
                    / 255
                )
            idx = pred_boxes.cls if pred_boxes else range(len(pred_masks))
            annotator.masks(pred_masks.data, colors=[colors(x, True) for x in idx], im_gpu=im_gpu)

        # Plot Detect results
        if pred_boxes is not None and show_boxes:
            for d in reversed(pred_boxes):
                c, conf, id = int(d.cls), float(d.conf) if conf else None, None if d.id is None else int(d.id.item())
                name = ("" if id is None else f"id:{id} ") + names[c]
                label = (f"{name} {conf:.2f}" if conf else name) if labels else None
                box = d.xyxyxyxy.reshape(-1, 4, 2).squeeze() if is_obb else d.xyxy.squeeze()
                annotator.box_label(box, label, color=colors(c, True), rotated=is_obb)

        # Plot Classify results
        if pred_probs is not None and show_probs:
            text = ",\n".join(f"{names[j] if names else j} {pred_probs.data[j]:.2f}" for j in pred_probs.top5)
            x = round(self.orig_shape[0] * 0.03)
            annotator.text([x, x], text, txt_color=(255, 255, 255))  # TODO: allow setting colors

        # Plot Pose results
        if self.keypoints is not None:
            for k in reversed(self.keypoints.data):
                annotator.kpts(k, self.orig_shape, radius=kpt_radius, kpt_line=kpt_line)

        # Show results
        if show:
            annotator.show(self.path)

        # Save results
        if save:
            annotator.save(filename)

        return annotator.result()

    def show(self, *args, **kwargs):
        """Show annotated results image."""
        self.plot(show=True, *args, **kwargs)

    def save(self, filename=None, *args, **kwargs):
        """Save annotated results image."""
        if not filename:
            filename = f"results_{Path(self.path).name}"
        self.plot(save=True, filename=filename, *args, **kwargs)
        return filename

    def verbose(self):
        """Return log string for each task."""
        log_string = ""
        probs = self.probs
        boxes = self.boxes
        if len(self) == 0:
            return log_string if probs is not None else f"{log_string}(no detections), "
        if probs is not None:
            log_string += f"{', '.join(f'{self.names[j]} {probs.data[j]:.2f}' for j in probs.top5)}, "
        if boxes:
            for c in boxes.cls.unique():
                n = (boxes.cls == c).sum()  # detections per class
                log_string += f"{n} {self.names[int(c)]}{'s' * (n > 1)}, "
        return log_string

    def save_txt(self, txt_file, save_conf=False):
        """
        Save predictions into txt file.

        Args:
            txt_file (str): txt file path.
            save_conf (bool): save confidence score or not.
        """
        is_obb = self.obb is not None
        boxes = self.obb if is_obb else self.boxes
        masks = self.masks
        probs = self.probs
        kpts = self.keypoints
        texts = []
        if probs is not None:
            # Classify
            [texts.append(f"{probs.data[j]:.2f} {self.names[j]}") for j in probs.top5]
        elif boxes:
            # Detect/segment/pose
            for j, d in enumerate(boxes):
                c, conf, id = int(d.cls), float(d.conf), None if d.id is None else int(d.id.item())
                line = (c, *(d.xyxyxyxyn.view(-1) if is_obb else d.xywhn.view(-1)))
                if masks:
                    seg = masks[j].xyn[0].copy().reshape(-1)  # reversed mask.xyn, (n,2) to (n*2)
                    line = (c, *seg)
                if kpts is not None:
                    kpt = torch.cat((kpts[j].xyn, kpts[j].conf[..., None]), 2) if kpts[j].has_visible else kpts[j].xyn
                    line += (*kpt.reshape(-1).tolist(),)
                line += (conf,) * save_conf + (() if id is None else (id,))
                texts.append(("%g " * len(line)).rstrip() % line)

        if texts:
            Path(txt_file).parent.mkdir(parents=True, exist_ok=True)  # make directory
            with open(txt_file, "a") as f:
                f.writelines(text + "\n" for text in texts)

    def save_crop(self, save_dir, file_name=Path("im.jpg")):
        """
        Save cropped predictions to `save_dir/cls/file_name.jpg`.

        Args:
            save_dir (str | pathlib.Path): Save path.
            file_name (str | pathlib.Path): File name.
        """
        if self.probs is not None:
            LOGGER.warning("WARNING ⚠️ Classify task do not support `save_crop`.")
            return
        if self.obb is not None:
            LOGGER.warning("WARNING ⚠️ OBB task do not support `save_crop`.")
            return
        for d in self.boxes:
            save_one_box(
                d.xyxy,
                self.orig_img.copy(),
                file=Path(save_dir) / self.names[int(d.cls)] / f"{Path(file_name)}.jpg",
                BGR=True,
            )

    def summary(self, normalize=False, decimals=5):
        """Convert the results to a summarized format."""
        # Create list of detection dictionaries
        results = []
        if self.probs is not None:
            class_id = self.probs.top1
            results.append(
                {
                    "name": self.names[class_id],
                    "class": class_id,
                    "confidence": round(self.probs.top1conf.item(), decimals),
                }
            )
            return results

        data = self.boxes or self.obb
        is_obb = self.obb is not None
        h, w = self.orig_shape if normalize else (1, 1)
        for i, row in enumerate(data):  # xyxy, track_id if tracking, conf, class_id
            class_id, conf = int(row.cls), round(row.conf.item(), decimals)
            box = (row.xyxyxyxy if is_obb else row.xyxy).squeeze().reshape(-1, 2).tolist()
            xy = {}
            for j, b in enumerate(box):
                xy[f"x{j + 1}"] = round(b[0] / w, decimals)
                xy[f"y{j + 1}"] = round(b[1] / h, decimals)
            result = {"name": self.names[class_id], "class": class_id, "confidence": conf, "box": xy}
            if data.is_track:
                result["track_id"] = int(row.id.item())  # track ID
            if self.masks:
                result["segments"] = {
                    "x": (self.masks.xy[i][:, 0] / w).round(decimals).tolist(),
                    "y": (self.masks.xy[i][:, 1] / h).round(decimals).tolist(),
                }
            if self.keypoints is not None:
                x, y, visible = self.keypoints[i].data[0].cpu().unbind(dim=1)  # torch Tensor
                result["keypoints"] = {
                    "x": (x / w).numpy().round(decimals).tolist(),  # decimals named argument required
                    "y": (y / h).numpy().round(decimals).tolist(),
                    "visible": visible.numpy().round(decimals).tolist(),
                }
            results.append(result)

        return results

    def tojson(self, normalize=False, decimals=5):
        """Convert the results to JSON format."""
        import json

        return json.dumps(self.summary(normalize=normalize, decimals=decimals), indent=2)

__getitem__(idx)

返回指定索引的结果对象。

源代码 ultralytics/engine/results.py
def __getitem__(self, idx):
    """Return a Results object for the specified index."""
    return self._apply("__getitem__", idx)

__init__(orig_img, path, names, boxes=None, masks=None, probs=None, keypoints=None, obb=None)

初始化结果类。

参数

名称 类型 说明 默认值
orig_img ndarray

原始图像的 numpy 数组。

所需
path str

图像文件的路径。

所需
names dict

类名字典。

所需
boxes tensor

每个检测的边界框坐标的二维tensor 。

None
masks tensor

检测掩码的 3Dtensor ,其中每个掩码都是二值图像。

None
probs tensor

分类任务中每个类别概率的一维tensor 。

None
keypoints tensor

每个检测点关键点坐标的二维tensor 。

None
obb tensor

每个检测的定向边界框坐标的二维tensor 。

None
源代码 ultralytics/engine/results.py
def __init__(self, orig_img, path, names, boxes=None, masks=None, probs=None, keypoints=None, obb=None) -> None:
    """
    Initialize the Results class.

    Args:
        orig_img (numpy.ndarray): The original image as a numpy array.
        path (str): The path to the image file.
        names (dict): A dictionary of class names.
        boxes (torch.tensor, optional): A 2D tensor of bounding box coordinates for each detection.
        masks (torch.tensor, optional): A 3D tensor of detection masks, where each mask is a binary image.
        probs (torch.tensor, optional): A 1D tensor of probabilities of each class for classification task.
        keypoints (torch.tensor, optional): A 2D tensor of keypoint coordinates for each detection.
        obb (torch.tensor, optional): A 2D tensor of oriented bounding box coordinates for each detection.
    """
    self.orig_img = orig_img
    self.orig_shape = orig_img.shape[:2]
    self.boxes = Boxes(boxes, self.orig_shape) if boxes is not None else None  # native size boxes
    self.masks = Masks(masks, self.orig_shape) if masks is not None else None  # native size or imgsz masks
    self.probs = Probs(probs) if probs is not None else None
    self.keypoints = Keypoints(keypoints, self.orig_shape) if keypoints is not None else None
    self.obb = OBB(obb, self.orig_shape) if obb is not None else None
    self.speed = {"preprocess": None, "inference": None, "postprocess": None}  # milliseconds per image
    self.names = names
    self.path = path
    self.save_dir = None
    self._keys = "boxes", "masks", "probs", "keypoints", "obb"

__len__()

返回结果对象中的检测次数。

源代码 ultralytics/engine/results.py
def __len__(self):
    """Return the number of detections in the Results object."""
    for k in self._keys:
        v = getattr(self, k)
        if v is not None:
            return len(v)

cpu()

返回包含 CPU 内存中所有张量的结果对象副本。

源代码 ultralytics/engine/results.py
def cpu(self):
    """Return a copy of the Results object with all tensors on CPU memory."""
    return self._apply("cpu")

cuda()

返回包含 GPU 内存中所有张量的 Results 对象副本。

源代码 ultralytics/engine/results.py
def cuda(self):
    """Return a copy of the Results object with all tensors on GPU memory."""
    return self._apply("cuda")

new()

返回一个具有相同图像、路径和名称的新结果对象。

源代码 ultralytics/engine/results.py
def new(self):
    """Return a new Results object with the same image, path, and names."""
    return Results(orig_img=self.orig_img, path=self.path, names=self.names)

numpy()

返回结果对象的副本,其中所有张量均为 numpy 数组。

源代码 ultralytics/engine/results.py
def numpy(self):
    """Return a copy of the Results object with all tensors as numpy arrays."""
    return self._apply("numpy")

plot(conf=True, line_width=None, font_size=None, font='Arial.ttf', pil=False, img=None, im_gpu=None, kpt_radius=5, kpt_line=True, labels=True, boxes=True, masks=True, probs=True, show=False, save=False, filename=None)

在输入的 RGB 图像上绘制检测结果。接受 numpy 数组(cv2)或 PIL 图像。

参数

名称 类型 说明 默认值
conf bool

是否绘制检测置信度得分。

True
line_width float

边界框的线宽。如果无,则按图像大小缩放。

None
font_size float

文本的字体大小。如果无,则按图像大小缩放。

None
font str

文本使用的字体。

'Arial.ttf'
pil bool

是否将图像作为 PIL 图像返回。

False
img ndarray

如果没有,则绘制到原始图像。

None
im_gpu Tensor

在 gpu 中以形状(1, 3, 640, 640)对图像进行归一化处理,以便更快地绘制掩膜图。

None
kpt_radius int

绘制关键点的半径。默认值为 5。

5
kpt_line bool

是否绘制连接关键点的线条。

True
labels bool

是否绘制边界框的标签。

True
boxes bool

是否绘制边界框。

True
masks bool

是否绘制面具。

True
probs bool

是否绘制分类概率

True
show bool

是否直接显示注释图像。

False
save bool

是否将注释的图像保存到 filename.

False
filename str

如果保存为 True,则保存图像的文件名。

None

返回:

类型 说明
ndarray

注释图像的 numpy 数组。

示例
from PIL import Image
from ultralytics import YOLO

model = YOLO('yolov8n.pt')
results = model('bus.jpg')  # results list
for r in results:
    im_array = r.plot()  # plot a BGR numpy array of predictions
    im = Image.fromarray(im_array[..., ::-1])  # RGB PIL image
    im.show()  # show image
    im.save('results.jpg')  # save image
源代码 ultralytics/engine/results.py
def plot(
    self,
    conf=True,
    line_width=None,
    font_size=None,
    font="Arial.ttf",
    pil=False,
    img=None,
    im_gpu=None,
    kpt_radius=5,
    kpt_line=True,
    labels=True,
    boxes=True,
    masks=True,
    probs=True,
    show=False,
    save=False,
    filename=None,
):
    """
    Plots the detection results on an input RGB image. Accepts a numpy array (cv2) or a PIL Image.

    Args:
        conf (bool): Whether to plot the detection confidence score.
        line_width (float, optional): The line width of the bounding boxes. If None, it is scaled to the image size.
        font_size (float, optional): The font size of the text. If None, it is scaled to the image size.
        font (str): The font to use for the text.
        pil (bool): Whether to return the image as a PIL Image.
        img (numpy.ndarray): Plot to another image. if not, plot to original image.
        im_gpu (torch.Tensor): Normalized image in gpu with shape (1, 3, 640, 640), for faster mask plotting.
        kpt_radius (int, optional): Radius of the drawn keypoints. Default is 5.
        kpt_line (bool): Whether to draw lines connecting keypoints.
        labels (bool): Whether to plot the label of bounding boxes.
        boxes (bool): Whether to plot the bounding boxes.
        masks (bool): Whether to plot the masks.
        probs (bool): Whether to plot classification probability
        show (bool): Whether to display the annotated image directly.
        save (bool): Whether to save the annotated image to `filename`.
        filename (str): Filename to save image to if save is True.

    Returns:
        (numpy.ndarray): A numpy array of the annotated image.

    Example:
        ```python
        from PIL import Image
        from ultralytics import YOLO

        model = YOLO('yolov8n.pt')
        results = model('bus.jpg')  # results list
        for r in results:
            im_array = r.plot()  # plot a BGR numpy array of predictions
            im = Image.fromarray(im_array[..., ::-1])  # RGB PIL image
            im.show()  # show image
            im.save('results.jpg')  # save image
        ```
    """
    if img is None and isinstance(self.orig_img, torch.Tensor):
        img = (self.orig_img[0].detach().permute(1, 2, 0).contiguous() * 255).to(torch.uint8).cpu().numpy()

    names = self.names
    is_obb = self.obb is not None
    pred_boxes, show_boxes = self.obb if is_obb else self.boxes, boxes
    pred_masks, show_masks = self.masks, masks
    pred_probs, show_probs = self.probs, probs
    annotator = Annotator(
        deepcopy(self.orig_img if img is None else img),
        line_width,
        font_size,
        font,
        pil or (pred_probs is not None and show_probs),  # Classify tasks default to pil=True
        example=names,
    )

    # Plot Segment results
    if pred_masks and show_masks:
        if im_gpu is None:
            img = LetterBox(pred_masks.shape[1:])(image=annotator.result())
            im_gpu = (
                torch.as_tensor(img, dtype=torch.float16, device=pred_masks.data.device)
                .permute(2, 0, 1)
                .flip(0)
                .contiguous()
                / 255
            )
        idx = pred_boxes.cls if pred_boxes else range(len(pred_masks))
        annotator.masks(pred_masks.data, colors=[colors(x, True) for x in idx], im_gpu=im_gpu)

    # Plot Detect results
    if pred_boxes is not None and show_boxes:
        for d in reversed(pred_boxes):
            c, conf, id = int(d.cls), float(d.conf) if conf else None, None if d.id is None else int(d.id.item())
            name = ("" if id is None else f"id:{id} ") + names[c]
            label = (f"{name} {conf:.2f}" if conf else name) if labels else None
            box = d.xyxyxyxy.reshape(-1, 4, 2).squeeze() if is_obb else d.xyxy.squeeze()
            annotator.box_label(box, label, color=colors(c, True), rotated=is_obb)

    # Plot Classify results
    if pred_probs is not None and show_probs:
        text = ",\n".join(f"{names[j] if names else j} {pred_probs.data[j]:.2f}" for j in pred_probs.top5)
        x = round(self.orig_shape[0] * 0.03)
        annotator.text([x, x], text, txt_color=(255, 255, 255))  # TODO: allow setting colors

    # Plot Pose results
    if self.keypoints is not None:
        for k in reversed(self.keypoints.data):
            annotator.kpts(k, self.orig_shape, radius=kpt_radius, kpt_line=kpt_line)

    # Show results
    if show:
        annotator.show(self.path)

    # Save results
    if save:
        annotator.save(filename)

    return annotator.result()

save(filename=None, *args, **kwargs)

保存带注释的结果图像。

源代码 ultralytics/engine/results.py
def save(self, filename=None, *args, **kwargs):
    """Save annotated results image."""
    if not filename:
        filename = f"results_{Path(self.path).name}"
    self.plot(save=True, filename=filename, *args, **kwargs)
    return filename

save_crop(save_dir, file_name=Path('im.jpg'))

将裁剪后的预测保存到 save_dir/cls/file_name.jpg.

参数

名称 类型 说明 默认值
save_dir str | Path

保存路径。

所需
file_name str | Path

文件名。

Path('im.jpg')
源代码 ultralytics/engine/results.py
def save_crop(self, save_dir, file_name=Path("im.jpg")):
    """
    Save cropped predictions to `save_dir/cls/file_name.jpg`.

    Args:
        save_dir (str | pathlib.Path): Save path.
        file_name (str | pathlib.Path): File name.
    """
    if self.probs is not None:
        LOGGER.warning("WARNING ⚠️ Classify task do not support `save_crop`.")
        return
    if self.obb is not None:
        LOGGER.warning("WARNING ⚠️ OBB task do not support `save_crop`.")
        return
    for d in self.boxes:
        save_one_box(
            d.xyxy,
            self.orig_img.copy(),
            file=Path(save_dir) / self.names[int(d.cls)] / f"{Path(file_name)}.jpg",
            BGR=True,
        )

save_txt(txt_file, save_conf=False)

将预测结果保存到 txt 文件中。

参数

名称 类型 说明 默认值
txt_file str

txt 文件路径。

所需
save_conf bool

是否保存信心分数。

False
源代码 ultralytics/engine/results.py
def save_txt(self, txt_file, save_conf=False):
    """
    Save predictions into txt file.

    Args:
        txt_file (str): txt file path.
        save_conf (bool): save confidence score or not.
    """
    is_obb = self.obb is not None
    boxes = self.obb if is_obb else self.boxes
    masks = self.masks
    probs = self.probs
    kpts = self.keypoints
    texts = []
    if probs is not None:
        # Classify
        [texts.append(f"{probs.data[j]:.2f} {self.names[j]}") for j in probs.top5]
    elif boxes:
        # Detect/segment/pose
        for j, d in enumerate(boxes):
            c, conf, id = int(d.cls), float(d.conf), None if d.id is None else int(d.id.item())
            line = (c, *(d.xyxyxyxyn.view(-1) if is_obb else d.xywhn.view(-1)))
            if masks:
                seg = masks[j].xyn[0].copy().reshape(-1)  # reversed mask.xyn, (n,2) to (n*2)
                line = (c, *seg)
            if kpts is not None:
                kpt = torch.cat((kpts[j].xyn, kpts[j].conf[..., None]), 2) if kpts[j].has_visible else kpts[j].xyn
                line += (*kpt.reshape(-1).tolist(),)
            line += (conf,) * save_conf + (() if id is None else (id,))
            texts.append(("%g " * len(line)).rstrip() % line)

    if texts:
        Path(txt_file).parent.mkdir(parents=True, exist_ok=True)  # make directory
        with open(txt_file, "a") as f:
            f.writelines(text + "\n" for text in texts)

show(*args, **kwargs)

显示带注释的结果图像。

源代码 ultralytics/engine/results.py
def show(self, *args, **kwargs):
    """Show annotated results image."""
    self.plot(show=True, *args, **kwargs)

summary(normalize=False, decimals=5)

将结果转换为摘要格式。

源代码 ultralytics/engine/results.py
def summary(self, normalize=False, decimals=5):
    """Convert the results to a summarized format."""
    # Create list of detection dictionaries
    results = []
    if self.probs is not None:
        class_id = self.probs.top1
        results.append(
            {
                "name": self.names[class_id],
                "class": class_id,
                "confidence": round(self.probs.top1conf.item(), decimals),
            }
        )
        return results

    data = self.boxes or self.obb
    is_obb = self.obb is not None
    h, w = self.orig_shape if normalize else (1, 1)
    for i, row in enumerate(data):  # xyxy, track_id if tracking, conf, class_id
        class_id, conf = int(row.cls), round(row.conf.item(), decimals)
        box = (row.xyxyxyxy if is_obb else row.xyxy).squeeze().reshape(-1, 2).tolist()
        xy = {}
        for j, b in enumerate(box):
            xy[f"x{j + 1}"] = round(b[0] / w, decimals)
            xy[f"y{j + 1}"] = round(b[1] / h, decimals)
        result = {"name": self.names[class_id], "class": class_id, "confidence": conf, "box": xy}
        if data.is_track:
            result["track_id"] = int(row.id.item())  # track ID
        if self.masks:
            result["segments"] = {
                "x": (self.masks.xy[i][:, 0] / w).round(decimals).tolist(),
                "y": (self.masks.xy[i][:, 1] / h).round(decimals).tolist(),
            }
        if self.keypoints is not None:
            x, y, visible = self.keypoints[i].data[0].cpu().unbind(dim=1)  # torch Tensor
            result["keypoints"] = {
                "x": (x / w).numpy().round(decimals).tolist(),  # decimals named argument required
                "y": (y / h).numpy().round(decimals).tolist(),
                "visible": visible.numpy().round(decimals).tolist(),
            }
        results.append(result)

    return results

to(*args, **kwargs)

返回带有指定设备和 dtype 上张量的 Results 对象副本。

源代码 ultralytics/engine/results.py
def to(self, *args, **kwargs):
    """Return a copy of the Results object with tensors on the specified device and dtype."""
    return self._apply("to", *args, **kwargs)

tojson(normalize=False, decimals=5)

将结果转换为 JSON 格式。

源代码 ultralytics/engine/results.py
def tojson(self, normalize=False, decimals=5):
    """Convert the results to JSON format."""
    import json

    return json.dumps(self.summary(normalize=normalize, decimals=decimals), indent=2)

update(boxes=None, masks=None, probs=None, obb=None)

更新结果对象的方框、掩码和 probs 属性。

源代码 ultralytics/engine/results.py
def update(self, boxes=None, masks=None, probs=None, obb=None):
    """Update the boxes, masks, and probs attributes of the Results object."""
    if boxes is not None:
        self.boxes = Boxes(ops.clip_boxes(boxes, self.orig_shape), self.orig_shape)
    if masks is not None:
        self.masks = Masks(masks, self.orig_shape)
    if probs is not None:
        self.probs = probs
    if obb is not None:
        self.obb = OBB(obb, self.orig_shape)

verbose()

返回每个任务的日志字符串。

源代码 ultralytics/engine/results.py
def verbose(self):
    """Return log string for each task."""
    log_string = ""
    probs = self.probs
    boxes = self.boxes
    if len(self) == 0:
        return log_string if probs is not None else f"{log_string}(no detections), "
    if probs is not None:
        log_string += f"{', '.join(f'{self.names[j]} {probs.data[j]:.2f}' for j in probs.top5)}, "
    if boxes:
        for c in boxes.cls.unique():
            n = (boxes.cls == c).sum()  # detections per class
            log_string += f"{n} {self.names[int(c)]}{'s' * (n > 1)}, "
    return log_string



ultralytics.engine.results.Boxes

垒球 BaseTensor

管理检测框,方便访问和操作检测框坐标、置信度分数、类别 标识符和可选的跟踪 ID。支持多种方框坐标格式,包括绝对和 规范化形式。

属性

名称 类型 说明
data Tensor

原始tensor 包含检测框及其相关数据。

orig_shape tuple

原始图像尺寸的元组(高、宽),用于标准化。

is_track bool

表示跟踪 ID 是否包含在包装盒数据中。

属性

xyxy (torch.Tensor | numpy.ndarray):格式为 [x1, y1, x2, y2] 的方框。 conf (torch.Tensor | numpy.ndarray):每个方框的置信度得分。 cls (torch.Tensor | numpy.ndarray):每个方框的类标签:每个方框的类标签。 id (torch.Tensor | numpy.ndarray,可选):每个方框的跟踪 ID(如果有)。 xywh (torch.Tensor | numpy.ndarray):按要求计算的 [x, y, width, height] 格式的方框。 xyxyn (torch.Tensor | numpy.ndarray):归一化 [x1, y1, x2, y2] 方框,相对于 orig_shape. xywhn (torch.Tensor | numpy.ndarray):归一化的 [x、y、宽、高] 方框,相对于 orig_shape.

方法

名称 说明
cpu

将方框移动到 CPU 内存中。

numpy

将方框转换为 numpy 数组格式。

cuda

将方框移动到 CUDA(GPU)内存。

to

将方框移动到指定设备。

源代码 ultralytics/engine/results.py
class Boxes(BaseTensor):
    """
    Manages detection boxes, providing easy access and manipulation of box coordinates, confidence scores, class
    identifiers, and optional tracking IDs. Supports multiple formats for box coordinates, including both absolute and
    normalized forms.

    Attributes:
        data (torch.Tensor): The raw tensor containing detection boxes and their associated data.
        orig_shape (tuple): The original image size as a tuple (height, width), used for normalization.
        is_track (bool): Indicates whether tracking IDs are included in the box data.

    Properties:
        xyxy (torch.Tensor | numpy.ndarray): Boxes in [x1, y1, x2, y2] format.
        conf (torch.Tensor | numpy.ndarray): Confidence scores for each box.
        cls (torch.Tensor | numpy.ndarray): Class labels for each box.
        id (torch.Tensor | numpy.ndarray, optional): Tracking IDs for each box, if available.
        xywh (torch.Tensor | numpy.ndarray): Boxes in [x, y, width, height] format, calculated on demand.
        xyxyn (torch.Tensor | numpy.ndarray): Normalized [x1, y1, x2, y2] boxes, relative to `orig_shape`.
        xywhn (torch.Tensor | numpy.ndarray): Normalized [x, y, width, height] boxes, relative to `orig_shape`.

    Methods:
        cpu(): Moves the boxes to CPU memory.
        numpy(): Converts the boxes to a numpy array format.
        cuda(): Moves the boxes to CUDA (GPU) memory.
        to(device, dtype=None): Moves the boxes to the specified device.
    """

    def __init__(self, boxes, orig_shape) -> None:
        """
        Initialize the Boxes class.

        Args:
            boxes (torch.Tensor | numpy.ndarray): A tensor or numpy array containing the detection boxes, with
                shape (num_boxes, 6) or (num_boxes, 7). The last two columns contain confidence and class values.
                If present, the third last column contains track IDs.
            orig_shape (tuple): Original image size, in the format (height, width).
        """
        if boxes.ndim == 1:
            boxes = boxes[None, :]
        n = boxes.shape[-1]
        assert n in {6, 7}, f"expected 6 or 7 values but got {n}"  # xyxy, track_id, conf, cls
        super().__init__(boxes, orig_shape)
        self.is_track = n == 7
        self.orig_shape = orig_shape

    @property
    def xyxy(self):
        """Return the boxes in xyxy format."""
        return self.data[:, :4]

    @property
    def conf(self):
        """Return the confidence values of the boxes."""
        return self.data[:, -2]

    @property
    def cls(self):
        """Return the class values of the boxes."""
        return self.data[:, -1]

    @property
    def id(self):
        """Return the track IDs of the boxes (if available)."""
        return self.data[:, -3] if self.is_track else None

    @property
    @lru_cache(maxsize=2)  # maxsize 1 should suffice
    def xywh(self):
        """Return the boxes in xywh format."""
        return ops.xyxy2xywh(self.xyxy)

    @property
    @lru_cache(maxsize=2)
    def xyxyn(self):
        """Return the boxes in xyxy format normalized by original image size."""
        xyxy = self.xyxy.clone() if isinstance(self.xyxy, torch.Tensor) else np.copy(self.xyxy)
        xyxy[..., [0, 2]] /= self.orig_shape[1]
        xyxy[..., [1, 3]] /= self.orig_shape[0]
        return xyxy

    @property
    @lru_cache(maxsize=2)
    def xywhn(self):
        """Return the boxes in xywh format normalized by original image size."""
        xywh = ops.xyxy2xywh(self.xyxy)
        xywh[..., [0, 2]] /= self.orig_shape[1]
        xywh[..., [1, 3]] /= self.orig_shape[0]
        return xywh

cls property

返回方框的类值。

conf property

返回方框的置信度值。

id property

返回盒子的轨道 ID(如果有)。

xywh cached property

以 xywh 格式返回方框。

xywhn cached property

以 xywh 格式返回按原始图像大小归一化的方框。

xyxy property

以 xyxy 格式返回方框。

xyxyn cached property

以 xyxy 格式返回按原始图像大小归一化的方框。

__init__(boxes, orig_shape)

初始化方框类。

参数

名称 类型 说明 默认值
boxes Tensor | ndarray

tensor 或 numpy 数组,其中包含检测框,形状为 形状 (num_boxes, 6) 或 (num_boxes, 7)。最后两列包含置信度和类别值。 如果存在,倒数第三列包含轨迹 ID。

所需
orig_shape tuple

原始图像大小,格式为(高、宽)。

所需
源代码 ultralytics/engine/results.py
def __init__(self, boxes, orig_shape) -> None:
    """
    Initialize the Boxes class.

    Args:
        boxes (torch.Tensor | numpy.ndarray): A tensor or numpy array containing the detection boxes, with
            shape (num_boxes, 6) or (num_boxes, 7). The last two columns contain confidence and class values.
            If present, the third last column contains track IDs.
        orig_shape (tuple): Original image size, in the format (height, width).
    """
    if boxes.ndim == 1:
        boxes = boxes[None, :]
    n = boxes.shape[-1]
    assert n in {6, 7}, f"expected 6 or 7 values but got {n}"  # xyxy, track_id, conf, cls
    super().__init__(boxes, orig_shape)
    self.is_track = n == 7
    self.orig_shape = orig_shape



ultralytics.engine.results.Masks

垒球 BaseTensor

用于存储和操作检测掩码的类。

属性

名称 类型 说明
xy list

以像素坐标表示的线段列表。

xyn list

标准化片段列表。

方法

名称 说明
cpu

返回 CPU 内存中的掩码tensor 。

numpy

以 numpy 数组形式返回掩码tensor 。

cuda

返回 GPU 内存中的掩码tensor 。

to

返回具有指定设备和 dtype 的掩码tensor 。

源代码 ultralytics/engine/results.py
class Masks(BaseTensor):
    """
    A class for storing and manipulating detection masks.

    Attributes:
        xy (list): A list of segments in pixel coordinates.
        xyn (list): A list of normalized segments.

    Methods:
        cpu(): Returns the masks tensor on CPU memory.
        numpy(): Returns the masks tensor as a numpy array.
        cuda(): Returns the masks tensor on GPU memory.
        to(device, dtype): Returns the masks tensor with the specified device and dtype.
    """

    def __init__(self, masks, orig_shape) -> None:
        """Initialize the Masks class with the given masks tensor and original image shape."""
        if masks.ndim == 2:
            masks = masks[None, :]
        super().__init__(masks, orig_shape)

    @property
    @lru_cache(maxsize=1)
    def xyn(self):
        """Return normalized segments."""
        return [
            ops.scale_coords(self.data.shape[1:], x, self.orig_shape, normalize=True)
            for x in ops.masks2segments(self.data)
        ]

    @property
    @lru_cache(maxsize=1)
    def xy(self):
        """Return segments in pixel coordinates."""
        return [
            ops.scale_coords(self.data.shape[1:], x, self.orig_shape, normalize=False)
            for x in ops.masks2segments(self.data)
        ]

xy cached property

以像素坐标返回线段。

xyn cached property

返回归一化分段。

__init__(masks, orig_shape)

使用给定的遮罩tensor 和原始图像形状初始化遮罩类。

源代码 ultralytics/engine/results.py
def __init__(self, masks, orig_shape) -> None:
    """Initialize the Masks class with the given masks tensor and original image shape."""
    if masks.ndim == 2:
        masks = masks[None, :]
    super().__init__(masks, orig_shape)



ultralytics.engine.results.Keypoints

垒球 BaseTensor

用于存储和操作检测关键点的类。

属性

名称 类型 说明
xy Tensor

关键点集合,包含每次检测的 x、y 坐标。

xyn Tensor

xy 的标准化版本,坐标范围为 [0,1]。

conf Tensor

与关键点相关的置信度值(如果有),否则为 "无"。

方法

名称 说明
cpu

返回 CPU 内存中关键点tensor 的副本。

numpy

以 numpy 数组形式返回关键点tensor 的副本。

cuda

返回 GPU 内存中关键点tensor 的副本。

to

用指定的设备和 dtype 返回关键点tensor 的副本。

源代码 ultralytics/engine/results.py
class Keypoints(BaseTensor):
    """
    A class for storing and manipulating detection keypoints.

    Attributes:
        xy (torch.Tensor): A collection of keypoints containing x, y coordinates for each detection.
        xyn (torch.Tensor): A normalized version of xy with coordinates in the range [0, 1].
        conf (torch.Tensor): Confidence values associated with keypoints if available, otherwise None.

    Methods:
        cpu(): Returns a copy of the keypoints tensor on CPU memory.
        numpy(): Returns a copy of the keypoints tensor as a numpy array.
        cuda(): Returns a copy of the keypoints tensor on GPU memory.
        to(device, dtype): Returns a copy of the keypoints tensor with the specified device and dtype.
    """

    @smart_inference_mode()  # avoid keypoints < conf in-place error
    def __init__(self, keypoints, orig_shape) -> None:
        """Initializes the Keypoints object with detection keypoints and original image size."""
        if keypoints.ndim == 2:
            keypoints = keypoints[None, :]
        if keypoints.shape[2] == 3:  # x, y, conf
            mask = keypoints[..., 2] < 0.5  # points with conf < 0.5 (not visible)
            keypoints[..., :2][mask] = 0
        super().__init__(keypoints, orig_shape)
        self.has_visible = self.data.shape[-1] == 3

    @property
    @lru_cache(maxsize=1)
    def xy(self):
        """Returns x, y coordinates of keypoints."""
        return self.data[..., :2]

    @property
    @lru_cache(maxsize=1)
    def xyn(self):
        """Returns normalized x, y coordinates of keypoints."""
        xy = self.xy.clone() if isinstance(self.xy, torch.Tensor) else np.copy(self.xy)
        xy[..., 0] /= self.orig_shape[1]
        xy[..., 1] /= self.orig_shape[0]
        return xy

    @property
    @lru_cache(maxsize=1)
    def conf(self):
        """Returns confidence values of keypoints if available, else None."""
        return self.data[..., 2] if self.has_visible else None

conf cached property

返回关键点的置信度值(如果有),否则为空。

xy cached property

返回关键点的 x、y 坐标。

xyn cached property

返回关键点的归一化 x、y 坐标。

__init__(keypoints, orig_shape)

使用检测关键点和原始图像尺寸初始化关键点对象。

源代码 ultralytics/engine/results.py
@smart_inference_mode()  # avoid keypoints < conf in-place error
def __init__(self, keypoints, orig_shape) -> None:
    """Initializes the Keypoints object with detection keypoints and original image size."""
    if keypoints.ndim == 2:
        keypoints = keypoints[None, :]
    if keypoints.shape[2] == 3:  # x, y, conf
        mask = keypoints[..., 2] < 0.5  # points with conf < 0.5 (not visible)
        keypoints[..., :2][mask] = 0
    super().__init__(keypoints, orig_shape)
    self.has_visible = self.data.shape[-1] == 3



ultralytics.engine.results.Probs

垒球 BaseTensor

用于存储和处理分类预测的类。

属性

名称 类型 说明
top1 int

前 1 级的指数。

top5 list[int]

前 5 个等级的指数。

top1conf Tensor

对前 1 级充满信心。

top5conf Tensor

前五名班级的机密

方法

名称 说明
cpu

返回 CPU 内存中 probstensor 的副本。

numpy

以 numpy 数组形式返回 probstensor 的副本。

cuda

返回 GPU 内存中 probstensor 的副本。

to

返回带有指定设备和 dtype 的 probstensor 的副本。

源代码 ultralytics/engine/results.py
class Probs(BaseTensor):
    """
    A class for storing and manipulating classification predictions.

    Attributes:
        top1 (int): Index of the top 1 class.
        top5 (list[int]): Indices of the top 5 classes.
        top1conf (torch.Tensor): Confidence of the top 1 class.
        top5conf (torch.Tensor): Confidences of the top 5 classes.

    Methods:
        cpu(): Returns a copy of the probs tensor on CPU memory.
        numpy(): Returns a copy of the probs tensor as a numpy array.
        cuda(): Returns a copy of the probs tensor on GPU memory.
        to(): Returns a copy of the probs tensor with the specified device and dtype.
    """

    def __init__(self, probs, orig_shape=None) -> None:
        """Initialize the Probs class with classification probabilities and optional original shape of the image."""
        super().__init__(probs, orig_shape)

    @property
    @lru_cache(maxsize=1)
    def top1(self):
        """Return the index of top 1."""
        return int(self.data.argmax())

    @property
    @lru_cache(maxsize=1)
    def top5(self):
        """Return the indices of top 5."""
        return (-self.data).argsort(0)[:5].tolist()  # this way works with both torch and numpy.

    @property
    @lru_cache(maxsize=1)
    def top1conf(self):
        """Return the confidence of top 1."""
        return self.data[self.top1]

    @property
    @lru_cache(maxsize=1)
    def top5conf(self):
        """Return the confidences of top 5."""
        return self.data[self.top5]

top1 cached property

返回顶部 1 的索引。

top1conf cached property

返回前 1 名的置信度。

top5 cached property

返回前 5 名的指数。

top5conf cached property

返回前 5 名的保密信息。

__init__(probs, orig_shape=None)

用分类概率和可选的图像原始形状初始化 Probs 类。

源代码 ultralytics/engine/results.py
def __init__(self, probs, orig_shape=None) -> None:
    """Initialize the Probs class with classification probabilities and optional original shape of the image."""
    super().__init__(probs, orig_shape)



ultralytics.engine.results.OBB

垒球 BaseTensor

用于存储和操作定向边框(OBB)的类。

参数

名称 类型 说明 默认值
boxes Tensor | ndarray

tensor 或包含检测框的 numpy 数组、 形状为 (num_boxes, 7) 或 (num_boxes, 8)。最后两列包含置信度和类别值。 如果存在,倒数第三列包含轨迹 ID,左起第五列包含旋转。

所需
orig_shape tuple

原始图像大小,格式为(高、宽)。

所需

属性

名称 类型 说明
xywhr Tensor | ndarray

x_center, y_center, width, height, rotation] 格式的方框。

conf Tensor | ndarray

方框的置信度值。

cls Tensor | ndarray

方框的类值。

id Tensor | ndarray

盒子的轨道 ID(如果有)。

xyxyxyxyn Tensor | ndarray

按原始图像大小归一化的 xyxyxyxy 格式旋转框。

xyxyxyxy Tensor | ndarray

以 xyxyxyxy 格式旋转的方框。

xyxy Tensor | ndarray

xyxyxyxy 格式的水平方框。

data Tensor

原始 OBBtensor (OBB 的别名 boxes).

方法

名称 说明
cpu

将对象移至 CPU 内存。

numpy

将对象转换为 numpy 数组。

cuda

将对象移至 CUDA 内存。

to

将对象移动到指定设备。

源代码 ultralytics/engine/results.py
class OBB(BaseTensor):
    """
    A class for storing and manipulating Oriented Bounding Boxes (OBB).

    Args:
        boxes (torch.Tensor | numpy.ndarray): A tensor or numpy array containing the detection boxes,
            with shape (num_boxes, 7) or (num_boxes, 8). The last two columns contain confidence and class values.
            If present, the third last column contains track IDs, and the fifth column from the left contains rotation.
        orig_shape (tuple): Original image size, in the format (height, width).

    Attributes:
        xywhr (torch.Tensor | numpy.ndarray): The boxes in [x_center, y_center, width, height, rotation] format.
        conf (torch.Tensor | numpy.ndarray): The confidence values of the boxes.
        cls (torch.Tensor | numpy.ndarray): The class values of the boxes.
        id (torch.Tensor | numpy.ndarray): The track IDs of the boxes (if available).
        xyxyxyxyn (torch.Tensor | numpy.ndarray): The rotated boxes in xyxyxyxy format normalized by orig image size.
        xyxyxyxy (torch.Tensor | numpy.ndarray): The rotated boxes in xyxyxyxy format.
        xyxy (torch.Tensor | numpy.ndarray): The horizontal boxes in xyxyxyxy format.
        data (torch.Tensor): The raw OBB tensor (alias for `boxes`).

    Methods:
        cpu(): Move the object to CPU memory.
        numpy(): Convert the object to a numpy array.
        cuda(): Move the object to CUDA memory.
        to(*args, **kwargs): Move the object to the specified device.
    """

    def __init__(self, boxes, orig_shape) -> None:
        """Initialize the Boxes class."""
        if boxes.ndim == 1:
            boxes = boxes[None, :]
        n = boxes.shape[-1]
        assert n in {7, 8}, f"expected 7 or 8 values but got {n}"  # xywh, rotation, track_id, conf, cls
        super().__init__(boxes, orig_shape)
        self.is_track = n == 8
        self.orig_shape = orig_shape

    @property
    def xywhr(self):
        """Return the rotated boxes in xywhr format."""
        return self.data[:, :5]

    @property
    def conf(self):
        """Return the confidence values of the boxes."""
        return self.data[:, -2]

    @property
    def cls(self):
        """Return the class values of the boxes."""
        return self.data[:, -1]

    @property
    def id(self):
        """Return the track IDs of the boxes (if available)."""
        return self.data[:, -3] if self.is_track else None

    @property
    @lru_cache(maxsize=2)
    def xyxyxyxy(self):
        """Return the boxes in xyxyxyxy format, (N, 4, 2)."""
        return ops.xywhr2xyxyxyxy(self.xywhr)

    @property
    @lru_cache(maxsize=2)
    def xyxyxyxyn(self):
        """Return the boxes in xyxyxyxy format, (N, 4, 2)."""
        xyxyxyxyn = self.xyxyxyxy.clone() if isinstance(self.xyxyxyxy, torch.Tensor) else np.copy(self.xyxyxyxy)
        xyxyxyxyn[..., 0] /= self.orig_shape[1]
        xyxyxyxyn[..., 1] /= self.orig_shape[0]
        return xyxyxyxyn

    @property
    @lru_cache(maxsize=2)
    def xyxy(self):
        """
        Return the horizontal boxes in xyxy format, (N, 4).

        Accepts both torch and numpy boxes.
        """
        x1 = self.xyxyxyxy[..., 0].min(1).values
        x2 = self.xyxyxyxy[..., 0].max(1).values
        y1 = self.xyxyxyxy[..., 1].min(1).values
        y2 = self.xyxyxyxy[..., 1].max(1).values
        xyxy = [x1, y1, x2, y2]
        return np.stack(xyxy, axis=-1) if isinstance(self.data, np.ndarray) else torch.stack(xyxy, dim=-1)

cls property

返回方框的类值。

conf property

返回方框的置信度值。

id property

返回盒子的轨道 ID(如果有)。

xywhr property

以 xywhr 格式返回旋转后的方框。

xyxy cached property

以 xyxy 格式返回水平方框(N,4)。

同时接受torch 和 numpy 框。

xyxyxyxy cached property

以 xyxyxyxy 格式返回方框(N,4,2)。

xyxyxyxyn cached property

以 xyxyxyxy 格式返回方框(N,4,2)。

__init__(boxes, orig_shape)

初始化方框类。

源代码 ultralytics/engine/results.py
def __init__(self, boxes, orig_shape) -> None:
    """Initialize the Boxes class."""
    if boxes.ndim == 1:
        boxes = boxes[None, :]
    n = boxes.shape[-1]
    assert n in {7, 8}, f"expected 7 or 8 values but got {n}"  # xywh, rotation, track_id, conf, cls
    super().__init__(boxes, orig_shape)
    self.is_track = n == 8
    self.orig_shape = orig_shape





创建于 2023-11-12,更新于 2024-05-08
作者:Burhan-Q(1)、glenn-jocher(4)、Laughing-q(1)