hrnet训练的pt模型结合目标检测进行关键点识别的更准确前向推理

本篇在将图像输入hrnet识别之前先进行目标检测来确定识别的位置,让识别更加精准。

本段代码设置了一个区域框BOX,让人走入区域内才开始检测,适用于考核等场景,也可以直接去掉BOX也是一样的效果。若画面背景中有多个行人,还是只取要检测的那个人,同理还是适用考核场景。
为了让检测效果更直观,在一些点位直接使用线连接起来模拟人体骨骼。

import os
import sys
import numpy as np
from mmpose.apis import init_model, inference_topdown
import cv2import torch
sys.path.append("/home/yons/train/code/yolov5")
from models.experimental import attempt_load
from utils.general import non_max_suppression, scale_boxes
from torchvision import transforms# 配置文件路径和检查点文件路径
config_file = '/home/.../pose_td-hm_hrnet-w48_8xb32-210e_PullUp-det/pose_td-hm_hrnet-w48_8xb32-210e_PullUp-det.py'
checkpoint_file = '/home/.../pose_td-hm_hrnet-w48_8xb32-210e_PullUp-det/best_coco_AP_epoch_250.pth'# 初始化姿态估计模型
pose_model = init_model(config_file, checkpoint_file, device='cuda:0')
yolo_model = attempt_load('yolov5x6.pt', device='cuda:0')  # 加载训练好的yolov5模型
pose_model.eval()
yolo_model.eval()VIDEO_PATH = 'input.mp4' 
BOX = (300, 50, 300, 450)  # 区域框的左上角坐标和宽高
OUTPUT_VIDEO_PATH = 'output.mp4'def draw_keypoints(frame, keypoints, box, det_box):# 在帧上绘制关键点# 这里假设关键点是一个 Nx2 的数组,其中 N 是关键点的数量# 并且关键点的坐标是相对于裁剪区域的x, y, w, h = boxfor kp in keypoints:kp_x, kp_y = kpx_rec1 = int(det_box[0] + x)y_rec1 = int(det_box[1] + y)x_rec2 = int(det_box[2] + x)y_rec2 = int(det_box[3] + y)cv2.rectangle(frame, (x_rec1, y_rec1), (x_rec2, y_rec2), (0, 0, 255), 2)x_cir = int(kp_x + det_box[0] + x)y_cir = int(kp_y + det_box[1] + y)cv2.circle(frame, (x_cir, y_cir), 3, (0, 255, 0), -1)lines = [(15, 13), (13, 11), (16, 14), (14, 12), (11, 12), (5, 11), (6, 12), (5, 6),(5, 7), (6, 8), (7, 9), (8, 10), (1, 2), (0, 1), (0, 2), (1, 3), (2, 4), (3, 5), (4, 6)]for line in lines:pt1 = (int(keypoints[line[0]][0] + det_box[0] + x), int(keypoints[line[0]][1] + det_box[1] + y))pt2 = (int(keypoints[line[1]][0] + det_box[0] + x), int(keypoints[line[1]][1] + det_box[1] + y))cv2.line(frame, pt1, pt2, (0, 255, 0), 2)def letterbox(im, new_shape=(640, 640), color=(114, 114, 114), auto=True, scaleFill=False, scaleup=True, stride=32):"""Resizes and pads image to new_shape with stride-multiple constraints, returns resized image, ratio, padding."""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 paddingratio = r, r  # width, height ratiosnew_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 paddingif auto:  # minimum rectangledw, dh = np.mod(dw, stride), np.mod(dh, stride)  # wh paddingelif scaleFill:  # stretchdw, dh = 0.0, 0.0new_unpad = (new_shape[1], new_shape[0])ratio = new_shape[1] / shape[1], new_shape[0] / shape[0]  # width, height ratiosdw /= 2  # divide padding into 2 sidesdh /= 2if shape[::-1] != new_unpad:  # resizeim = cv2.resize(im, new_unpad, interpolation=cv2.INTER_LINEAR)print(im.shape)top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1))left, right = int(round(dw - 0.1)), int(round(dw + 0.1))im = cv2.copyMakeBorder(im, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)  # add borderreturn im, ratio, (dw, dh)# 处理每一张图像
k = 0
if __name__ == '__main__':# 打开视频cap = cv2.VideoCapture(VIDEO_PATH)# 获取视频的一些属性fps = cap.get(cv2.CAP_PROP_FPS)width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))# 创建 VideoWriter 对象fourcc = cv2.VideoWriter_fourcc(*'mp4v')  # 或者使用 'XVID'out = cv2.VideoWriter(OUTPUT_VIDEO_PATH, fourcc, fps, (width, height))while True:# 读取一帧ret, frame = cap.read()if not ret:break# 加载帧x, y, w, h = BOXimg0 = frame[y:y+h, x:x+w, :]img_size = (1280, 1280)stride = max(int(yolo_model.stride.max()), 32)img = letterbox(img0, img_size, stride=stride, auto=True)[0]   # padded resizeimg = img.transpose((2, 0, 1))[::-1]  # HWC to CHW, BGR to RGBimg = np.ascontiguousarray(img)  # contiguous# yolo_model.warmup(imgsz=(1, 3, *img_size))  # warmupimg = torch.from_numpy(img).to('cuda:0')# img = img.half() if yolo_model.fp16 else img.float()  # uint8 to fp16/32img = img.float()img /= 255  # 0 - 255 to 0.0 - 1.0if len(img.shape) == 3:img = img[None]  # expand for batch dimwith torch.no_grad():pred = yolo_model(img)  # Inferencepred = non_max_suppression(pred, 0.25, 0.45, 0)  # NMS    0 for person# input()det_box = None# Process predictions# print(pred)for i, det in enumerate(pred):  # per image# print(det)if len(det):# Rescale boxes from img_size to img0 sizedet[:, :4] = scale_boxes(img.shape[2:], det[:, :4], img0.shape).round()max_bb = Nonefor x1, y1, x2, y2, conf, cls in reversed(det):if max_bb is None:max_bb = [x1, y1, x2, y2]else:if ((x2 - x1) * (y2 - y1)) > ((max_bb[2] - max_bb[0]) * (max_bb[3] - max_bb[3])):max_bb = [x1, y1, x2, y2]det_box = max_bbfor idx in range(len(det_box)):det_box[idx] = int(det_box[idx])x1, y1, x2, y2 = det_box# print(det_box)img_seg = img0[y1:y2, x1:x2, :]person_results = np.array([[0, 0, x2-x1, y2-y1]])# 推理得到关键点坐标pose_results = inference_topdown(pose_model, img_seg, person_results, bbox_format='xyxy')# 提取关键点坐标并检查是否检测出17个关键点keypoints = []if len(pose_results) > 0 and pose_results[0].pred_instances.keypoints.shape[1] == 17:keypoints = pose_results[0].pred_instances.keypoints[0]draw_keypoints(frame, keypoints, BOX, det_box)# 写入帧out.write(frame)# 显示帧cv2.imshow('frame', frame)if cv2.waitKey(1) & 0xFF == ord('q'):breakcap.release()out.release()cv2.destroyAllWindows()

