AI金融攻防赛:YOLO理论学习及赛题进阶思路(DataWhale组队学习)

head

引言

大家好,我是GISer Liu😁,一名热爱AI技术的GIS开发者。本系列文章是我跟随DataWhale 2024年10月学习赛的AI金融攻防赛学习总结文档。本文主要讲解如何在金融场景凭证篡改检测中应用YOLO算法。我们将从模型概述、数据准备、训练流程以及模型评估等多个方面,详细介绍如何搭建一个高效的目标检测模型。希望我的经验能对大家有所帮助!💕💕😊


一、物体检测与YOLO算法介绍

1. 什么是物体检测?

物体检测是计算机视觉中的一个重要任务,它不仅需要识别图像中的对象类别,还要确定对象在图像中的位置,并以边界框的形式标注出来(类别+位置)。物体检测的应用场景包括自动驾驶、视频监控、工业检测、金融凭证核验等领域。

物体检测的一般步骤

  1. 输入:一张图像或视频帧,对其进行缩放。
  2. 特征提取:通过卷积神经网络(CNN)提取视觉特征,为检测提供基础。
  3. 候选区域生成:部分算法会生成可能含有目标的区域(如R-CNN)。
  4. 分类与边界框回归:判断区域内物体的类别并回归出精确的边界框坐标。
  5. 非极大值抑制(NMS):去除重复的边界框,保留最高置信度的框。

流程

2. YOLO算法概述

YOLO(You Only Look Once)是一种高效的实时目标检测算法,将检测任务视为一个单一的回归问题。与传统的滑动窗口方法不同,YOLO在一次网络评估中即可同时预测多个边界框和类别概率。其设计能够兼顾检测速度和精度,非常适合金融凭证篡改检测这种需要实时处理的任务。
流程

YOLO算法并行预测原理

YOLO(You Only Look Once)算法之所以能够同时预测多个边界框和类别概率,主要是因为它将目标检测任务视为一个单一的回归问题。具体来说,YOLO通过以下几个关键步骤实现这一目标:

  1. 单一网络评估:YOLO将整个图像输入到一个卷积神经网络(CNN)中,网络在一次前向传播过程中直接输出所有边界框和类别概率。这与传统的滑动窗口方法不同,滑动窗口方法需要多次评估图像的不同区域,而YOLO只需要一次评估。

  2. 网格划分:YOLO将输入图像划分为一个S×S的网格(例如,7×7)。每个网格单元负责预测在其中心附近的目标。每个网格单元可以预测多个边界框(通常是B个,例如B=2),并且每个边界框都与一个类别概率相关联。

  3. 边界框预测:每个网格单元预测B个边界框,每个边界框由5个参数组成:边界框的中心坐标(x, y)、边界框的宽度和高度(w, h),以及一个置信度(confidence)。置信度表示该边界框包含目标的概率。

  4. 类别概率预测:每个网格单元还预测C个类别概率,表示该网格单元中目标属于每个类别的概率。这些类别概率与边界框无关,而是基于网格单元的内容。

相关公式理论:
1. 置信度(Confidence):

  • 置信度的计算公式为:
    Confidence = Pr(Object) × IOU(pred, truth) \text{Confidence} = \text{Pr(Object)} \times \text{IOU(pred, truth)} Confidence=Pr(Object)×IOU(pred, truth)
    • Pr(Object):表示网格单元中存在目标的概率。如果网格单元中没有目标,Pr(Object)为0;如果有目标,Pr(Object)为1。
    • IOU(pred, truth):表示预测边界框与真实边界框的交并比(Intersection over Union)。IOU的值范围在0到1之间,值越大表示预测框与真实框的重叠程度越高。

