技术专栏
mmpose-rtmpose onnx 的后处理
RTMpose 的前后处理
RRTMPose-l onnx的
预处理
根据输入的size将图片转成相应的size[384,288,3]
def preprocess(
img: np.ndarray, input_size: Tuple[int, int] = (192, 256)
) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
"""Do preprocessing for RTMPose model inference.
Args:
img (np.ndarray): Input image in shape.
input_size (tuple): Input image size in shape (w, h).
Returns:
tuple:
- resized_img (np.ndarray): Preprocessed image.
- center (np.ndarray): Center of image.
- scale (np.ndarray): Scale of image.
"""
# get shape of image
img_shape = img.shape[:2]
bbox = np.array([0, 0, img_shape[1], img_shape[0]])
# get center and scale
center, scale = bbox_xyxy2cs(bbox, padding=1.25)
# do affine transformation
resized_img, scale = top_down_affine(input_size, scale, center, img)
# normalize image
mean = np.array([123.675, 116.28, 103.53])
std = np.array([58.395, 57.12, 57.375])
resized_img = (resized_img - mean) / std
return resized_img, center, scale
后处理功能
def postprocess(outputs: List[np.ndarray],
model_input_size: Tuple[int, int],
center: Tuple[int, int],
scale: Tuple[int, int],
simcc_split_ratio: float = 2.0
) -> Tuple[np.ndarray, np.ndarray]:
"""Postprocess for RTMPose model output.
Args:
outputs (np.ndarray): Output of RTMPose model.
model_input_size (tuple): RTMPose model Input image size.
center (tuple): Center of bbox in shape (x, y).
scale (tuple): Scale of bbox in shape (w, h).
simcc_split_ratio (float): Split ratio of simcc.
Returns:
tuple:
- keypoints (np.ndarray): Rescaled keypoints.
- scores (np.ndarray): Model predict scores.
"""
# use simcc to decode
simcc_x, simcc_y = outputs
keypoints, scores = decode(simcc_x, simcc_y, simcc_split_ratio)
# rescale keypoints
keypoints = keypoints / model_input_size * scale + center - scale / 2
return keypoints, scores
导出带有后处理的onnx
首先我们要把SIMCC解码部分用pytorch来实现。模型的直接输出是x和y两个方向上的预测向量,只需要取两个向量的最大值的index即可获得关键点的坐标。而关键点的置信度是取 max(max(x), max(y))。代码如下:
max_val_x, x_locs = torch.max(simcc_x, dim=2) # x方向上最大值和坐标
max_val_y, y_locs = torch.max(simcc_y, dim=2) # y方向上最大值和坐标
scores = torch.maximum(max_val_x, max_val_y) # 置信度取两个方向上最大值中最大的那个
keypoints = torch.stack([x_locs, y_locs], dim=-1) # 合并x, y坐标表示
keypoints = keypoints.float() / simcc_split_ratio # 最终的坐标需要除以采样倍率
完整的导出代码如下:
# Copyright (c) OpenMMLab. All rights reserved.
import argparse
import torch
import torch.nn as nn
import onnx
from onnxsim import simplify
from mmpose.apis import init_model
class RTMPoseWithDecode(nn.Module):
def __init__(self, config, checkpoint):
super().__init__()
self.detector = init_model(config, checkpoint, 'cpu')
def forward(self, x):
simcc_x, simcc_y = self.detector.forward(x, None)
max_val_x, x_locs = torch.max(simcc_x, dim=2)
max_val_y, y_locs = torch.max(simcc_y, dim=2)
scores = torch.maximum(max_val_x, max_val_y)
keypoints = torch.stack([x_locs, y_locs], dim=-1)
keypoints = keypoints.float() / self.detector.cfg.codec.simcc_split_ratio
return keypoints, scores
def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument('config', help='Config file')
parser.add_argument('checkpoint', help='Checkpoint file')
parser.add_argument('save_path', help='onnx save path')
parser.add_argument(
'--input_size',
type=int,
nargs=2,
default=[192, 256],
help='network input size')
parser.add_argument('--opset', type=int, default=11, help='opset version')
args = parser.parse_args()
return args
def export(args):
model = RTMPoseWithDecode(args.config, args.checkpoint)
dummy_image = torch.zeros((1, 3, *args.input_size[::-1]), device='cpu')
torch.onnx.export(
model,
dummy_image,
args.save_path,
input_names=['input'],
dynamic_axes={'input': {
0: 'batch'
}})
# 使用onnx simplify简化模型,当前没用
# onnx_model = onnx.load(args.save_path)
# onnx_model_simp, check = simplify(onnx_model)
# assert check, 'Simplified ONNX model could not be validated'
# onnx.save(onnx_model_simp, args.save_path)
if __name__ == '__main__':
args = parse_args()
export(args)
声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
红包
2
收藏
评论
打赏
- 分享
- 举报
评论
0个
手气红包
暂无数据
相关专栏
-
浏览量:730次2023-12-22 22:09:41
-
浏览量:1650次2023-08-07 12:05:31
-
浏览量:28680次2021-05-04 20:18:49
-
浏览量:4927次2021-06-21 11:50:25
-
浏览量:6393次2021-06-07 09:26:53
-
浏览量:15892次2021-06-07 17:47:54
-
浏览量:1916次2018-06-18 11:38:30
-
浏览量:9967次2021-06-09 12:09:57
-
浏览量:2827次2024-05-22 15:23:49
-
浏览量:630次2023-06-03 16:03:04
-
浏览量:1218次2023-12-27 15:46:55
-
浏览量:1197次2023-12-19 16:06:28
-
2024-01-03 22:05:50
-
浏览量:1723次2024-03-05 15:34:48
-
浏览量:2123次2024-01-05 14:11:13
-
浏览量:1498次2023-04-14 10:20:01
-
浏览量:1459次2024-01-05 16:46:11
-
浏览量:2622次2024-05-23 13:45:40
-
浏览量:1344次2024-02-19 17:07:05
置顶时间设置
结束时间
删除原因
-
广告/SPAM
-
恶意灌水
-
违规内容
-
文不对题
-
重复发帖
打赏作者
shui
您的支持将鼓励我继续创作!
打赏金额:
¥1
¥5
¥10
¥50
¥100
支付方式:
微信支付
打赏成功!
感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~
举报反馈
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明
审核成功
发布时间设置
发布时间:
请选择发布时间设置
是否关联周任务-专栏模块
审核失败
失败原因
请选择失败原因
备注
请输入备注