關鍵點檢測--使用YOLOv8對Leeds Sports Pose(LSP)關鍵點檢測

目錄

  • 1. Leeds Sports Pose數據集下載
  • 2. 數據集處理
    • 2.1 獲取標簽
    • 2.2 將圖像文件和標簽文件處理成YOLO能使用的格式
  • 3. 用YOLOv8進行訓練
    • 3.1 訓練
    • 3.2 預測


1. Leeds Sports Pose數據集下載

從kaggle官網下載這個數據集,地址為link,下載好的數據集文件如下:
| |——archive
|——images 這個文件夾中放了2000張運動圖像
|——visualized 這個文件夾放的是帶關鍵點的圖像
|——joints.mat 存放的是關鍵點標簽
|——README.txt 存放對數據集的介紹

2. 數據集處理

2.1 獲取標簽

原圖像的關鍵點標簽以joints.mat格式存放,用python腳本對其進行解析,這里注意每張圖像的大小不同,因此不同圖像的寬高不同要注意。 解析代碼如下,注意更換里面的圖像路徑。

import os
import cv2
import numpy as np
import scipy.io as sio# 加載 joints.mat 文件
mat_path = "joints.mat"
data = sio.loadmat(mat_path)# 查看所有鍵
print(data.keys())# 獲取 joints 數據 (假設其結構為 (3, num_keypoints, num_samples))
joints = data['joints']# 路徑配置
output_dir = r"LSP\labels"
image_dir = r"LSP\images"  # 圖像目錄路徑
os.makedirs(output_dir, exist_ok=True)# 解析 joints 數據
num_samples = joints.shape[2]for idx in range(num_samples):# 構建圖像路徑image_path = os.path.join(image_dir, f"im{idx + 1:04d}.jpg")# 檢查圖像是否存在if not os.path.exists(image_path):print(f"圖像 {image_path} 不存在,跳過該樣本。")continue# 獲取當前樣本的關鍵點數據keypoints = joints[:, :, idx]x_coords = keypoints[0, :]y_coords = keypoints[1, :]visibility = keypoints[2, :]# 讀取圖像獲取實際尺寸img = cv2.imread(image_path)if img is None:print(f"無法讀取圖像 {image_path},跳過該樣本。")continueimg_height, img_width = img.shape[:2]# 歸一化關鍵點坐標x_coords /= img_widthy_coords /= img_height# 計算邊界框x_min, x_max = np.min(x_coords), np.max(x_coords)y_min, y_max = np.min(y_coords), np.max(y_coords)bbox_width = x_max - x_minbbox_height = y_max - y_minx_center = x_min + bbox_width / 2y_center = y_min + bbox_height / 2# 構建標簽行:class_id x_center y_center width height x1 y1 x2 y2 ...label = f"0 {x_center:.6f} {y_center:.6f} {bbox_width:.6f} {bbox_height:.6f} "label += " ".join([f"{x:.6f} {y:.6f}" for x, y in zip(x_coords, y_coords)])label += "\n"# 保存標簽文件label_path = os.path.join(output_dir, f"im{idx + 1:04d}.txt")with open(label_path, "w") as f:f.write(label)print(f"所有關鍵點數據已轉換為 YOLOv8 格式,保存至 {output_dir}")

獲取的關鍵點標簽如下圖:
在這里插入圖片描述
對應的圖像如下圖:
在這里插入圖片描述

2.2 將圖像文件和標簽文件處理成YOLO能使用的格式

我是按照8比2將數據集分成訓練集和測試集,劃分代碼如下:

import os
import random
import shutil# 數據集路徑images_path = r"LSP\images"
labels_path = r"LSP\labels"# 輸出路徑
train_img_dir = os.path.join(images_path, "train")
val_img_dir = os.path.join(images_path, "val")
train_lbl_dir = os.path.join(labels_path, "train")
val_lbl_dir = os.path.join(labels_path, "val")# 創建輸出文件夾
os.makedirs(train_img_dir, exist_ok=True)
os.makedirs(val_img_dir, exist_ok=True)
os.makedirs(train_lbl_dir, exist_ok=True)
os.makedirs(val_lbl_dir, exist_ok=True)# 獲取所有圖像文件名(不帶擴展名)
image_files = sorted([f.split('.')[0] for f in os.listdir(images_path) if f.endswith('.jpg')])# 設置劃分比例
train_ratio = 0.8
val_ratio = 0.2# 隨機打亂文件列表
random.shuffle(image_files)# 劃分數據集
train_count = int(len(image_files) * train_ratio)
train_files = image_files[:train_count]
val_files = image_files[train_count:]def move_files(file_list, img_dir, lbl_dir):for filename in file_list:img_src = os.path.join(images_path, f"{filename}.jpg")lbl_src = os.path.join(labels_path, f"{filename}.txt")img_dst = os.path.join(img_dir, f"{filename}.jpg")lbl_dst = os.path.join(lbl_dir, f"{filename}.txt")if os.path.exists(img_src) and os.path.exists(lbl_src):shutil.move(img_src, img_dst)shutil.move(lbl_src, lbl_dst)# 移動文件
move_files(train_files, train_img_dir, train_lbl_dir)
move_files(val_files, val_img_dir, val_lbl_dir)print(f"數據集劃分完成:\n  訓練集:{len(train_files)} 張\n  驗證集:{len(val_files)} 張")