2. 类别概率(Class Probability)

  • 类别概率的计算公式为:
    Class Probability = Pr(Class i ∣ Object) \text{Class Probability} = \text{Pr(Class}_i | \text{Object)} Class Probability=Pr(ClassiObject)
    • Pr(Class_i | Object):表示在网格单元中存在目标的情况下,目标属于第i类的概率。
  • 最终预测:
    最终的预测结果是每个边界框的置信度与类别概率的乘积:
    Final Prediction = Confidence × Class Probability \text{Final Prediction} = \text{Confidence} \times \text{Class Probability} Final Prediction=Confidence×Class Probability
  • 举例:
    假设我们有一个7×7的网格,每个网格单元预测2个边界框,并且我们有3个类别(例如,人、车、自行车)。
  • 网格划分:图像被划分为7×7的网格,总共有49个网格单元。
  • 边界框预测:每个网格单元预测2个边界框,每个边界框有5个参数(x, y, w, h, confidence)。假设某个网格单元预测的两个边界框为:
    • 边界框1:(x1, y1, w1, h1, confidence1)
    • 边界框2:(x2, y2, w2, h2, confidence2)
  1. 类别概率预测

每个网格单元还预测3个类别概率(人、车、自行车)。假设某个网格单元的类别概率为:
- 人:0.8
- 车:0.1
- 自行车:0.1

  • 最终预测:对于每个边界框,最终的预测结果是置信度与类别概率的乘积。例如:
    • 边界框1的最终预测:(confidence1 * 0.8, confidence1 * 0.1, confidence1 * 0.1)
    • 边界框2的最终预测:(confidence2 * 0.8, confidence2 * 0.1, confidence2 * 0.1)

由此,YOLO能够在一次前向传播中同时预测多个边界框和类别概率,从而实现快速且高效的目标检测。


二、YOLO版本演进与特性

YOLO算法自2015年推出以来经历了多次迭代,每一代都在速度、准确性和易用性方面进行了改进:

版本年份主要贡献与特点
YOLOv12015将检测视为回归问题,单次网络预测物体类别与位置。
YOLOv22016引入批量归一化和高分辨率分类器,支持多达9000个类别的检测。
YOLOv32018使用Darknet-53骨干网络,提高了多尺度检测能力。
YOLOv42020融合CSPNet和PANet等技术,提升特征提取效率。
YOLOv52020用PyTorch实现,更易用,适应不同场景。
YOLOv82023引入Anchor-Free检测头和新损失函数,提升性能与灵活性。
YOLOv102024取消NMS操作,优化组件,实现最高性能。

三、YOLO数据集格式与标注

YOLO算法的标注格式主要使用.txt文件记录图像中的物体信息。每一行代表一个物体的类别及其边界框坐标,格式如下:

class_index x_center y_center width height
  • class_index:类别索引,对应于类别列表中的整数。
  • x_center, y_center:物体中心的x和y坐标,归一化到[0, 1]范围。
  • width, height:物体边界框的宽度和高度,同样归一化处理。

示例配置文件 (YOLO.yaml)

path: ../dataset/  # 数据集根目录
train: images/train/  # 训练集路径
val: images/val/  # 验证集路径# 类别数量和名称
nc: 2  # 类别数量
names: ["0", "1"]  # 类别名称

本此比赛的baseline中则是这个data.yaml的文件:
file-format

ok,看完Yolo的基本介绍后,我们根据本次比赛的baseLine代码来提出Yolo的训练过程吧!


四、金融检测YOLO模型的训练与评估流程

为了提升模型在金融场景中的应用效果,我们可以采取以下优化措施:

  1. 增加训练数据:整合更多高质量数据集,提升模型的泛化能力。
  2. 使用不同的预训练权重:在已有模型上微调,提升精度。
  3. 模型部署:将训练好的模型部署到云端或本地服务器,实时检测凭证篡改行为。

作者将在下面整理本次比赛代码流程:

1.安装必要的库
pip install ultralytics opencv-python-headless albumentations pandas numpy

2.导入依赖库
import os
import cv2
import shutil
import numpy as np
import pandas as pd
import albumentations as A
from ultralytics import YOLOprint('依赖库导入成功!')

3.定义图像增强和处理函数
# 绘制多边形到二值 mask 上
def polygon_to_mask(polygon, img_height, img_width):mask = np.zeros((img_height, img_width), dtype=np.uint8)polygon = np.array([polygon], dtype=np.int32)cv2.fillPoly(mask, polygon, 1)return mask# 增强图像并生成 mask
def augment_image(img, polygons):mask = np.zeros(img.shape[:2], dtype=np.uint8)for polygon in polygons:polygon_mask = polygon_to_mask(polygon, img.shape[0], img.shape[1])mask = np.maximum(mask, polygon_mask)transform = A.Compose([A.HorizontalFlip(p=0.5),A.VerticalFlip(p=0.5),A.RandomRotate90(p=0.5),A.RandomBrightnessContrast(p=0.2),], is_check_shapes=False)augmented = transform(image=img, mask=mask)return augmented['image'], augmented['mask']# 归一化多边形坐标
def normalize_polygon(polygon, img_width, img_height):return [(x / img_width, y / img_height) for x, y in polygon]print('图像增强和归一化函数定义成功!')

