yolov8-pose 推理流程

目录

一、关键点预测

二、图像预处理

二、推理

三、后处理与可视化

3.1、后处理

3.2、特征点可视化

四、完整pytorch代码


yolov8-pose tensorrt

一、关键点预测

注:本篇只是阐述推理流程,tensorrt实现后续跟进。

yolov8-pose的tensorrt部署代码稍后更新,还是在仓库:GitHub - FeiYull/TensorRT-Alpha: 🔥🔥🔥TensorRT-Alpha supports YOLOv8、YOLOv7、YOLOv6、YOLOv5、YOLOv4、v3、YOLOX、YOLOR...🚀🚀🚀CUDA IS ALL YOU NEED.🍎🍎🍎It also supports end2end CUDA C acceleration and multi-batch inference.

也可以关注:TensorRT系列教程-CSDN博客

以下是官方预测代码:

from ultralytics import YOLO
model = YOLO(model='yolov8n-pose.pt')
model.predict(source="d:/Data/1.jpg", save=True)

推理过程无非是:图像预处理 -> 推理 -> 后处理 + 可视化,这三个关键步骤在文件大概247行:D:\CodePython\ultralytics\ultralytics\engine\predictor.py,代码如下:

# Preprocess
with profilers[0]:
	im = self.preprocess(im0s) # 图像预处理

# Inference
with profilers[1]:
	preds = self.inference(im, *args, **kwargs) # 推理

# Postprocess
with profilers[2]:
	self.results = self.postprocess(preds, im, im0s) # 后处理

二、图像预处理

通过debug,进入上述self.preprocess函数,看到代码实现如下。处理流程大概是:padding(满足矩形推理),图像通道转换,即:BGR装RGB,检查图像数据是否连续,存储顺序有HWC转为CHW,然后归一化。需要注意,原始pytorch框架图像预处理的时候,会将图像缩放+padding为HxW的图像,其中H、W为32倍数,而导出tensorrt的时候,为了高效推理,H、W 固定为640x640。

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)

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

二、推理

图像预处理之后,直接推理就行了,这里是基于pytorch推理。

def inference(self, im, *args, **kwargs):
	visualize = increment_path(self.save_dir / Path(self.batch[0][0]).stem,
							   mkdir=True) if self.args.visualize and (not self.source_type.tensor) else False
	return self.model(im, augment=self.args.augment, visualize=visualize)

三、后处理与可视化

3.1、后处理

网络推理输出特征图维度为:56x8400,其中:

  • 8400表示候选目标数量,
  • 56 = xywhc + points * 17,points的长度为3,分别为:xyc,即:特征点的坐标和置信度

尽管推理输出特征图中,每一行既有bbox,还有keypoints,但是NMS的时候,依然只作用于bbox,下面代码作了NMS之后,将筛选之后的目标中bbox、keypoints进行坐标值缩放(缩放到原图尺寸坐标系)。

def postprocess(self, preds, img, orig_imgs):
	"""Return detection results for a given input image or list of images."""
	preds = ops.non_max_suppression(preds,
									self.args.conf,
									self.args.iou,
									agnostic=self.args.agnostic_nms,
									max_det=self.args.max_det,
									classes=self.args.classes,
									nc=len(self.model.names))

	results = []
	for i, pred in enumerate(preds):
		orig_img = orig_imgs[i] if isinstance(orig_imgs, list) else orig_imgs
		shape = orig_img.shape
		pred[:, :4] = ops.scale_boxes(img.shape[2:], pred[:, :4], shape).round()
		pred_kpts = pred[:, 6:].view(len(pred), *self.model.kpt_shape) if len(pred) else pred[:, 6:]
		pred_kpts = ops.scale_coords(img.shape[2:], pred_kpts, shape)
		path = self.batch[0]
		img_path = path[i] if isinstance(path, list) else path
		results.append(
			Results(orig_img=orig_img,
					path=img_path,
					names=self.model.names,
					boxes=pred[:, :6],
					keypoints=pred_kpts))
	return results

3.2、特征点可视化