劃分后的文件格式圖:
| | |——LSP 文件名
| |——images
|——train 訓練數據
|——val 測試數據
| |——val
|——train 訓練標簽
|——val 測試標簽
在這里插入圖片描述
數據集的yaml格式如下:
在這里插入圖片描述

3. 用YOLOv8進行訓練

3.1 訓練

下面是我進行訓練的代碼

# Ultralytics YOLO 🚀, AGPL-3.0 licensefrom copy import copyfrom ultralytics.models import yolo
from ultralytics.nn.tasks import PoseModel
from ultralytics.utils import DEFAULT_CFG, LOGGER
from ultralytics.utils.plotting import plot_images, plot_resultsclass PoseTrainer(yolo.detect.DetectionTrainer):"""A class extending the DetectionTrainer class for training based on a pose model.Example:```pythonfrom ultralytics.models.yolo.pose import PoseTrainerargs = dict(model='yolov8n-pose.pt', data='coco8-pose.yaml', epochs=3)trainer = PoseTrainer(overrides=args)trainer.train()```"""def __init__(self, cfg=DEFAULT_CFG, overrides=None, _callbacks=None):"""Initialize a PoseTrainer object with specified configurations and overrides."""if overrides is None:overrides = {}overrides["task"] = "pose"super().__init__(cfg, overrides, _callbacks)if isinstance(self.args.device, str) and self.args.device.lower() == "mps":LOGGER.warning("WARNING ?? Apple MPS known Pose bug. Recommend 'device=cpu' for Pose models. ""See https://github.com/ultralytics/ultralytics/issues/4031.")def get_model(self, cfg=None, weights=None, verbose=True):"""Get pose estimation model with specified configuration and weights."""model = PoseModel(cfg, ch=3, nc=self.data["nc"], data_kpt_shape=self.data["kpt_shape"], verbose=verbose)if weights:model.load(weights)return modeldef set_model_attributes(self):"""Sets keypoints shape attribute of PoseModel."""super().set_model_attributes()self.model.kpt_shape = self.data["kpt_shape"]def get_validator(self):"""Returns an instance of the PoseValidator class for validation."""self.loss_names = "box_loss", "pose_loss", "kobj_loss", "cls_loss", "dfl_loss"return yolo.pose.PoseValidator(self.test_loader, save_dir=self.save_dir, args=copy(self.args), _callbacks=self.callbacks)def plot_training_samples(self, batch, ni):"""Plot a batch of training samples with annotated class labels, bounding boxes, and keypoints."""images = batch["img"]kpts = batch["keypoints"]cls = batch["cls"].squeeze(-1)bboxes = batch["bboxes"]paths = batch["im_file"]batch_idx = batch["batch_idx"]plot_images(images,batch_idx,cls,bboxes,kpts=kpts,paths=paths,fname=self.save_dir / f"train_batch{ni}.jpg",on_plot=self.on_plot,)def plot_metrics(self):"""Plots training/val metrics."""plot_results(file=self.csv, pose=True, on_plot=self.on_plot)  # save results.pngif __name__ == "__main__":args = dict(model=r'E:\postgraduate\bolt_lossen_project\ultralytics-8.1.0\yolov8n-pose.pt', epochs= 100, mode='train')trains = PoseTrainer(overrides=args)trains.train()#predictor.predict_cli()

3.2 預測

預測代碼:

