YOLOv8-pose姿态估计实战:一份带数据集的关键点检测项目全解析
简介本资源是一套基于YOLOv8-pose的人体姿态关键点检测完整项目面向计算机视觉开发者、研究人员及入门学习者可用于运动分析、人机交互、视频监控等场景。项目将模型结构、训练与推理流程、标注数据集整合在一起无需从零搭建即可直接运行和二次开发。压缩包共1369个文件约89MB主要包含Python源码与编译缓存、PyTorch模型权重、YOLO配置文件、数据标注与标签文件、训练日志及说明文档等目录结构清晰适合对照学习训练流程、损失函数设计与数据增强策略。目前已有6200余人学习使用。资源附带已标注的人体图像数据集与预训练权重并提供了完整可复现的训练、验证和推理脚本方便读者快速评估模型精度、微调参数并迁移至自有数据场景是系统掌握姿态关键点检测的实用参考。1. 姿态识别项目落地一份能直接跑通的 YOLOv8-pose 关键点检测源码如果你手上正好有一批带标注的人体姿态数据或者只想先跑通一套关键点检测流程再谈二次开发这个基于 YOLOv8-pose 的姿态关键点检测项目是最省事的起点。它不是那种只有模型没有数据的半成品而是把训练、验证、推理、可视化整条链路都串好了解压之后按顺序执行就能在本地看到骨骼点叠加在原图上的效果。这套方案适合两类人一类是做人体动作分析、健身计数、安防行为识别的开发者需要先拿到一个可复现的基线模型另一类是刚接触姿态估计的学生或转岗工程师想通过完整代码理解 YOLOv8-pose 从数据标注到坐标输出的全过程。标题里强调“带数据集、可直接跑通”意味着你不需要满网找权重文件和标注文件项目内已经准备好了训练所需的最小数据集和配置。下面我从数据处理、模型结构、运行避坑、二次开发四个层面把这份源码拆开讲。2. 技术选型与数据准备COCO17 点标注怎么变成训练集2.1 为什么选 YOLOv8-pose 而不是 OpenPose 或 MediaPipe姿态估计的常见路线有三条传统自顶向下先检测人再回归关键点典型代表是 OpenPose、轻量级方案MediaPipe、以及单阶段检测器直接输出人体框和关键点YOLOv8-pose。YOLOv8-pose 属于第三种它在特征提取阶段就把目标检测和姿态回归合并到同一个网络里推理时一次前向同时给出人体边界框和 17 个关键点的坐标与置信度。相比 OpenPose 的复杂后处理流程YOLOv8-pose 的工程友好度高很多模型文件就是一个标准 YAML训练命令和普通目标检测完全一致权重导出 ONNX 后还能用自带 NMS 处理多人的情况。MediaPipe 虽然轻但它返回的是归一化坐标且不可训练想落业务时很难针对特定场景比如侧卧、遮挡微调。这个项目选 YOLOv8-pose 的另一个好处是——ultralytics 库的接口足够简单训练和预测各一个 Python 文件就能完成适合做基线验证。2.2 数据集目录结构与 keypoints 标签格式拿到项目压缩包后先看数据目录它的组织方式直接决定了后续改数据时踩不踩坑。常见做法是把数据集拆成 images 和 labels 两个并列目录再按 train/val 划分而不是把所有图片堆在一起然后靠脚本临时切分。这个项目的目录结构大致是这样datasets/ ├── images/ │ ├── train/ │ └── val/ └── labels/ ├── train/ └── val/标注文件是 YOLO-pose 格式的 txt每一行对应一张图里的一个人。第一个数字是类别 id后面跟着归一化坐标。关键点部分从第 6 个数字开始每三个数字一组表示一个点的 x、y 和可见性标记。可见性标记是 0、1、2 三档含义分别是未标注、遮挡但可推断、可见。以 COCO 17 点格式为例一整行的结构是class_id x_center y_center width height x1 y1 vis1 x2 y2 vis2 ... x17 y17 vis17前 5 个数是人体框的归一化中心坐标和宽高后面 51 个数字是 17 个关键点的数据。之所以带可见性标记是因为训练时 loss 计算要对不同状态的 keypoint 区别对待——完全不可见的点如果强行参与回归会把模型带偏。这个项目自带的数据集是某实验环境拍摄的动作样本虽然规模不大但胜在标注干净、场景单一拿来验证训练链路非常合适。如果你要换自己的数据集只需要把图片和标注按同样目录放好再把数据配置文件里的路径改掉就行不需要动任何训练代码。2.3 数据校验跑通前必须确认的几件事解压之后别急着训练先做三件事能省掉后面大量排查时间。第一检查标签里的坐标是否归一化在 0~1 之间。有些标注工具导出的是像素坐标直接喂给 YOLO 训练会导致 loss 极大且不收敛。用下面的脚本扫一遍最快import os label_dir datasets/labels/train for name in os.listdir(label_dir): with open(os.path.join(label_dir, name)) as f: for line in f: parts line.strip().split() nums [float(v) for v in parts[2:]] if max(nums) 1.0: print(f{name} 存在非归一化坐标: {max(nums)})这段脚本把标签里所有数值取出来如果发现大于 1 的值就打印文件名。逻辑很简单但非常管用——标注尺寸填错、单位搞混是最常见的低级错误而且报错信息往往要到训练中期才出现那时候已经浪费了几小时。第二确认图片和标签的文件名一一对应。YOLO 系列训练要求同名不同后缀比如frame_001.jpg对应frame_001.txt。如果命名对不上ultralytics 会把这张图当成无标注样本跳过训练集实际参与训练的图片数量和你以为的不一样。第三看每张图的人数。YOLO-pose 标注一行一个人一张图里有多个人就有多行。如果你的数据集有大量多人场景但标签文件大多只有一行说明标注阶段漏了人需要回到标注工具里补全否则模型会学出“只检测一个人”的偏见。检查方法很简单统计一下包含多行标签的文件占比即可。3. 核心模块拆解一个关键点在 YOLOv8-pose 里的完整流转3.1 模型配置从 pose yaml 看懂输出通道YOLOv8-pose 的网络结构定义在ultralytics/cfg/models/v8-pose.yaml里核心改动集中在检测头部分。相比普通的 YOLOv8 检测模型pose 版本在输出层增加了 keypoint 分支。通道数的计算逻辑是4 num_cls keypoint_channels * num_kpts * 2。这里容易困惑的是为什么乘 2——因为定位分支里每个关键点的 x、y 被分开存flatten 之后输出通道翻倍而可见性分支单独走 sigmoid。以默认的 COCO 17 点配置为例类别数一般是 1person那么输出通道就是4 1 1 * 17 * 2 39。如果你换了自定义数据集只保留 12 个关键点那输出通道要相应改成4 1 1 * 12 * 2 29。改错这个数字模型训练时 loss 直接 NaN而且报错信息不会明确告诉你是通道不匹配只会在某个 Conv 层抛出尺寸不一致的提示新手很容易看懵。3.2 训练入口参数怎么传才不至于白跑项目里训练脚本通常长这样from ultralytics import YOLO model YOLO(yolov8n-pose.yaml) results model.train( datapose.yaml, epochs100, imgsz640, batch8, device0, projectruns/pose, nameexp1 )model.train()会先按传入的 YAML 构建模型结构然后读取数据配置。datapose.yaml指向一个描述数据集路径和类别信息的文件epochs和batch按显存调节device0指定使用 GPU没有 GPU 就改成devicecpu但速度会有数量级差距这个项目的数据集规模在 CPU 上也能勉强跑通只是不建议拿它做完整训练。3.3 推理与可视化画出骨架不是调一个函数这么简单训练完成后推理入口代码非常短from ultralytics import YOLO model YOLO(runs/pose/exp1/weights/best.pt) results model.predict( sourcedatasets/images/val, saveTrue, save_txtTrue )saveTrue会把渲染了骨骼点的图片保存到runs/pose/predict/目录save_txtTrue会把每个关键点的归一化坐标写到 txt 文件里。但你如果想把坐标拿回自己的业务逻辑里用一般都会选择手动解析 results 对象for r in results: boxes r.boxes.xyxy keypoints r.keypoints.xy conf r.keypoints.confr.keypoints.xy的形状是(num_detections, 17, 2)r.keypoints.conf是(num_detections, 17)。每个检测框对应一组关键点数据拿到之后可以自行过滤置信度低的点再按业务需求映射到原图坐标。可视化部分项目里用的是 ultralytics 自带的plot()接口它内部通过 OpenCV 画线段把骨骼关节连接起来。这里有个默认行为要注意17 点骨骼的连线顺序写死在库的骨骼连接定义里如果你自定义了关键点顺序画出来的骨架会串线需要在绘制前自己定义连接索引。3.4 训练超参与日志解读训练过程中的 loss 变化是判断模型是否学歪的重要依据。YOLOv8-pose 的训练日志里会同时出现多个 loss 分量box_loss代表人体框回归误差cls_loss代表分类误差dfl_loss是分布焦点损失pose_loss是关键点坐标回归误差。如果pose_loss下降缓慢但box_loss已经收敛问题大概率出在关键点标注噪声上而不是网络结构别急着调学习率。另外一个容易忽略的参数是kpt_shape它在模型 YAML 里定义关键点数量和维度。默认 COCO 配置是[17, 3]第二个维度 3 代表(x, y, visible)。如果你只用二维标注应该改成[17, 2]同时要保证标注文件里每行关键点部分只写 34 个数字多写的可见性值会被解析器忽略训练时不报错但数据已经读错了。4. 常规运行步骤把源码从压缩包变成可见的骨架图4.1 环境安装一套干净的依赖组合不同机器的 Python 环境和 CUDA 版本差异很大我一般建议先建一个干净的虚拟环境再装依赖。ultralytics 框架的版本敏感性比较高装得太新可能踩 API 变更的坑装得太旧又缺少部分功能。项目级的做法是直接用 requirements.txt 锁定版本conda create -n yolo-pose python3.10 -y conda activate yolo-pose pip install -r requirements.txtrequirements.txt 里通常至少包含这几个核心依赖ultralytics、torch、torchvision、opencv-python、numpy、pyyaml。其中 PyTorch 建议根据你的 CUDA 版本单独安装不要直接用 pip 默认源否则装出来的是 CPU 版本训练速度会慢到怀疑人生。装完后运行一条测试命令确认环境没问题再开始跑项目from ultralytics import YOLO model YOLO(yolov8n-pose.pt) print(model.names)如果这条命令能打印出模型信息说明依赖链完整。输出的类别名是 person没有异常报错就继续。4.2 训练与验证用自己的数据复现一次完整流程一切就绪后在项目根目录执行训练命令。为了快速验证链路通畅第一次跑不需要完整训练设置epochs10就能在第 3 个 epoch 之后看到 loss 有意义的下降。python train.py项目里的 train.py 就是一个精简入口内部读取pose.yaml数据集配置然后调用上面提到的model.train()。训练过程中注意 watch 两个东西一个是runs/pose/exp1/目录下的results.csv另一个是每轮训练结束保存的val_batch_pred.jpg预览图。如果预览图里的骨骼点画在人的躯干外面多半是标注文件坐标换算出了问题。训练完成后项目脚本也会自动做一次验证集评估输出 mAP50 和 mAP50-95 两个关键指标。姿态任务的 mAP 计算方式和检测不一样——它允许预测关键点与 GT 在 OKS 阈值下匹配如果 mAP 值低得离谱优先检查标注而不是网络。4.3 导出与部署从 PyTorch 权重到 ONNX 推理验证结果符合预期后下一步是导出推理格式。Python 环境里直接跑 PyTorch 权重没问题但真实项目要接入服务端推理时更通用的做法是导出 ONNXyolo export modelruns/pose/exp1/weights/best.pt formatonnx imgsz640导出成功后可以用onnxruntime做一次推理验证确认导出前后坐标输出一致。这一步有个常见的坑ONNX 的 NMS 输出顺序和 PyTorch 里可能不同尤其是置信度阈值和 IoU 阈值的默认值不一样。拿同一张图分别跑 PyTorch 和 ONNX对比检测框数量如果差异大于一两个框需要手动对齐阈值参数否则后续接业务时会出现前后端结果不一致的怪问题。5. 常见问题与避坑记录姿态项目最容易翻车的几个现实场景5.1 训练 loss 早停不下降先查学习率和标注噪声现象pose_loss在前 5 个 epoch 降到 2 之后一直停滞在 1.8 附近不再明显下降。原因多数情况下不是模型瓶颈而是关键点标注一致性差。尤其是遮挡状态下的关键点不同标注员之间的位置偏差本来就大模型无法在歧义样本上继续逼近。其次是学习率设置得不合适默认 0.01 在小数据集上容易反复震荡。解决先把lr0降到 0.001 试试同时把weight_decay调到 0.0005。如果依然停滞回到数据检查遮挡样本——把 17 个点的可见性标记统计一下如果vis0的点占比过高说明标注阶段存在大量漏标这部分样本造成的 loss 噪声远大于正常样本的梯度贡献。5.2 导出 ONNX 后坐标偏移了半个图问题出在预处理现象同一张测试图在 PyTorch 里画出来的框是准的ONNX 导出后用onnxruntime推理画框发现框偏了大约 30 像素。原因ultralytics 推理时默认会做 letterbox 缩放并记录原始图尺寸与缩放图尺寸的比例坐标还原回原图时要乘这个比例。直接用 ONNX 时如果跳过了框架自带的预处理或者拿了缩放后的输出坐标直接画自然就偏了。解决导出 ONNX 后推理脚本里必须保留 letterbox 参数用(orig_w / new_w, orig_h / new_h)做坐标映射不要只写一个简单的仿射变换完事。把还原后的坐标再画到原图上做二次校验确认和 PyTorch 的结果误差在 1 像素以内再接服务。5.3 多人场景下关键点经常串人需要调整 NMS 参数现象两个人靠近时A 的左手腕点被分到了 B 的人体框上骨架看起来像是两个人手臂连在一起。原因YOLOv8-pose 的关键点回归是基于人体框的两个检测框 IoU 高的时候NMS 会把框保留下来但关键点分支的输出并没有做跨人约束。这是单阶段姿态方案的通病不是 bug。解决调高conf_thres到 0.25 以上减少低置信度检测框对 NMS 的干扰另一个办法是后处理中按关键点可见性做一次跨框插值——当两个框的同类关键点距离小于某阈值时保留置信度高的那个。这个项目里预留了后处理脚本的接口改post_process()一个函数就行。5.4 改了数据集之后训练报“shape mismatch”现象把自带数据集换成自己的 14 点标注后训练在第 1 个 epoch 报错提示某 Conv 层输出尺寸对不上。原因模型 YAML 里的kpt_shape没有同步改网络输出通道还是按 17 点计算的和数据的 14 点标签数量不一致。解决打开yolov8n-pose.yaml把kpt_shape改成[14, 3]同时确认pose.yaml里的关键点连接顺序和数量匹配。这两个 YAML 一处没改都会在训练初期报错属于改自定义数据集最容易踩的坑了。5.5 验证集 mAP 很高但可视化结果很差检查置信度处理现象训练日志里 mAP50 到 0.9但预测画图时很多关键点消失了。原因mAP 统计时用了较低的置信度阈值而可视化代码里默认过滤掉了置信度小于 0.5 的点。两者的阈值不一致导致官方指标好看但实际视觉输出缺胳膊少腿。解决在可视化脚本里把keypoint_conf_thres调到 0.25 再画图对齐评估和可视化的口径。从那以后我每次调完阈值都会强制跑一遍评估脚本和可视化脚本确认两条链路的置信度逻辑一致才往下走这个习惯帮我少踩了很多次坑希望帮到你。本文还有配套的精品资源点击获取