4. 处理训练集和验证集
# 加载数据集(假设已有一个包含路径和多边形数据的DataFrame:training_anno)
training_anno = pd.read_csv('annotations.csv')  # 替换为你的注释文件路径# 处理训练数据集
for _, row in training_anno.iloc[:14000].iterrows():shutil.copy(row['Path'], 'yolo_seg_dataset/train/')img = cv2.imread(row['Path'])img_height, img_width = img.shape[:2]# 数据增强img, mask = augment_image(img, row['Polygons'])# 保存标签文件txt_filename = os.path.join('yolo_seg_dataset/train/', row['Path'].split('/')[-1][:-4] + '.txt')with open(txt_filename, 'w') as f:for polygon in row['Polygons']:normalized_polygon = normalize_polygon(polygon, img_width, img_height)normalized_coords = ' '.join([f'{coord[0]:.3f} {coord[1]:.3f}' for coord in normalized_polygon])f.write(f'0 {normalized_coords}\n')print('训练集处理完成!')# 处理验证集
for _, row in training_anno.iloc[14000:17000].iterrows():shutil.copy(row['Path'], 'yolo_seg_dataset/valid/')img = cv2.imread(row['Path'])img_height, img_width = img.shape[:2]mask = np.zeros(img.shape[:2], dtype=np.uint8)for polygon in row['Polygons']:polygon_mask = polygon_to_mask(polygon, img.shape[0], img.shape[1])mask = np.maximum(mask, polygon_mask)txt_filename = os.path.join('yolo_seg_dataset/valid/', row['Path'].split('/')[-1][:-4] + '.txt')with open(txt_filename, 'w') as f:for polygon in row['Polygons']:normalized_polygon = normalize_polygon(polygon, img_width, img_height)normalized_coords = ' '.join([f'{coord[0]:.3f} {coord[1]:.3f}' for coord in normalized_polygon])f.write(f'0 {normalized_coords}\n')print('验证集处理完成!')

5.创建配置文件
# 创建数据集的配置文件 data.yaml
with open('yolo_seg_dataset/data.yaml', 'w') as f:data_root = os.path.abspath('yolo_seg_dataset/')f.write(f'''
path: {data_root}
train: train
val: validnames:0: alter
''')print('配置文件创建成功!')

6.训练模型
print('开始模型训练!')# 加载 YOLOv8 分割模型并进行训练
model = YOLO("yolov8l-seg.pt")  # 使用较大的 YOLOv8-L 分割模型
results = model.train(data="./yolo_seg_dataset/data.yaml", epochs=50, imgsz=640)  # 设置训练轮数为50print('模型训练完成!')

7.保存和验证结果
# 保存训练结果
results.save("yolo_seg_results/")
# 打印训练结果摘要
print(results)

  1. 安装依赖:安装必要的 Python 包,如 ultralyticsopencvalbumentations 等。
  2. 定义增强函数:通过 Albumentations 进行图像增强,并生成 mask。
  3. 处理数据集:将训练集和验证集中的图像及其标签进行增强和格式化。
  4. 创建配置文件:定义数据集路径和类别名称。
  5. 训练模型:加载 YOLOv8 分割模型,使用增强后的数据集进行训练,并保存结果。

相信看完以上代码后,读者对这个流程有了自己的理解;我们再来了解一下实例分割的概念与原理吧!


五、YOLO实例分割原理

1.实例分割的概念

实例分割
实例分割(Instance Segmentation)是一种计算机视觉任务,它**不仅需要识别图像中的每个物体,还需要精确地分割出每个物体的像素级边界。**与物体检测(Object Detection)不同,物体检测只需要识别出图像中物体的边界框(Bounding Box),而实例分割则需要进一步将每个物体的像素精确地分割出来。