# Ultralytics YOLO 🚀, AGPL-3.0 licensefrom ultralytics.engine.results import Results
from ultralytics.models.yolo.detect.predict import DetectionPredictor
from ultralytics.utils import DEFAULT_CFG, LOGGER, ops
import cv2class PosePredictor(DetectionPredictor):"""A class extending the DetectionPredictor class for prediction based on a pose model.Example:```pythonfrom ultralytics.utils import ASSETSfrom ultralytics.models.yolo.pose import PosePredictorargs = dict(model='yolov8n-pose.pt', source=ASSETS)predictor = PosePredictor(overrides=args)predictor.predict_cli()```"""def __init__(self, cfg=DEFAULT_CFG, overrides=None, _callbacks=None):"""Initializes PosePredictor, sets task to 'pose' and logs a warning for using 'mps' as device."""super().__init__(cfg, overrides, _callbacks)self.args.task = "pose"if isinstance(self.args.device, str) and self.args.device.lower() == "mps":LOGGER.warning("WARNING ?? Apple MPS known Pose bug. Recommend 'device=cpu' for Pose models. ""See https://github.com/ultralytics/ultralytics/issues/4031.")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),)if not isinstance(orig_imgs, list):  # input images are a torch.Tensor, not a listorig_imgs = ops.convert_torch2numpy_batch(orig_imgs)results = []for i, pred in enumerate(preds):orig_img = orig_imgs[i]pred[:, :4] = ops.scale_boxes(img.shape[2:], pred[:, :4], orig_img.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, orig_img.shape)img_path = self.batch[0][i]results.append(Results(orig_img, path=img_path, names=self.model.names, boxes=pred[:, :6], keypoints=pred_kpts))return resultsif __name__ == "__main__":img = r'E:\postgraduate\bolt_lossen_project\ultralytics-8.1.0\archive\LSP\images\train\im0089.jpg'args = dict(model=r'E:\postgraduate\bolt_lossen_project\ultralytics-8.1.0\runs\pose\train\weights\best.pt', source=img, task = 'pose')predictor = PosePredictor(overrides=args)predictor.predict_cli()

預測結果圖:
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/79253.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/79253.shtml
英文地址,請注明出處:http://en.pswp.cn/web/79253.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

20250508在WIN10下使用移遠的4G模塊EC200A-CN直接上網

1、在WIN10/11下安裝驅動程序:Quectel_Windows_USB_DriverA_Customer_V1.1.13.zip 2、使用移遠的專用串口工具:QCOM_V1.8.2.7z QCOM_V1.8.2_win64.exe 3、配置串口UART42/COM42【移遠會自動生成連續三個串口,最小的那一個】 AT命令&#xf…

第J7周:ResNeXt解析

🍨 本文為🔗365天深度學習訓練營 中的學習記錄博客🍖 原作者:K同學啊 目標 具體實現 (一)環境 語言環境:Python 3.10 編 譯 器: PyCharm 框 架: Tensorflow (二)具體…

C++之類和對象:初始化列表,static成員,友元,const成員 ……

目錄 const成員函數: 前置和后置重載: 取地址及const取地址操作符重載: 初始化列表: explicit關鍵字: static成員: 友元: 友元函數: 友元類: 內部類&#xff1a…

uni-app 中的條件編譯與跨端兼容

uni-app 為了實現一套代碼編譯到多個平臺(包括小程序,App,H5 等),引入了條件編譯機制。 通過條件編譯,我們可以針對不同的平臺編寫特定的代碼,從而實現跨端兼容。 一、條件編譯的作用 平臺差異…

Linux平臺下SSH 協議克隆Github遠程倉庫并配置密鑰

目錄 注意:先提前配置好SSH密鑰,然后再git clone 1. 檢查現有 SSH 密鑰 2. 生成新的 SSH 密鑰 3. 將 SSH 密鑰添加到 ssh-agent 4. 將公鑰添加到 GitHub 5. 測試 SSH 連接 6. 配置 Git 使用 SSH 注意:先提前配置好SSH密鑰,然…

[C++] 大數減/除法

