yolov8onnx推理读取坐标
时间: 2023-11-15 19:58:28 浏览: 261
YOLOv8 Pose是一个基于YOLOv5的人体关键点检测模型,可以用于识别人体的关键点。在使用YOLOv8 Pose进行推理时,需要读取模型并传入图片或视频,然后将检测框、关键点坐标还原到原图上。具体的步骤如下:
1. 使用onnxruntime.InferenceSession()读取模型。
2. 将图片或视频传入模型进行推理,得到检测框和关键点坐标。
3. 将检测框和关键点坐标还原到原图上,需要先将检测框和关键点坐标从缩放后的图片中还原到原图中。
4. 计算缩放比和填充大小,将检测数据缩放到原图中。
需要注意的是,YOLOv8 Pose的推理过程需要使用GPU进行加速,否则速度会比较慢。同时,模型的准确率也会受到硬件设备的影响。
相关问题
YOLOV8onnx推理
### 使用 ONNX 进行 YOLOv8 模型推理
为了使用 ONNX Runtime 对 YOLOv8 模型进行推理,需完成几个主要步骤:初始化模型、预处理输入数据以及解析输出结果。
#### 初始化检测模型
通过给定的 `model_path` 创建一个 ONNX 推理会话,并获取必要的输入配置参数:
```python
import onnxruntime as ort
def init_detect_model(model_path):
# 使用ONNX模型文件创建一个推理会话,并指定执行提供者
session = ort.InferenceSession(model_path, providers=['CUDAExecutionProvider', 'CPUExecutionProvider'])
# 获取模型的输入信息
model_inputs = session.get_inputs()
# 获取输入的形状,用于后续使用
input_shape = model_inputs[0].shape
# 从输入形状中提取输入宽度和高度
input_width = input_shape[2]
input_height = input_shape[3]
# 返回会话、模型输入信息、输入宽度和输入高度
return session, model_inputs, input_width, input_height[^3]
```
此函数返回了一个包含推理会话的对象以及其他一些元数据,这些对于准备输入图像至关重要。
#### 图像预处理
在将图片送入网络之前,通常需要对其进行标准化处理,比如调整大小到固定尺寸、归一化像素值等操作。这里假设已经有一个读取并转换成 NumPy 数组形式的 RGB 图片 img_raw:
```python
import cv2
import numpy as np
def preprocess_image(img_raw, target_size=(640, 640)):
"""Preprocesses an image to fit the network's requirements."""
height, width = img_raw.shape[:2]
ratio_h = target_size[1] / height
ratio_w = target_size[0] / width
min_ratio = min(ratio_h, ratio_w)
resized_img = cv2.resize(
img_raw,
(int(width * min_ratio), int(height * min_ratio)),
interpolation=cv2.INTER_LINEAR
)
padded_img = np.ones((target_size[1], target_size[0], 3)) * 114.
pad_h = max(target_size[1] - resized_img.shape[0], 0)
pad_w = max(target_size[0] - resized_img.shape[1], 0)
padded_img[pad_h//2:resized_img.shape[0]+pad_h//2,
pad_w//2:resized_img.shape[1]+pad_w//2, :] = resized_img
normalized_img = padded_img.astype(np.float32) / 255.
transposed_img = np.transpose(normalized_img, axes=[2, 0, 1])
batched_img = np.expand_dims(transposed_img, axis=0).astype('float32')
return batched_img, min_ratio, (width, height)
```
这段代码实现了对原始图像的缩放和平铺填充至目标分辨率的过程,同时也记录下了比例因子以便于后期恢复坐标位置。
#### 执行推理过程
有了上述准备工作之后就可以调用 ONNX Session 来运行预测了:
```python
session, _, input_width, input_height = init_detect_model("path/to/yolov8.onnx")
img_preprocessed, ratio, original_size = preprocess_image(cv2.imread("test.jpg"), (input_width, input_height))
outputs = session.run(None, {"images": img_preprocessed})[0][0]
```
此时得到的结果是未经解码的目标框列表,还需要进一步解释才能获得最终的人类可读格式。
#### 解析输出结果
YOLO 的输出通常是多个特征图组成的张量集合,其中包含了边界框的位置、置信度分数及类别概率等内容。具体解析方式取决于所使用的版本及其配置细节,在此仅给出一般性的指导思路:
```python
from typing import List, Tuple
class DetectionResult:
def __init__(self, box:List[float], score: float, class_id:int):
self.box = box
self.score = score
self.class_id = class_id
def post_process(outputs, conf_threshold=.25, iou_threshold=.45)->List[List[DetectionResult]]:
detections = []
for output in outputs:
boxes = output[:, :4]
scores = output[:, 4:]
best_class_indices = np.argmax(scores, axis=-1)
best_scores = scores[np.arange(len(best_class_indices)), best_class_indices]
mask = best_scores >= conf_threshold
filtered_boxes = boxes[mask]
filtered_scores = best_scores[mask]
filtered_classes = best_class_indices[mask]
indices_after_nms = nms(filtered_boxes, filtered_scores, iou_threshold=iou_threshold)
detection_results = [
DetectionResult(box.tolist(), score.item(), cls_idx.item())
for idx, (box, score, cls_idx) in enumerate(zip(filtered_boxes, filtered_scores, filtered_classes))
if idx in indices_after_nms
]
detections.append(detection_results)
return detections
def nms(boxes, scores, iou_threshold):
keep = []
order = (-scores).argsort().tolist()
while len(order)>0:
i = order.pop(0)
keep.append(i)
if not order:
break
inter_xmin = np.maximum(boxes[i, 0], boxes[order, 0])
inter_ymin = np.maximum(boxes[i, 1], boxes[order, 1])
inter_xmax = np.minimum(boxes[i, 2], boxes[order, 2])
inter_ymax = np.minimum(boxes[i, 3], boxes[order, 3])
iw = np.clip(inter_xmax - inter_xmin , a_min=0., a_max=None)
ih = np.clip(inter_ymax - inter_ymin , a_min=0., a_max=None)
inters = iw*ih
unions = ((boxes[i, 2]-boxes[i, 0])*(boxes[i, 3]-boxes[i, 1]) +
(boxes[order, 2]-boxes[order, 0])*(boxes[order, 3]-boxes[order, 1])-inters)
overlaps = inters/unions
non_overlapping_order = [idx for idx,val in enumerate(overlaps) if val<=iou_threshold]
order = list(map(lambda x: order[x],non_overlapping_order))
return set(keep)
```
以上展示了如何利用非极大抑制算法(NMS)去除冗余候选区域,并筛选出高可信度的目标实例。
YOLOv8ONNX.
### YOLOv8 ONNX 模型使用教程
#### 导入必要的库
为了加载并运行YOLOv8的ONNX模型,首先需要导入一些基本的Python库以及安装必要环境。
```bash
pip install torch torchvision onnx onnxruntime opencv-python matplotlib numpy
```
这些包提供了处理图像输入输出、执行推理所需的功能和支持[^3]。
#### 加载预训练模型
通过`ultralytics`库中的`YOLO`类来加载官方提供的预训练权重文件,并将其转换成ONNX格式。这一步骤通常只需要做一次,除非想要尝试不同的架构或自定义训练好的模型。
```python
from ultralytics import YOLO
model = YOLO('yolov8n.pt') # 或者其他版本如 yolov8s, yolov8m 等
model.export(format='onnx')
```
上述代码会保存一个名为 `yolov8n.onnx` 的文件到当前工作目录下。
#### 准备测试图片
准备一张用于检测目标物体的照片作为输入数据。这里假设有一张叫做 `test.jpg` 的照片位于项目根目录中。
```python
import cv2
image_path = 'test.jpg'
img = cv2.imread(image_path)
resized_img = cv2.resize(img, (640, 640)) # 调整大小以匹配网络输入尺寸
input_data = resized_img.astype(np.float32)[np.newaxis, :, :, :] / 255.
input_data = np.transpose(input_data, axes=[0, 3, 1, 2]) # HWC -> CHW
```
这段脚本读取了一幅JPEG格式的彩色图象,并进行了适当调整以便于后续传递给神经网络进行预测操作。
#### 进行推理运算
现在有了经过前处理后的输入样本之后就可以调用ONNX Runtime来进行实际的目标检测任务了:
```python
import onnxruntime as ort
session = ort.InferenceSession('yolov8n.onnx', providers=['CPUExecutionProvider'])
outputs = session.run(None, {'images': input_data})[0]
print(outputs.shape) # 输出形状应类似于(batch_size, num_boxes, box_info),其中box_info包含边界框坐标和其他信息
```
以上代码创建了一个新的InferenceSession实例指向之前导出的那个`.onnx`文件路径;接着传入已准备好形式的数据集完成一轮完整的推断过程,最后打印出来自最后一层节点的结果数组维度信息。
#### 解析结果
对于得到的结果矩阵来说,每一行代表一个可能存在的候选区域及其对应的类别概率分布情况。具体解析方法取决于所使用的特定实现方式和个人需求偏好,在此仅给出一种简单的可视化方案供参考:
```python
import matplotlib.pyplot as plt
def plot_bboxes(image, bboxes):
fig, ax = plt.subplots(1)
ax.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
for bbox in bboxes:
x_min, y_min, x_max, y_max = map(int, bbox[:4])
rect = patches.Rectangle((x_min, y_min), x_max-x_min, y_max-y_min,
linewidth=2, edgecolor='r', facecolor="none")
label = f"{bbox[-1]}"
ax.text(x_min, y_min - 10, s=label, color='white', verticalalignment='top',
bbox={'color': 'red', 'pad': 0})
ax.add_patch(rect)
plt.show()
```
该函数接收原始图象与由上一阶段产生的矩形列表作为参数,绘制带有标签说明的对象包围盒覆盖在其上方显示出来。
阅读全文
相关推荐
