相关新闻

24-内核编译流程与镜像生成

24-内核编译流程与镜像生成

文章目录 一、概述 二、形象比喻:出版一本书 三、内核编译完整流程 3.1 vmlinux -> Image -> zImage 四、RK3506 内核编译命令 4.1 SDK 中的自动编译(mk-kernel.sh) 五、编译产物位置 六、编译过程关键输出解读 七、编译优化选项 八、zImage 启动流程 九、常见编译错误 �…

2026/10/16 16:13:47 阅读更多 →
YOLOv8-pose关键点检测实战:从COCO数据标注到训练部署

YOLOv8-pose关键点检测实战:从COCO数据标注到训练部署

简介:这是一套基于YOLOV8-pose的人体姿态关键点检测项目,面向计算机视觉开发者与科研人员,可用于姿态识别、运动分析、人机交互等场景的模型训练与推理。包内含完整源码、预训练权重、标注数据集和配置文件,并附有README说明&…

2026/10/16 16:13:47 阅读更多 →
DeepSeek本地知识库实战:RAG原理、选型与落地避坑指南

DeepSeek本地知识库实战:RAG原理、选型与落地避坑指南

简介:基于 DeepSeek 构建个人与企业大模型本地知识库的 PDF 技术文档,共 1 个文件、约 2.28MB,已有 261 人学习下载。内容面向希望落地本地知识库的技术人员、架构师及企业 AI 应用开发者,系统讲解 RAG 检索增强生成的核心原理&am…