bbox可视化没什么好说的,说下17个特征点的可视化,在文件:D:\CodePython\ultralytics_fire_smoke\ultralytics\utils\plotting.py171行,绘制特征点需要注意,需要按照预定义的顺序绘制,其中特征点置信度需要足够大。

def kpts(self, kpts, shape=(640, 640), radius=5, kpt_line=True):
	"""
	Plot keypoints on the image.

	Args:
		kpts (tensor): Predicted keypoints with shape [17, 3]. Each keypoint has (x, y, confidence).
		shape (tuple): Image shape as a tuple (h, w), where h is the height and w is the width.
		radius (int, optional): Radius of the drawn keypoints. Default is 5.
		kpt_line (bool, optional): If True, the function will draw lines connecting keypoints
								   for human pose. Default is True.

	Note: `kpt_line=True` currently only supports human pose plotting.
	"""
	if self.pil:
		# Convert to numpy first
		self.im = np.asarray(self.im).copy()
	nkpt, ndim = kpts.shape
	is_pose = nkpt == 17 and ndim == 3
	kpt_line &= is_pose  # `kpt_line=True` for now only supports human pose plotting
	# 绘制特征点
	for i, k in enumerate(kpts):
		color_k = [int(x) for x in self.kpt_color[i]] if is_pose else colors(i)
		x_coord, y_coord = k[0], k[1]
		if x_coord % shape[1] != 0 and y_coord % shape[0] != 0:
			if len(k) == 3:
				conf = k[2]
				if conf < 0.5:
					continue
			cv2.circle(self.im, (int(x_coord), int(y_coord)), radius, color_k, -1, lineType=cv2.LINE_AA)
	# 绘制线段
	if kpt_line:
		ndim = kpts.shape[-1]
		for i, sk in enumerate(self.skeleton):
			pos1 = (int(kpts[(sk[0] - 1), 0]), int(kpts[(sk[0] - 1), 1]))
			pos2 = (int(kpts[(sk[1] - 1), 0]), int(kpts[(sk[1] - 1), 1]))
			if ndim == 3:
				conf1 = kpts[(sk[0] - 1), 2]
				conf2 = kpts[(sk[1] - 1), 2]
				if conf1 < 0.5 or conf2 < 0.5:
					continue
			if pos1[0] % shape[1] == 0 or pos1[1] % shape[0] == 0 or pos1[0] < 0 or pos1[1] < 0:
				continue
			if pos2[0] % shape[1] == 0 or pos2[1] % shape[0] == 0 or pos2[0] < 0 or pos2[1] < 0:
				continue
			cv2.line(self.im, pos1, pos2, [int(x) for x in self.limb_color[i]], thickness=2, lineType=cv2.LINE_AA)
	if self.pil:
		# Convert im back to PIL and update draw
		self.fromarray(self.im)

这里给一张特征点顺序图:

四、完整pytorch代码

将以上流程合并起来,并加以修改,完整代码如下:

import torch
import cv2 as cv
import numpy as np
from ultralytics.data.augment import LetterBox
from ultralytics.utils import ops
from ultralytics.engine.results import Results
import copy

# path = 'd:/Data/1.jpg'
path = 'd:/Data/6406402.jpg'
device = 'cuda:0'
conf = 0.25
iou = 0.7

# preprocess
im = cv.imread(path)
# letterbox
im = [im]
orig_imgs = copy.deepcopy(im)
im = [LetterBox([640, 640], auto=True, stride=32)(image=x) for x in im]
im = im[0][None] # im = np.stack(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)
img = im.to(device)
img = img.float()
img /= 255
# load model pt
ckpt = torch.load('yolov8n-pose.pt', map_location='cpu')
model = ckpt['model'].to(device).float()  # FP32 model
model.eval()

# inference
preds = model(img)
prediction = ops.non_max_suppression(preds, conf, iou, agnostic=False, max_det=300, classes=None, nc=len(model.names))