目錄 高精度博客 - 前兩講高精度減法高精度除法高精度系列函數完整版 高精度博客 - 前兩講 講次名稱鏈接高精加法[C] 高精度加法(作用 模板 例題)高精乘法[C] 高精度乘法 高精度減法 void subBIG(int x[], int y[], int z[]){z[0] max(x[0], y[0]);for(int i 1; i < …

視頻添加字幕腳本分享

腳本簡介 這是一個給視頻添加字幕的腳本&#xff0c;可以方便的在指定的位置給視頻添加不同大小、字體、顏色的文本字幕&#xff0c;添加方式可以直接修改腳本中的文本信息&#xff0c;或者可以提前編輯好.srt字幕文件。腳本執行環境&#xff1a;windowsmingwffmpeg。本方法僅…

ubuntu nobel + qt5.15.2 設置qss語法識別正確

問題展示 解決步驟 首選項里面的高亮怎么編輯選擇都沒用。如果已經有generic-highlighter和css.xml&#xff0c;直接修改css.xml文件最直接&#xff01; 在generic-highlighter目錄下找到css.xml文件&#xff0c;位置是&#xff1a;/opt/Qt/Tools/QtCreator/share/qtcreator/…

洛谷P7528 [USACO21OPEN] Portals G

P7528 [USACO21OPEN] Portals G luogu題目傳送門 題目描述 Bessie 位于一個由 N N N 個編號為 1 … N 1\dots N 1…N 的結點以及 2 N 2N 2N 個編號為 1 ? 2 N 1\cdots 2N 1?2N 的傳送門所組成的網絡中。每個傳送門連接兩個不同的結點 u u u 和 v v v&#xff08; u …

C++STL——priority_queue

優先隊列 前言優先隊列仿函數頭文件 前言 本篇主要講解優先隊列及其底層實現。 優先隊列 優先隊列的本質就是個堆&#xff0c;其與queue一樣&#xff0c;都是容器適配器&#xff0c;不過優先隊列是默認為vector實現的。priority_queue的接口優先隊列默認為大根堆。 仿函數 …

助力你的Neovim!輕松管理開發工具的魔法包管理器來了!

在現代編程環境中&#xff0c;Neovim 已經成為許多開發者的編輯器選擇。而針對 Neovim 的各種插件與功能擴展&#xff0c;則是提升開發體驗的重要手段。今天我們要介紹的就是一個強大而便捷的開源項目——mason.nvim&#xff0c;一個旨在簡化和優化 Neovim 使用體驗的便攜式包管…

Java-Lambda 表達式

Lambda 表達式是 Java 8 引入的一項重要特性&#xff0c;它提供了一種簡潔的方式來表示匿名函數。Lambda 表達式主要用于簡化函數式接口的實現&#xff0c;使代碼更加簡潔和易讀。以下是關于 Lambda 表達式的詳細闡述&#xff1a; 1. Lambda 表達式的基本語法 Lambda 表達式的…

05 mysql之DDL

一、SQL的四個分類 我們通常可以將 SQL 分為四類&#xff0c;分別是&#xff1a; DDL&#xff08;數據定義語言&#xff09;、DML&#xff08;數據操作語言&#xff09;、 DCL&#xff08;數據控制語言&#xff09;和 TCL&#xff08;事務控制語言&#xff09;。 DDL 用于創建…

1 2 3 4 5順序插入,形成一個紅黑樹

紅黑樹的特性與優點 紅黑樹是一種自平衡的二叉搜索樹&#xff0c;通過額外的顏色標記和平衡性約束&#xff0c;確保樹的高度始終保持在 O(log n)。其核心特性如下&#xff1a; 每個節點要么是紅色&#xff0c;要么是黑色。根節點和葉子節點&#xff08;NIL節點&#xff09;是…

微服務6大拆分原則

微服務6大拆分原則 微服務拆分是指將一個大型應用程序拆分成獨立服務的過程&#xff0c;在微服務拆分時&#xff0c;需要考慮以下6大微服務拆分原則 一、單一職責原則 微服務單一職責原則&#xff0c;是指每個微服務應該專注于解決一個明確定義的業務領域或功能&#xff0c;…

java: Compilation failed: internal java compiler error 報錯解決方案

java: Compilation failed: internal java compiler error 報錯解決方案 如下圖所示&#xff1a; 在編譯的時候提示 java: Compilation failed: internal java compiler error 原因&#xff1a;內部 java 編譯錯誤,一般是編譯版本不匹配。 問題解決 項目中有以下設置JDK版本…

介紹一下ReentrantLock 跟 Synchronized 區別

ReentrantLock 跟 Synchronized 區別 面試回答&#xff1a; 相同點&#xff1a; synchronized 和 ReentrantLock 都是用來保護資源線程安全的。 都可以保證可見性。 synchronized 和 ReentrantLock 都擁有可重入的特點。 從基本語義和概念上說 synchronized: Java 內建的…

第7次課 棧A

課堂學習 棧&#xff08;stack&#xff09; 是一種遵循先入后出邏輯的線性數據結構。 我們可以將棧類比為桌面上的一摞盤子&#xff0c;如果想取出底部的盤子&#xff0c;則需要先將上面的盤子依次移走。我們將盤子替換為各種類型的元素&#xff08;如整數、字符、對象等&…

ts裝飾器

TypeScript 裝飾器是一種特殊類型的聲明&#xff0c;能夠被附加到類聲明、方法、訪問符、屬性或參數上。它本質上是一個函數&#xff0c;會在運行時被調用&#xff0c;并且被裝飾的聲明信息會作為參數傳遞給裝飾器函數。 裝飾器的分類 類裝飾器 類裝飾器作用于類構造函數&…

【金倉數據庫征文】政府項目數據庫遷移:從MySQL 5.7到KingbaseES的蛻變之路

摘要&#xff1a;本文詳細闡述了政府項目中將 MySQL 5.7 數據庫遷移至 KingbaseES 的全過程&#xff0c;涵蓋遷移前的環境評估、數據梳理和工具準備&#xff0c;遷移實戰中的數據源與目標庫連接配置、遷移任務詳細設定、執行遷移與過程監控&#xff0c;以及遷移后的質量驗證、系…