2026/10/16 16:12:46 阅读更多 →

最新新闻

从ONNX到NPU:Llama-3.2-3B-Instruct_rai_1.8.0_npu_16K的OGA混合推理流水线深度解析

从ONNX到NPU:Llama-3.2-3B-Instruct_rai_1.8.0_npu_16K的OGA混合推理流水线深度解析

【免费下载链接】Llama-3.2-3B-Instruct_rai_1.8.0_npu_16K 项目地址: https://ai.gitcode.com/hf_mirrors/amd/Llama-3.2-3B-Instruct_rai_1.8.0_npu_16K 点击查看 免费下载 本文深入解析 Llama-3.2-3B-Instruct 在 AMD Ryzen AI 平台上的 OGA 混合推理流水线。该…

2026/10/16 16:46:26 阅读更多 →
25层堆叠也不发散:VisionHOPE 用“非扩张动力学“把自修改钉进了安全区

25层堆叠也不发散:VisionHOPE 用“非扩张动力学“把自修改钉进了安全区

25层堆叠也不发散:VisionHOPE 用"非扩张动力学"把自修改钉进了安全区 【免费下载链接】VisionHOPE 项目地址: https://ai.gitcode.com/hf_mirrors/PSRben/VisionHOPE 让视觉主干在推理时"边看图边改自己"——这个概念足够诱人&#xff…