上图中面积区域是实例分割的结果,框选区域是目标识别的结果;

2.实例分割与物体识别的区别

  1. 物体检测(Object Detection)

    • 任务:识别图像中物体的类别和位置。
    • 输出:每个物体的边界框(Bounding Box)和类别标签。
    • 示例:YOLO、Faster R-CNN。
  2. 实例分割(Instance Segmentation)

    • 任务:识别图像中每个物体的类别,并精确地分割出每个物体的像素级边界。
    • 输出:每个物体的像素级掩码(Mask)和类别标签。
    • 示例:Mask R-CNN、YOLOv8。

3.YOLO实例分割

YOLOv8通过扩展其基本的目标检测框架,实现了实例分割功能。以下是YOLOv8实现实例分割的关键步骤和原理:

  1. 多任务损失函数

    • 边界框损失:评估预测框与真实框之间的差异。
    • 分类损失:预测类别与真实类别的误差。
    • 分割损失:预测掩码与真实掩码的差异。
    • DFL损失:用于优化预测框的边缘精度。
  2. 特征提取

    • YOLOv8使用卷积神经网络(CNN)提取图像特征。这些特征图(feats)包含了图像的高级语义信息。
  3. 原型掩码生成

    • 在特征提取之后,YOLOv8生成一组原型掩码(proto)。这些原型掩码是基于特征图生成的,用于表示不同物体的潜在掩码形状。
  4. 预测掩码生成

    • 基于原型掩码和特征图,YOLOv8生成预测掩码(pred_masks)。这些预测掩码是每个物体的像素级掩码。
  5. 掩码组合

    • 最终的实例掩码是通过组合预测掩码和原型掩码生成的。这个过程考虑了不同目标之间的掩码重叠情况,并对重叠区域进行处理。
  6. 损失计算与优化

    • 在训练过程中,YOLOv8使用多任务损失函数来优化模型的参数。通过最小化边界框损失、分类损失、分割损失和DFL损失,模型能够同时学习物体检测和实例分割任务。

示例

假设我们有一张包含多个物体的图像,例如一张包含汽车、行人和自行车的街道图像。
test

  1. 物体检测

    • YOLOv8首先识别出图像中的每个物体,并生成它们的边界框。例如,它会识别出汽车、行人和自行车的边界框。
  2. 实例分割

    • 在物体检测的基础上,YOLOv8进一步生成每个物体的像素级掩码。例如,它会生成汽车、行人和自行车的像素级掩码,精确地分割出每个物体的像素。

代码如下:

import cv2from ultralytics import YOLO
from ultralytics.utils.plotting import Annotator, colorsmodel = YOLO("yolo11n-seg.pt")  # segmentation model
names = model.model.names
cap = cv2.VideoCapture("path/to/video/file.mp4")
w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS))out = cv2.VideoWriter("instance-segmentation.avi", cv2.VideoWriter_fourcc(*"MJPG"), fps, (w, h))while True:ret, im0 = cap.read()if not ret:print("Video frame is empty or video processing has been successfully completed.")breakresults = model.predict(im0)annotator = Annotator(im0, line_width=2)if results[0].masks is not None:clss = results[0].boxes.cls.cpu().tolist()masks = results[0].masks.xyfor mask, cls in zip(masks, clss):color = colors(int(cls), True)txt_color = annotator.get_txt_color(color)annotator.seg_bbox(mask=mask, mask_color=color, label=names[int(cls)], txt_color=txt_color)out.write(im0)cv2.imshow("instance-segmentation", im0)if cv2.waitKey(1) & 0xFF == ord("q"):breakout.release()
cap.release()
cv2.destroyAllWindows()

通过这种方式,YOLOv8不仅能够识别图像中的物体,还能够精确地分割出每个物体的像素级边界,从而实现实例分割任务。

OK! 今天就学习到这里了!😉


七、总结

通过本次AI金融攻防赛的学习和实践,我们深入了解了凭证篡改检测这一关键问题,并成功构建了一个基于YOLOv8l的检测模型。通过数据标注、模型训练和评估,我们验证了YOLO在金融凭证检测任务中的高效性和可靠性。OK,初步解析到此结束!更多内容看后续;希望这篇博客能为您的项目提供帮助!🚀