input.mp4视频如下:

引体向上原始视频


output.mp4视频如下:

引体向上推理结果视频

大概原理是区域框内进行一系列处理后输入进yolo进行目标检测,在多个目标框内选出我们要检测的人物的目标框输入进hrnet得到关键点,关键点从目标框映射回区域框再映射回原图,得到最终结果。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《pyqt+open3d》open3d可视化界面集成到qt中

《pyqtopen3d》open3d可视化界面集成到qt中 一、效果显示二、代码三、资源下载 一、效果显示 二、代码 参考链接 main.py import sys import open3d as o3d from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget from PyQt5.QtGui import QWindow from PyQt5.Qt…

App模拟下载场景的demo

摘要 目的:提供一个稳定的下载场景,可以手动触发和定时触发下载,每次下载相同大小文件,研究下载场景的功耗影响 原理:把电脑当做服务器,手机测试App固定下载电脑存放的某个XXXMB的大文件,基于…

C语言进阶版第14课—内存函数

文章目录 1. memcpy函数的使用和模拟实现1.1 memcpy函数的使用1.2 模拟实现memcpy函数 2. memmove函数的使用和模拟实现2.1 memmove函数的使用2.2 memmove函数的模拟实现 3. memset函数4. memcmp函数 1. memcpy函数的使用和模拟实现 1.1 memcpy函数的使用 memcpy函数的原形voi…

英语音标与重弱读

英语中,比较重要的是音标。但事实上,我们对音标的学习还是比较少的,对它的理解也是比较少的。 一、音标 2个半元音 [w][j] 5个长元音:[i:] [ə:] [ɔ:] [u:] [ɑ:] 7个短元音:[i] [ə] [ɔ] [u] [] [e] [ʌ] 8个双元音…

leetcode-32. 最长有效括号

题目描述 给你一个只包含 ( 和 ) 的字符串,找出最长有效(格式正确且连续)括号 子串 的长度。 示例 1: 输入:s "(()" 输出:2 解释:最长有效括号子串是 "()"示例 2&…

压力测试指南-压力测试基础入门

压力测试基础入门 在当今快速迭代的软件开发环境中,确保应用程序在高负载情况下仍能稳定运行变得至关重要。这正是压力测试大显身手的时刻。本文将带领您深入了解压力测试的基础知识,介绍实用工具,并指导您设计、执行压力测试,最…

ffmpeg 结合 opencv 显示ps流文件

存储的ps 流文件如何显示 使用ffmpeg 和 opencv 做demo 结合opencv 和 ffmpeg 显示ps文件 // showps.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 //#include <iostream> #include <opencv2/opencv.hpp>extern "C" { #inc…

【openwrt-21.02】T750 openwrt switch划分VLAN之后网口插拔状态异常问题分析及解决方案