2026/10/16 16:46:26 阅读更多 →
AI编程从无状态到有状态:Memory工程与AGENTS.md配置实战

AI编程从无状态到有状态:Memory工程与AGENTS.md配置实战

1. 从无状态到有状态:AI 编程范式转换的底层逻辑1.1 为什么无状态模型是当前 AI 编程的最大瓶颈如果你最近半年深度用过任何一款 AI 编程助手,大概率经历过这种场景:第一轮对话它帮你把某个模块重构得漂漂亮亮,第二轮你让它接着改…

2026/10/16 16:46:26 阅读更多 →
Windows域信任关系失败的三重根因与修复指南

Windows域信任关系失败的三重根因与修复指南

简介:本资源是一份针对Windows域环境中‘工作站和主域间信任关系失败’问题的实操型排错指南,主要面向企业IT运维人员、系统管理员及虚拟化平台(如VMware、Hyper-V)环境下的技术实践者。文档深入剖析该错误成因——域用户在本地计…

2026/10/16 16:46:26 阅读更多 →
Java通讯录管理系统:面向对象建模与工程实践入门指南

Java通讯录管理系统:面向对象建模与工程实践入门指南

简介:这是一份面向Java初学者的GUI实战项目资源,基于Swing框架开发的通讯录管理系统,帮助学习者掌握面向对象编程、集合操作、文件I/O及桌面应用界面设计等核心技能。资源包共16个文件,含6个.java源码文件(如Mainfrm.j…

2026/10/16 16:46:26 阅读更多 →
Nero刻录光盘软件:从数据归档翻车到批量刻录实战

Nero刻录光盘软件:从数据归档翻车到批量刻录实战

简介:这是一份面向需要光盘刻录与影音处理用户的Nero刻录软件安装包,适合初次接触刻录工具或希望快速搭建本地刻录环境的人群使用,可解决系统重装后缺少刻录软件、日常备份数据与制作影音光盘等需求。压缩包为zip格式,共收录140个…

2026/10/16 16:45:24 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →