YOLO V8-Pose 【单张图片推理】推理详解及部署实现

前言

在实际处理过程中,我们使用YOLO V8进行推理时,通常会针对一张图片进行推理。如果需要对多张图片进行推理,则可以通过一个循环来实现对图片逐张进行推理。

单张图片推理时,需要注意图片的尺寸必须是32的倍数,否则可能导致推理失败。在下面的示例中,我们展示了如何使用PyTorch和Ultralytics库进行单张图片的推理:

import torch
from ultralytics import YOLO

# Load a pretrained YOLOv8n model
model = YOLO('yolov8n-pose.pt')

# Create a random torch tensor of BCHW shape (1, 3, 640, 640) with values in range [0, 1] and type float32
source = torch.rand(1, 3, 640, 640, dtype=torch.float32)

# Run inference on the source
results = model(source)  # list of Results objects

批量图片推理时,也需要注意图片的尺寸必须是32的倍数。在下面的示例中,我们展示了如何使用PyTorch和Ultralytics库进行多张图片的批量推理:

import torch
from ultralytics import YOLO

# Load a pretrained YOLOv8n model
model = YOLO('yolov8n-pose.pt')

# Create a random torch tensor of BCHW shape (1, 3, 640, 640) with values in range [0, 1] and type float32
source = torch.rand(4, 3, 640, 640, dtype=torch.float32)

# Run inference on the source
results = model(source)  # list of Results objects

需要注意的是,在批量推理时,虽然一次推理了多张图片,但实际处理方式仍然是通过循环进行的。在后续的文章中,我们将介绍如何使用更高效的方式进行批量推理,以获得更快的推理速度和更好的性能。

下面我们介绍如何将检测推理代码给单独提取出来,进行推理。

一、YOLO V8-Segment 预测

在官方中,进行推理时,直接使用两行代码就能实现目标检测的功能。

from ultralytics import YOLO

# Load a model
model = YOLO('yolov8n-pose.pt')  # load an official model

# Predict with the model
results = model('./ultralytics/assets/bus.jpg')  # predict on an image

模型推理保存的结果图像如下所示:

模型预测成功,我们就需要自己动手来写下 YOLOv8-Seg 的模型加载、预处理和后处理,以便我们进行相关的操作,我们先来看看预处理的实现

二、YOLO V8-Pose 模型加载

原始加载方式

模型文件:ultralytics\engine\model.py

def _load(self, weights: str, task=None):
    """
    Initializes a new model and infers the task type from the model head.

    Args:
        weights (str): model checkpoint to be loaded
        task (str | None): model task
    """
    suffix = Path(weights).suffix
    if suffix == ".pt":
        self.model, self.ckpt = attempt_load_one_weight(weights)
        self.task = self.model.args["task"]
        self.overrides = self.model.args = self._reset_ckpt_args(self.model.args)
        self.ckpt_path = self.model.pt_path
    else:
        weights = checks.check_file(weights)
        self.model, self.ckpt = weights, None
        self.task = task or guess_model_task(weights)
        self.ckpt_path = weights
    self.overrides["model"] = weights
    self.overrides["task"] = self.task

模型文件:ultralytics/nn/tasks.py

def attempt_load_one_weight(weight, device=None, inplace=True, fuse=False):
    """Loads a single model weights."""
    ckpt, weight = torch_safe_load(weight)  # load ckpt
    args = {**DEFAULT_CFG_DICT, **(ckpt.get("train_args", {}))}  # combine model and default args, preferring model args
    model = (ckpt.get("ema") or ckpt["model"]).to(device).float()  # FP32 model

    # Model compatibility updates
    model.args = {k: v for k, v in args.items() if k in DEFAULT_CFG_KEYS}  # attach args to model
    model.pt_path = weight  # attach *.pt file path to model
    model.task = guess_model_task(model)
    if not hasattr(model, "stride"):
        model.stride = torch.tensor([32.0])

    model = model.fuse().eval() if fuse and hasattr(model, "fuse") else model.eval()  # model in eval mode

    # Module updates
    for m in model.modules():
        t = type(m)
        if t in (nn.Hardswish, nn.LeakyReLU, nn.ReLU, nn.ReLU6, nn.SiLU, Detect, Segment, Pose, OBB):
            m.inplace = inplace
        elif t is nn.Upsample and not hasattr(m, "recompute_scale_factor"):
            m.recompute_scale_factor = None  # torch 1.11.0 compatibility

    # Return model and ckpt
    return model, ckpt

上述两个代码是加载模型的原始方法,这种方法不仅会加载模型的权重,还会加载一系列相关的配置文件,这个并不是我们想要的。我们只加载模型权重,其余相关的都不需要加载,因此要使用下面这种方式进行加载。

修改后的加载方式

模型文件:ultralytics/nn/autobackend.py

@torch.no_grad()
def __init__(
    self,
    weights="yolov8n.pt",
    device=torch.device("cpu"),
    dnn=False,
    data=None,
    fp16=False,
    fuse=True,
    verbose=True,
):