results = []
for i, pred in enumerate(prediction):
    orig_img = orig_imgs[i] if isinstance(orig_imgs, list) else orig_imgs
    shape = orig_img.shape
    pred[:, :4] = ops.scale_boxes(img.shape[2:], pred[:, :4], shape).round()
    pred_kpts = pred[:, 6:].view(len(pred), *model.kpt_shape) if len(pred) else pred[:, 6:]
    pred_kpts = ops.scale_coords(img.shape[2:], pred_kpts, shape)
   
    img_path = path
    results.append(
        Results(orig_img=orig_img,
                path=img_path,
                names=model.names,
                boxes=pred[:, :6],
                keypoints=pred_kpts))

# show
plot_args = {'line_width': None,'boxes': True,'conf': True, 'labels': True}
plot_args['im_gpu'] = img[0]
result = results[0]
plotted_img = result.plot(**plot_args)
cv.imshow('plotted_img', plotted_img)
cv.waitKey(0)
cv.destroyAllWindows()
print()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/194255.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

FPGA模块——DA转换模块(AD9708类)

FPGA模块——DA转换模块&#xff08;AD9708类&#xff09; AD9708/3PD9708代码 AD9708/3PD9708 由于电路接了反相器&#xff0c;所以对应就不一样了。 电路图&#xff1a; 代码 在ROM中存入要输出的波形数据&#xff1a; 用软件生成各个对应的点。 给DA转换器一个时钟&…

智能优化算法应用:基于樽海鞘群算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于樽海鞘群算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于樽海鞘群算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.樽海鞘群算法4.实验参数设定5.算法结果6.参考…

Junos webauth_operation.php 文件上传漏洞复现(CVE-2023-36844)

0x01 产品简介 Junos 是 Juniper Networks 生产的一款可靠的高性能网络操作系统。 0x02 漏洞概述 Junos webauth_operation.php接口处存在文件上传漏洞&#xff0c;未经身份认证的攻击者可利用 Junos 操作系统的 J-Web 服务 /webauth_operation.php 路由上传 php webshell&…

C语言第三十四弹--矩形逆置

C语言实现矩阵逆置 逆置结果如图 思路&#xff1a;通过观察逆置结果&#xff0c;首先发现行数和列数都发生了调换。其次观察逆置前后数字对应的下标&#xff0c;逆置前数字对应下标为:[x][j] 逆置后数字对应下标为&#xff1a;[y][x]。综上&#xff0c;就可以实现矩阵逆置。 …

人才“塔尖城市”,长沙如何炼成?

文 | 智能相对论 作者 | 范柔丝 长沙在人才吸引力上&#xff0c;近几年来可谓风头无二。 自2022年长沙人才政策“升级版45条”实施以来&#xff0c;越来越多的人才因为长沙真金白银的政策与城市发展机遇&#xff0c;奔赴长沙安居乐业。 随着2023互联网岳麓峰会吹响长沙全力…

用函数初始化数组

将数组全部初始化为相同值 对于一般情况 一般是用函数&#xff0c;传什么数就初始化为什么数 #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> void init(int arr[], int len, int num) {int i;for (i 0; i < len; i){arr[i] num;} } int main() {int arr[…

网页设计--第5次课后作业

1、快速学习JavaScript的基本知识第1-10章 JavaScript入门 - 绿叶学习网 2、使用所学的知识完成以下练习。需求如下3个&#xff1a; 1&#xff09;点亮灯泡 2&#xff09;将所有的div标签的标签体内容后面加上&#xff1a; very good 3&#xff09;使所有的复选框呈现被选…

OpenHarmony模块化编译

一、环境配置 OpenHarmony版本&#xff1a;OpenHarmony 4.0 Release 编译环境&#xff1a;WSL2 Ubuntu 18.04 平台设备&#xff1a;RK3568 二、配置hb OpenHarmony 代码构建有build.sh和hb两种方式: #方式一、build.sh ./build.sh --product-name rk3568 --ccache#方式二、…

人工智能关键技术决定机器人产业的前途

人工智能&#xff08;Artificial Intelligence&#xff0c;AI&#xff09;是指让计算机或机器具有类似于人类的智能和学习能力的技术。人工智能技术与机器人技术的结合将改变传统的机器人行业格局&#xff0c;就像智能手机对传统手机的颠覆一样。本文从人工智能技术的发展趋势、…

QT基础实践之简易计算器