Openwrt版本 NAME="OpenWrt" VERSION="21.02-SNAPSHOT" ID="openwrt" ID_LIKE="lede openwrt" PRETTY_NAME="OpenWrt 21.02-SNAPSHOT" VERSION_ID="21.02-snapshot" HOME_URL="https://openwrt.org/" …

第100+26步 ChatGPT学习:概率校准 Bayesian Binning into Quantiles

基于Python 3.9版本演示 一、写在前面 最近看了一篇在Lancet子刊《eClinicalMedicine》上发表的机器学习分类的文章&#xff1a;《Development of a novel dementia risk prediction model in the general population: A large, longitudinal, population-based machine-learn…

【2】图像视频的加载和显示

文章目录 【2】图像视频的加载和显示一、代码在哪写二、创建和显示窗口&#xff08;一&#xff09;导入OpenCV的包cv2&#xff08;二&#xff09;创建窗口&#xff08;三&#xff09;更改窗口大小 & 显示窗口&#xff08;四&#xff09;等待用户输入补充&#xff1a;ord()函…

Gateway和VirtualService

在 Istio 服务网格中&#xff0c;Gateway 和 VirtualService 是两个关键的配置对象&#xff0c;它们分别用于定义入站流量的接入点和路由规则。下面详细介绍这两个配置对象的功能及其相互关系。 Gateway Gateway 是 Istio 中用于定义入站流量接入点的配置对象。它描述了外部流…

正则表达式的使用规则

1.介绍 正则表达式&#xff08;Regular Expression&#xff09;是一种强大的文本模式匹配工具&#xff0c;它使用单个字符串来描述、匹配一系列符合某个句法规则的字符串搜索模式。正则表达式可以用于文本搜索、文本替换等场景。 2.基本语法 正则表达式由普通字符&#xff0…

vue框架学习-- 父子页面 参数方法调用

一、父组件向子组件传递参数 在Vue中&#xff0c;父组件向子组件传递参数是一种非常常见的通信方式&#xff0c;这通常通过props来实现。props允许父组件向子组件传递数据&#xff0c;并且这些数据是单向的&#xff0c;即子组件不能直接修改由父组件传递的数据。但是&#xff…

【Unity踩坑】Unity更新Google Play结算库

一、问题描述&#xff1a; 在Google Play上提交了app bundle后&#xff0c;提示如下错误。 我使用的是Unity 2022.01.20f1&#xff0c;看来用的Play结算库版本是4.0 查了一下文档&#xff0c;Google Play结算库的维护周期是两年。现在需要更新到至少6.0。 二、更新过程 1. 下…

【视频目标分割-2024CVPR】Putting the Object Back into Video Object Segmentation

Cutie 系列文章目录1 摘要2 引言2.1背景和难点2.2 解决方案2.3 成果 3 相关方法3.1 基于记忆的VOS3.2对象级推理3.3 自动视频分割 4 工作方法4.1 overview4.2 对象变换器4.2.1 overview4.2.2 Foreground-Background Masked Attention4.2.3 Positional Embeddings 4.3 Object Me…

cpp,git,unity学习

c#中的? 1. 空值类型&#xff08;Nullable Types&#xff09; ? 可以用于值类型&#xff08;例如 int、bool 等&#xff09;&#xff0c;使它们可以接受 null。通常&#xff0c;值类型不能为 null&#xff0c;但是通过 ? 可以表示它们是可空的。 int? number null; // …

使用 SSH 连接 Docker 服务器:IntelliJ IDEA 高效配置与操作指南

使用 SSH 连接 Docker 服务器&#xff1a;IntelliJ IDEA 高效配置与操作指南 本文详细介绍了如何在 2375 端口未开放的情况下&#xff0c;通过 SSH 连接 Docker 服务器并在 Idea 中进行开发。通过修改用户权限、生成密钥对以及配置 SSH 访问&#xff0c;用户可以安全地远程操作…

NASA数据集:ATLAS/ICESat-2 L3B 每日和每月网格化海冰自由面高度,第 4 版

目录 简介 摘要 代码 引用 网址推荐 0代码在线构建地图应用 机器学习 ATLAS/ICESat-2 L3B Daily and Monthly Gridded Sea Ice Freeboard, Version 4 简介 ATLAS/ICESat-2 L3B Daily and Monthly Gridded Sea Ice Freeboard, Version 4数据是由NASA的ATLAS&#xff08…

Ubuntu 系统崩了,如何把数据拷下来

问题描述&#xff1a; Linux系统中安装输入法后&#xff0c;重启后&#xff0c;导致系统无法进入&#xff0c;进入 recovery mode下的resume 也启动不了&#xff0c;所以决定将需要的东西复制到U盘 解决方案&#xff1a; 1.重启ubuntu&#xff0c;随即点按Esc进入grub菜单&am…

OpenStack Yoga版安装笔记(十五)Horizon安装

1、官方文档 OpenStack Installation Guidehttps://docs.openstack.org/install-guide/ 本次安装是在Ubuntu 22.04上进行&#xff0c;基本按照OpenStack Installation Guide顺序执行&#xff0c;主要内容包括&#xff1a; 环境安装 &#xff08;已完成&#xff09;OpenStack…