参数介绍

  1. weights:模型权重文件的路径。默认为 "yolov8n.pt"。
  2. device (torch.device):运行模型的设备。默认为 CPU。
  3. dnn:使用 OpenCV DNN 模块进行 ONNX 推断。默认为假。
  4. data:包含类名的附加 data.yaml 文件的路径。可选。
  5. fp16:启用半精度推理。仅在特定后端支持。默认为 False。
  6. fuse:融合 Conv2D + BatchNorm 层进行优化。默认为 True。
  7. verbose:启用详细日志记录。默认为 True。

.pt 加载方式

elif pt:  # PyTorch
    from ultralytics.nn.tasks import attempt_load_weights

    model = attempt_load_weights(
        weights if isinstance(weights, list) else w, device=device, inplace=True, fuse=fuse
    )
    if hasattr(model, "kpt_shape"):
        kpt_shape = model.kpt_shape  # pose-only
    stride = max(int(model.stride.max()), 32)  # model stride
    names = model.module.names if hasattr(model, "module") else model.names  # get class names
    model.half() if fp16 else model.float()
    self.model = model  # explicitly assign for to(), cpu(), cuda(), half()

最终代码

from ultralytics.nn.autobackend import AutoBackend

weights = 'yolov8n-pose.pt'
model = AutoBackend(weights, device=torch.device("cuda:0"))

三、YOLO V8-Pose 预处理

原始处理方式

模型文件:ultralytics/engine/predictor.py

from ultralytics.data.augment import LetterBox

@smart_inference_mode()
def stream_inference(self, source=None, model=None, *args, **kwargs):
    """Streams real-time inference on camera feed and saves results to file."""
    .
    .
    .
    # Preprocess
    with profilers[0]:
        im = self.preprocess(im0s)
     .
     .
     .
    
    
def pre_transform(self, im):
    """
    Pre-transform input image before inference.

    Args:
        im (List(np.ndarray)): (N, 3, h, w) for tensor, [(h, w, 3) x N] for list.

    Returns:
        (list): A list of transformed images.
    """
    same_shapes = all(x.shape == im[0].shape for x in im)
    letterbox = LetterBox(self.imgsz, auto=same_shapes and self.model.pt, stride=self.model.stride)
    return [letterbox(image=x) for x in im]
    
def preprocess(self, im):
    """
    Prepares input image before inference.

    Args:
        im (torch.Tensor | List(np.ndarray)): BCHW for tensor, [(HWC) x B] for list.
    """
    not_tensor = not isinstance(im, torch.Tensor)
    if not_tensor:
        im = np.stack(self.pre_transform(im))
        im = im[..., ::-1].transpose((0, 3, 1, 2))  # BGR to RGB, BHWC to BCHW, (n, 3, h, w)
        im = np.ascontiguousarray(im)  # contiguous
        im = torch.from_numpy(im)

    im = im.to(self.device)
    im = im.half() if self.model.fp16 else im.float()  # uint8 to fp16/32
    if not_tensor:
        im /= 255  # 0 - 255 to 0.0 - 1.0
    return im

它包含以下步骤:

  • self.pre_transform:即 letterbox 添加灰条

  • im[…,::-1]:BGR → RGB

  • transpose((0, 3, 1, 2)):添加 batch 维度,HWC → CHW

  • torch.from_numpy:to Tensor

  • im /= 255:除以 255,归一化

大家如果对 YOLOv5 的预处理熟悉的话,会发现 YOLOv8 的预处理和 YOLOv5 的预处理一模一样,因此我们不难写出对应的预处理代码,如下所示:

修改后的处理方式