相关链接

  • 项目地址:Git地址
  • 活动地址:AI核身之金融场景凭证篡改检测
  • 相关文档:专栏地址
  • 作者主页:GISer Liu-CSDN博客

thank_watch

如果觉得我的文章对您有帮助,记得三连+关注哦!🌟

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

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

相关文章

互联网数字化商品管理浪潮思考:从信息化到精准运营

目录 一、商品数字化转型面临的现状分析 (一)运营方向分析 (二)商品归类分析 二、商品数字化管理建设分析 三、基础建设——商品信息数字化 (一)商品信息质量数字化的目的 (二&#xff0…

Apache HTTP服务器上强制执行HTTPS重定向

要在Apache HTTP服务器上强制执行HTTPS重定向&#xff0c;您可以在服务器配置的虚拟主机中使用Redirect指令或者RewriteRule。以下是两种常见的方法&#xff1a; 方法1&#xff1a;使用Redirect指令 <VirtualHost *:80>ServerName yourdomain.comRedirect / https://yo…

[k8s理论知识]3.docker基础(二)隔离技术

容器其实是一种沙盒技术&#xff0c;其核心是通过约束和修改进程的动态表现&#xff0c;为其创建一个边界。这个边界确保了应用与应用之间不会相互干扰&#xff0c;同时可以方便在不同的环境中迁移&#xff0c;这是PaaS最理想的状态。 程序是代码的可执行镜像&#xff0c;通常…

力扣1652.拆炸弹

你有一个炸弹需要拆除&#xff0c;时间紧迫&#xff01;你的情报员会给你一个长度为 n 的 循环 数组 code 以及一个密钥 k 。 为了获得正确的密码&#xff0c;你需要替换掉每一个数字。所有数字会 同时 被替换。 如果 k > 0 &#xff0c;将第 i 个数字用 接下来 k 个数字之…

探索Spring Cloud Config:构建高可用的配置中心

目录 认识Spring Cloud ConfigConfig Server读取配置文件步骤1&#xff1a;&#xff08;1&#xff09;创建config-server项目&#xff08;2&#xff09;在config-server中开启Config Server功能&#xff08;3&#xff09;在config-server配置文件进行相关配置&#xff08;4&…

Axure复选框全选反选取消高级交互

亲爱的小伙伴&#xff0c;在您浏览之前&#xff0c;烦请关注一下&#xff0c;在此深表感谢&#xff01; 课程主题&#xff1a;复选框全选反选取消制作 主要内容&#xff1a;点击复选框&#xff0c;实现列表数据项全选选中、反选和取消选中效果 应用场景&#xff1a;多项选定…

【MySQL 保姆级教学】表的增删改查(上)

表的增删改查 1. 创建一个表 CREATE2 插入数据 INSERT INTO2.1 语法2.2 插入单行数据全列插入2.3 插入多行数据指定列插入2.4 同步更新 ON DUPLICATE KEY UPDATE2.4.1 引入2.4.2 同步更新2.4.3 查看被影响的行 2.5. 替换 REPLACE INTO 3. Retrieve&#xff08;查询SELECT&#…

有道在线翻译+4款新星,翻译从此无障碍,你get了吗?

现在全世界都连在一起了&#xff0c;说话不一样的问题再也不是啥大事。不管是搞研究、谈生意还是平时过日子&#xff0c;翻译软件都成了我们离不开的帮手。今儿&#xff0c;我们特激动地告诉大家&#xff0c;有道在线翻译和三个新伙伴一起&#xff0c;给Windows系统做了个超牛的…

9.校园二手网站系统( Springboot 和 thymeleaf(html)开源框架)

目录 1.系统的受众说明 2.系统需求分析 2.2.1用户功能模块 2.2.2二手交易功能需求 2.2.3需求发布功能需求 2.3.1操作流程 2.3.2添加信息流程 2.3.3删除信息流程 2.4 系统E-R图 3.系统概要设计 3.1系统的整体架构 3.2 数据库表 4.系统实现 4.1用户功能模块 4.2 二…

数据集成系统:赋能企业数字化转型的核心技术

在当今数字化时代下&#xff0c;企业面临数据量增长和多样化带来了巨大的挑战。如何整合利用这些数据是企业成功决策的基础。所以在这样的背景之下&#xff0c;数据集成系统成为了企业关注点。将不同来源的数据整合在一起&#xff0c;并且能够清晰的分析各类问题&#xff0c;已…

程序员们辛苦啦!1024程序员节,今天,我们不一样!

一、程序员节来历 程序员节&#xff08;Programmers Day&#xff09;是一年中专门为程序员和计算机科学工作者所设立的节日&#xff0c;通常是在每年的第256天庆祝。256这个数字在编程中具有特别的意义&#xff0c;因为它是2的8次方&#xff0c;代表着一个字节可以表示的所有可…

如何借助前端表格控件助力企业实现财务数字化转型

最新技术资源&#xff08;建议收藏&#xff09; https://www.grapecity.com.cn/resources/ 前言 在当今快速变化的经济环境中&#xff0c;记账软件对个人和企业的重要性愈发突出。对于个人而言&#xff0c;它可以帮助用户实时掌握财务状况&#xff0c;促进合理消费和有效储蓄&…

Java项目-基于Springboot的高校党务系统项目(源码+说明).zip

作者&#xff1a;计算机学长阿伟 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、ElementUI等&#xff0c;“文末源码”。 开发运行环境 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBoot、Vue、Mybaits Plus、ELementUI工具&#xff1a;IDEA/…

【SoC_Design】USB基本知识

目录 USB物理接口 USB3.0物理层支持dp-alt的usb type-c接口 拓扑结构层次结构 USB物理接口 USB2.0 两线&#xff1a;D、D- USB3 六线&#xff1a;D、D-、SSTX、SSTX-、SSRX、SSRX- USB3 2lane 十线&#xff1a; D、D-、&#xff08;SSTX、SSTX-、SSRX、SSRX-&#xff09;x2USB2…

什么是KKT 条件(Karush-Kuhn-Tucker 条件)

KKT 条件&#xff08;Karush-Kuhn-Tucker 条件&#xff09;是优化理论中的一组必要条件&#xff0c;适用于求解带有等式和不等式约束的非线性规划问题。当目标函数和约束条件是凸的时&#xff0c;KKT 条件也是找到最优解的充分条件。在支持向量机&#xff08;SVM&#xff09;的…

CSS文本基础知识

1、文本缩进 属性名&#xff1a;text-indent 属性值&#xff1a;数值px&#xff1b; 数字em&#xff08;推荐&#xff1a;1em当前标签的字号大小&#xff09; 例&#xff1a;代码&#xff1a; 结果: 2、文本对齐方式 作用&#xff1a;控制内容水平方式 属性名&#xff1a…

【力扣 | SQL题 | 每日3题】力扣1990, 2020, 2051

1. 力扣1990&#xff1a;统计实验的数量 1.1 题目&#xff1a; 表: Experiments ----------------------- | Column Name | Type | ----------------------- | experiment_id | int | | platform | enum | | experiment_name | enum | ----------------------…

公众号变现及生财内参项目建议

一、核心内容 &#xff08;一&#xff09;公众号变现分享 从业者王薄荷介绍公众号常规盈利思路为推文广告和品牌广告&#xff0c;公众号能外链的地方有菜单栏和阅读原文&#xff0c;虽菜单栏点击率低但有商业价值。以小说为例&#xff0c;主要盈利方式是小黄文截止在高潮部分…

HTB:Knife[WriteUP]

目录 连接至HTB服务器并启动靶机 1.How many TCP ports are open on Knife? 2.What version of PHP is running on the webserver? 并没有我们需要的信息&#xff0c;接着使用浏览器访问靶机80端口 尝试使用ffuf对靶机Web进行一下目录FUZZ 使用curl访问该文件获取HTTP头…

VisionPro 手部骨骼跟踪 Skeletal Hand Tracking 虚拟首饰

骨骼手部跟踪由XR Hands Package中的Hand Subsystem提供。使用场景中的Hand Visualizer组件&#xff0c;用户可以显示玩家手部的蒙皮网格或每个关节的几何图形&#xff0c;以及用于基于手部物理交互的物理对象。用户可以直接针对Hand Subsystem编写 C# 脚本&#xff0c;以推断骨…