文章目录 简易计算器源码分享演示图第一步 界面设计第二步 设置槽第三步 计算功能实现 简易计算器 源码分享 链接&#xff1a;https://pan.baidu.com/s/1Jn5fJLYOZUq77eNJ916Kig 提取码&#xff1a;qwer 演示图 第一步 界面设计 这里直接用了ui界面&#xff0c;如果想要自己…

ITIL4中自动化测试和质量保障的重要性

点击进入IT管理资料库 在迅速变革的科技世界中&#xff0c;IT服务管理的关键要素之一是自动化测试和质量保障。随着ITIL 4的崭新框架崛起&#xff0c;这两者不仅成为服务管理的重要组成部分&#xff0c;更是组织提高服务质量和效率的不可或缺的利器。 自动化测试和质量保障如何…

MySQL备份与恢复(重点)

MySQL备份与恢复&#xff08;重点&#xff09; 一、用户管理与权限管理 ☆ 用户管理 1、创建MySQL用户 注意&#xff1a;MySQL中不能单纯通过用户名来说明用户&#xff0c;必须要加上主机。如jack10.1.1.1 基本语法&#xff1a; mysql> create user 用户名被允许连接的主…

DM8数据库版本升级

DM数据库版本升级说明 DM数据库的版本一直在不断的的迭代。 对于DM 的数据库版本&#xff0c;分大版本和小版本。 1)大版本&#xff1a;指DM6&#xff0c;DM7&#xff0c;DM8 这种。2)小版本&#xff1a;指同一个大版本子版本的变化&#xff0c;比如DM8的&#xff1a;8.1.0.1…

Android修行手册 - 使用ViewPager2实现画廊效果

Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列ChatGPT和AIGC &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分…

什么是Cyclomatic Complexity循环复杂度

Cyclomatic Complexity&#xff0c;可以翻译成 循环复杂度圈复杂度圈复杂性回路复杂性 循环复杂度是软件工程中的一个定量度量&#xff0c;表示程序或函数的复杂性。它衡量程序源代码中线性独立路径或分支的数量。如果一个函数的循环复杂度太高了&#xff0c;就需要进行重构。…

sqli-labs靶场详解less-24(二次注入)

less-24 对于一个像我一样的小白来说这关就像php代码审计 一开始进行判断注入点的时候怎么都找不到一点思路都没有 只能搜教程 说是二次注入 从来没遇见的题型 于是从代码审计开始 先说一下什么叫二次注入 二次注入 二次注入是指通过SQL语句存储到数据库的用户输入被读取后再次…

STM32_9(USART串口)

一、串口通信 串口是一种应用十分广泛的通讯接口&#xff0c;串口成本低、容易使用、通信线路简单&#xff0c;可实现两个设备的互相通信单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信&#xff0c;极大地扩展了单片机的应用范围&#xff0…

西南科技大学(数据结构A)期末自测练习一

一、填空题(每空0.5分,共5分) 1、数据结构是指( A )。 A、数据元素的组织形式 B、数据类型 C、数据存储结构 D、数据定义 2、数据结构被形式地定义为(D,R),其中D是( B )的有限集合,R是D上( D )的有限集合。 (1)A.算法B.数据元素C.数据操作D.逻辑结构 (2)A.操作B.…

滴滴昨晚崩了,看这波还敢不敢降本增效?

起因 截至 2023 年 11 月 27 日晚&#xff0c;中国最大的网约车服务平台滴滴打车遭遇系统崩溃&#xff0c;继阿里云控制台故障之后&#xff0c;再次引发热议。这一事件迅速攀升至热搜榜首&#xff0c;引起广泛关注。 今晚约 10 点&#xff0c;滴滴打车遭遇大范围技术故障。用户…

小程序----使用图表显示数据--canvas

需求&#xff1a;在小程序上实现数据可视化 思路&#xff1a;本来想用的是echarts或者相关的可视化插件&#xff0c;但因为用的是vue3&#xff0c;大多数插件不支持&#xff0c;所以用了echarts&#xff0c;但最后打包的时候说包太大超过2M无法上传&#xff0c;百度了一下&…