def letterbox(self, im, new_shape=(640, 640), color=(114, 114, 114), auto=True, scaleFill=False, scaleup=True,
              stride=32):
    # Resize and pad image while meeting stride-multiple constraints
    shape = im.shape[:2]  # current shape [height, width]
    if isinstance(new_shape, int):
        new_shape = (new_shape, new_shape)

    # Scale ratio (new / old)
    r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])
    if not scaleup:  # only scale down, do not scale up (for better val mAP)
        r = min(r, 1.0)

    # Compute padding
    ratio = r, r  # width, height ratios
    new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r))
    dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1]  # wh padding
    if auto:  # minimum rectangle
        dw, dh = np.mod(dw, stride), np.mod(dh, stride)  # wh padding
    elif scaleFill:  # stretch
        dw, dh = 0.0, 0.0
        new_unpad = (new_shape[1], new_shape[0])
        ratio = new_shape[1] / shape[1], new_shape[0] / shape[0]  # width, height ratios

    dw /= 2  # divide padding into 2 sides
    dh /= 2

    if shape[::-1] != new_unpad:  # resize
        im = cv2.resize(im, new_unpad, interpolation=cv2.IN
<think>好的,用户想了解如何使用YOLOv8进行姿态估计,特别是关于YOLOv8-Pose实现和使用。首先,我需要回忆YOLOv8的相关信息,尤其是姿态估计部分。YOLOv8是Ultralytics公司推出的最新版本,支持多种任务,包括目标检测、实例分割、姿态估计等。而YOLOv8-Pose就是专门用于姿态估计的模型。 用户提到参考的站内引用链接是关于YOLOv8-Pose关键点检测的专栏,这可能意味着他们已经在CSDN上看到过相关的中文教程,但需要更详细的实现和使用说明。需要确保回答结构清晰,分步骤说明,并且符合用户的中文需求。 首先,我应该介绍YOLOv8-Pose的基本概念,比如它基于YOLO架构,能够实时检测人体关键点,比如17个COCO格式的关键点。然后,安装步骤是必要的,需要指导用户安装Ultralytics库,可能通过pip安装。 接下来是使用预训练模型进行推理,这里需要给出具体的Python代码示例,展示如何加载模型、进行预测并可视化结果。同时,要提到关键点的数据结构,比如每个关键点的坐标和置信度,方便用户后续处理。 然后,自定义训练部分也很重要。用户可能需要在自己的数据集上训练模型,所以需要说明数据集的格式要求,比如YOLO格式的标注文件结构,以及如何配置数据集yaml文件。训练代码示例也是必须的,包括加载模型、训练参数等。 可视化部分,用户可能需要将检测结果保存为图片或视频,这里需要给出绘制关键点和骨骼连接的代码示例,可能使用OpenCV或者matplotlib库。同时,可以提到Ultralytics内置的可视化功能,方便用户快速查看结果。 在注意事项里,需要提醒用户硬件要求,比如GPU加速,数据标注的准确性,以及参数调优的重要性。这些都能帮助用户避免常见的问题。 最后,相关问题的部分需要生成几个可能的问题,比如性能优化、部署到移动端、标注工具选择等,帮助用户进一步探索。 需要确保所有数学表达式,如果有的话,使用正确的LaTeX格式,但在这个主题下可能数学内容不多。代码块要正确格式化,使用三个反引号包裹,并注明语言。引用标识要添加到参考链接处,但用户提供的引用链接是关于YOLOv8-Pose的专栏,所以在回答中合适的位置插入[^1]。 检查所有步骤是否覆盖了实现和使用的关键点,确保信息准确,特别是代码部分是否正确,比如导入的模块、函数名是否有变化。例如,YOLO模型的加载是否正确,predict方法的参数是否最新。可能需要查阅最新的Ultralytics文档确认细节,但根据记忆,代码示例应该是正确的。 还要注意使用中文回答,避免专业术语错误,保持口语化但专业。最后,确保相关问题部分的问题有针对性,能够引导用户深入学习和解决问题。</think>### YOLOv8-Pose姿态估计实现与使用指南 YOLOv8-Pose是基于YOLOv8架构优化的姿态估计模型,能够实时检测人体关键点(如17个COCO格式关键点),适用于运动分析、安防监控等场景[^1]。 #### 一、环境安装 ```bash pip install ultralytics # 安装Ultralytics官方库 ``` #### 二、使用预训练模型推理 ```python from ultralytics import YOLO # 加载预训练模型 model = YOLO('yolov8n-pose.pt') # 可选模型:yolov8{s/m/l/x}-pose # 执行推理 results = model.predict('input_image.jpg', save=True, conf=0.5) # 解析关键点数据 for result in results: keypoints = result.keypoints # 形状为(N,17,3), 包含(x,y,置信度) print(f"检测到{len(keypoints)}个人的关键点") ``` #### 三、自定义训练 1. **数据集准备** - 标注格式要求: ``` class x_center y_center width height px1 py1 c1 px2 py2 c2 ... px17 py17 c17 ``` - 配置文件`data.yaml`示例: ```yaml train: ./train/images val: ./val/images nc: 1 # 类别数(人体检测) kpt_shape: [17, 3] # 关键点维度 ``` 2. **启动训练** ```python model = YOLO('yolov8n-pose.yaml') # 从配置文件初始化 model.train(data='data.yaml', epochs=100, imgsz=640, batch=16) ``` #### 四、结果可视化 ```python # 绘制带关键点的结果 result = model('input_image.jpg')[0] plot = result.plot() # 自动绘制检测框与关键点 plot.show() # 使用matplotlib显示 ``` #### 五、关键应用参数 | 参数 | 说明 | 推荐值 | |------|------|--------| | `conf` | 检测置信度阈值 | 0.25-0.5 | | `iou` | 交并比阈值 | 0.7 | | `kpt_radius` | 关键点绘制半径 | 5 | | `line_width` | 骨骼连接线宽 | 3 | #### 注意事项 1. GPU加速建议使用NVIDIA显卡(CUDA环境) 2. 关键点检测精度高度依赖标注质量 3. 复杂场景需调整`conf`和`iou`参数平衡精度与召回率
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

牧锦程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值