基于Detectron2和LSTM的人体动作识别

article/2025/10/16 6:07:00

人体动作识别通过分析视频来预测或分类视频中人物的各种动作。它被广泛应用于监测、体育、健身、防御等各个领域。

假设你想创建一个在线教授瑜伽的应用程序。它应该提供一个预先录制的瑜伽视频列表供用户观看。用户在应用程序上观看视频后,可以上传自己的个人练习视频。然后app评估他们的表现,并根据用户的各种瑜伽体式(或姿势)的表现给出反馈。使用动作识别来自动评估视频不是很好吗?你可以用它做更多的事。看看下面的视频。

下面展示在瑜伽app中使用人体姿势估计来识别每个瑜伽姿势。

通过人体上关键来识别瑜伽姿势(Natarajasana, Trikonasana或Virabhadrasana)。

在这篇博文中,我们将解释如何使用姿势估计和LSTM (Long - term Memory)创建一个用于人类动作识别(或分类)的App。我们将创建一个web应用程序,它接收一个视频,并生成一个带有标识动作类注释的输出视频。我们将在web应用程序中使用Flask框架,并使用PyTorch lightning进行模型训练和验证。

Detectron2

Detectron2是Facebook AI Research的开源平台,用于目标检测、人体姿态估计、分割和其他视觉识别任务。这个平台现在是在PyTorch中实现的,不像之前的版本Detectron是在caff2中实现的。

在这里,我们使用了一个来自Detectron2 model zoo的预训练的“R50-FPN”模型来进行姿态估计。这个模型已经在包含20多万张图片和25万个任务实例的COCO数据集上进行了训练,这些数据集被标记为关键点。模型对输入图像帧中的每个人输出17个关键点,如下图所示。
[图片]

人体有17个关键点。图片的左边显示的是一个人,中间部分显示的是一个关键点列表,右边显示的是关键点在人身上的位置

LSTM

LSTM网络是一种递归神经网络(RNN),在序列预测问题中具有学习顺序依赖的能力。如下图所示,RNN有一个重复的神经网络模块链。

在这里插入图片描述

递归神经网络及其重复神经网络模块链

在神经网络(NN)中:

  • X 0 , X 1 , … , X t X_{0}, X_1,…,X_t X0,X1Xt是输入, h 0 , h 1 , … , h t h_0 ,h_1,…,h_t h0,h1ht是预测。
  • 每一时刻 t ( h t ) t_(ht) t(ht)的预测都依赖于之前的预测和当前输入 X t X_t Xt
    RNN记住之前的信息,并利用它来优化处理当前的输入。但是RNN的缺点是不能记住长期的依赖关系,具体梯度消失和爆炸的问题

LSTM也有类似的链式结构,但它的神经网络模块可以轻松处理长期依赖关系
我们使用LSTM对一段视频中的一系列关键点进行动作分类。

Dataset

为了训练LSTM模型,我们使用这个数据集。
这个数据集有什么特别之处?它由关键点检测组成,使用OpenPose深度学习模型,是伯克利多模态人类行为数据库(MHAD)数据集的中的一个子数据集。

OpenPose是第一个在单个图像上联合检测人体、手、面部和脚关键点(总共135个关键点)的实时多人系统。对12名受试者(从4个角度拍摄)的视频进行关键点检测,做以下6个动作,重复5次

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FINEWMQm-1653124062459)(https://learnopencv.com/wp-content/uploads/2021/07/human-actions-768x388.jpg)]

来自MHAD数据集子集的一系列6个人类动作(JUMPING, JUMPING_JACKS, BOXING, WAVING_2HANDS, WAVING_1HAND, CLAPPING_HANDS)。

  • JUMPING
  • JUMPING_JACKS
  • BOXING
  • WAVING_2HANDS
  • WAVING_1HAND
  • CLAPPING_HANDS

Flask

Flask是一个流行的Python web框架,用于开发多个web应用程序。该应用程序内部使用Detectron2和LSTM模型来识别动作。

人体动作识别的高级方法

要对一个动作进行分类,我们首先需要在每一帧中定位身体的各个部位,然后分析身体部位随时间的变化。

  • 第一步是使用Detectron2,在观察视频中的一帧后输出身体姿态(17个关键点)。
  • 第二步是利用LSTM网络分析物体随时间的运动并做出预测。因此,将一组帧中的关键点发送到LSTM进行动作分类,如下图所示。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iPDm99cz-1653124369795)(https://learnopencv.com/wp-content/uploads/2021/07/data-flow-diagram.jpg)]

端到端动作识别工作流,使用Detectron2和LSTM

动作识别的ML模型训练

  • 1.正如我们之前提到的,对于关键点检测,我们使用了Detectron2 model zoo.中预先训练好的“R50-FPN”模型。所以不需要进一步的训练。

  • 2.使用pytorch lightning训练用于基于关键点的动作分类的LSTM模型。

训练输入数据包含一系列关键点(每帧17个关键点)和相关的动作标签。一个连续的32帧序列被用来识别一个特定的动作。32帧的样本序列将是一个大小为32×34的多维数组,如下所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EDH9DXeY-1653124688436)(https://learnopencv.com/wp-content/ql-cache/quicklatex.com-03e64c7a975c61e3f419ad675e3c51ca_l3.png)]

每行包含17个关键点值。每个关键点都表示为(x,y)值,因此每行总共有34个值。

**注意:**与OpenPose模型在原始数据集中检测到的18个人体关键点不同,我们的应用程序只有17个关键点被Detectron2检测到。因此,在训练我们的LSTM模型之前,我们要转换成17个关键点的格式。

我们对模型进行了400epoch的训练,得到了0.913的验证精度。验证精度和损失曲线如下图所示。训练后的模型被存入到代码库中,并在推理过程中使用相同的模型。
在这里插入图片描述

模型推理

推理管道由Detectron2模型和自定义LSTM模型组成。

  • 我们的应用程序接受视频输入,迭代帧,然后使用Detectron2对每一帧进行关键点检测。
  • 然后将关键点结果追加到大小为32的缓冲区,该缓冲区以滑动窗口的方式操作。
  • 缓冲区的内容最终被发送到我们训练过的LSTM模型进行动作识别。
  • 此外,基于flas web应用程序有一个UI来接受用户的视频输入。
    我们的推理管道检测到的动作会在视频上加注释,并显示为结果。

“Tesla T4”GPU上的测试表明,Detectron2和LSTM的推理时间分别为0.14秒和0.002秒。因此,如果我们处理视频中的每一帧,那么我们的推断管道执行的组合FPS(帧/秒)大约是每秒6帧。

上述FPS速率可能适用于离线视频分析的应用程序。但如果你是在实时视频流上进行推断呢?一般来说,实时视频流的帧率为30fps或更高(取决于相机)。在这种情况下,推断管道的FPS必须高于或至少等于视频流的FPS,以处理帧没有任何延迟。虽然当前FPS很低,但你确实可以选择改善推断管道的FPS。

  • 对模型进行剪枝和量化可以加快模型的执行速度。
  • 跳过帧和间隔推断:你甚至可以跳过几个帧,选择间隔帧推断。例如,我们的测试显示,当在序列中每5帧进行推断时,FPS会增加到每秒27帧。但是我们发现准确性下降了,因此需要选择一个区间。
  • 多线程:有单独的线程接收视频和推断。
    • 接收线程可以专注于从流中读取视频帧,并将它们添加到队列中。
    • 独立的子线程可以从队列中读取帧来进行推断。子线程在处理帧时可能会滞后,但它不会阻止接收线程读取视频流

基于Web 应用的视频分析Detectron2, LSTM 模型代码

1. Detectron2姿态估计模型

我们使用的是预先训练好的Detectron2模型,如下图所示。

# obtain detectron2's default config
cfg = get_cfg()
# load the pre trained model from Detectron2 model zoo
cfg.merge_from_file(model_zoo.get_config_file("COCO-Keypoints/keypoint_rcnn_R_50_FPN_3x.yaml"))
# set confidence threshold for this model
cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5  
# load model weights
cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url("COCO-Keypoints/keypoint_rcnn_R_50_FPN_3x.yaml")
# create the predictor for pose estimation using the config
pose_detector = DefaultPredictor(cfg)

2. LSTM模型定义

我们的LSTM模型初始化隐藏维度(hidden_dim)为50,并使用PyTorch Lightning进行训练。我们使用了Adam优化器,还配置了ReduceLROnPlateau调度器,以根据val_loss的值降低学习速率。

# We have 6 output action classes.
TOT_ACTION_CLASSES = 6#lstm classifier definition
class ActionClassificationLSTM(pl.LightningModule):# initialise methoddef __init__(self, input_features, hidden_dim, learning_rate=0.001):super().__init__()# save hyperparametersself.save_hyperparameters()# The LSTM takes word embeddings as inputs, and outputs hidden states# with dimensionality hidden_dim.self.lstm = nn.LSTM(input_features, hidden_dim, batch_first=True)# The linear layer that maps from hidden state space to classesself.linear = nn.Linear(hidden_dim, TOT_ACTION_CLASSES)def forward(self, x):# invoke lstm layerlstm_out, (ht, ct) = self.lstm(x)# invoke linear layerreturn self.linear(ht[-1])def training_step(self, batch, batch_idx):# get data and labels from batchx, y = batch# reduce dimensiony = torch.squeeze(y)# convert to longy = y.long()# get predictiony_pred = self(x)# calculate lossloss = F.cross_entropy(y_pred, y)# get probability score using softmaxprob = F.softmax(y_pred, dim=1)# get the index of the max probabilitypred = prob.data.max(dim=1)[1]# calculate accuracyacc = torchmetrics.functional.accuracy(pred, y)dic = {'batch_train_loss': loss,'batch_train_acc': acc}# log the metrics for pytorch lightning progress bar or any other operationsself.log('batch_train_loss', loss, prog_bar=True)self.log('batch_train_acc', acc, prog_bar=True)#return loss and dictreturn {'loss': loss, 'result': dic}def training_epoch_end(self, training_step_outputs):# calculate average training loss end of the epochavg_train_loss = torch.tensor([x['result']['batch_train_loss'] for x in training_step_outputs]).mean()# calculate average training accuracy end of the epochavg_train_acc = torch.tensor([x['result']['batch_train_acc'] for x in training_step_outputs]).mean()# log the metrics for pytorch lightning progress bar and any further processingself.log('train_loss', avg_train_loss, prog_bar=True)self.log('train_acc', avg_train_acc, prog_bar=True)def validation_step(self, batch, batch_idx):# get data and labels from batchx, y = batch# reduce dimensiony = torch.squeeze(y)# convert to longy = y.long()# get predictiony_pred = self(x)# calculate lossloss = F.cross_entropy(y_pred, y)# get probability score using softmaxprob = F.softmax(y_pred, dim=1)# get the index of the max probabilitypred = prob.data.max(dim=1)[1]# calculate accuracyacc = torchmetrics.functional.accuracy(pred, y)dic = {'batch_val_loss': loss,'batch_val_acc': acc}# log the metrics for pytorch lightning progress bar and any further processingself.log('batch_val_loss', loss, prog_bar=True)self.log('batch_val_acc', acc, prog_bar=True)#return dictreturn dicdef validation_epoch_end(self, validation_step_outputs):# calculate average validation loss end of the epochavg_val_loss = torch.tensor([x['batch_val_loss']for x in validation_step_outputs]).mean()# calculate average validation accuracy end of the epochavg_val_acc = torch.tensor([x['batch_val_acc']for x in validation_step_outputs]).mean()# log the metrics for pytorch lightning progress bar and any further processingself.log('val_loss', avg_val_loss, prog_bar=True)self.log('val_acc', avg_val_acc, prog_bar=True)def configure_optimizers(self):# adam optimiseroptimizer = optim.Adam(self.parameters(), lr=self.hparams.learning_rate)# learning rate reducer schedulerscheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.5, patience=10, min_lr=1e-15, verbose=True)# scheduler reduces learning rate based on the value of val_loss metricreturn {"optimizer": optimizer,"lr_scheduler": {"scheduler": scheduler, "interval": "epoch", "frequency": 1, "monitor": "val_loss"}}

3. Web 应用

我们的web应用程序有几个已定义的路由。下面的程序处理输入视频。当用户从网页中提交视频进行分析时,该路由将被调用。

# route definition for video upload for analysis
@app.route('/analyze/<filename>')
def analyze(filename):# invokes method analyse_videoreturn Response(analyse_video(pose_detector, lstm_classifier, filename), mimetype='text/event-stream')

4. 视频分析

一旦我们的web应用程序接收到用户发来的视频,

  • 下面的函数对视频进行解析,调用:关键点检测调用Dectron2,动作分类调用LSTM。你可以看到,我们已经使用' buffer_window '来存储帧的32个连续的关键点结果,同样也用于推断动作类。
  • 接下来,我们使用OpenCV读取输入视频,并根据分类结果和姿态估计结果创建输出视频

如果你想要一个更高的FPS速率用于视频分析,你可以为SKIP_FRAME_COUNT配置一个更高的值。

# how many frames to skip while inferencing
# configuring a higher value will result in better FPS (frames per rate), but accuracy might get impacted
SKIP_FRAME_COUNT = 0# analyse the video
def analyse_video(pose_detector, lstm_classifier, video_path):# open the videocap = cv2.VideoCapture(video_path)# width of image framewidth = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))# height of image frameheight = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))# frames per second of the input videofps = int(cap.get(cv2.CAP_PROP_FPS))# total number of frames in the videotot_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))# video output codecfourcc = cv2.VideoWriter_fourcc(*'mp4v')# extract the file name from video pathfile_name = ntpath.basename(video_path)# video writervid_writer = cv2.VideoWriter('res_{}'.format(file_name), fourcc, 30, (width, height))# countercounter = 0# buffer to keep the output of detectron2 pose estimationbuffer_window = []# start timestart = time.time()    label = None# iterate through the videowhile True:# read the frameret, frame = cap.read()# return if end of the videoif ret == False:break# make a copy of the frameimg = frame.copy()if(counter % (SKIP_FRAME_COUNT+1) == 0):             # predict pose estimation on the frameoutputs = pose_detector(frame)          # filter the outputs with a good confidence scorepersons, pIndicies = filter_persons(outputs)if len(persons) >= 1:# pick only pose estimation results of the first person.# actually, we expect only one person to be present in the video. p = persons[0]# draw the body joints on the person bodydraw_keypoints(p, img)# input feature array for lstmfeatures = []# add pose estimate results to the feature arrayfor i, row in enumerate(p):features.append(row[0])features.append(row[1])# append the feature array into the buffer# not that max buffer size is 32 and buffer_window operates in a sliding window fashionif len(buffer_window) < WINDOW_SIZE:buffer_window.append(features)else:# convert input to tensormodel_input = torch.Tensor(np.array(buffer_window, dtype=np.float32))# add extra dimensionmodel_input = torch.unsqueeze(model_input, dim=0)# predict the action class using lstmy_pred = lstm_classifier(model_input)prob = F.softmax(y_pred, dim=1)# get the index of the max probabilitypred_index = prob.data.max(dim=1)[1]# pop the first value from buffer_window and add the new entry in FIFO fashion, to have a sliding window of size 32.buffer_window.pop(0)buffer_window.append(features)label = LABELS[pred_index.numpy()[0]]#print("Label detected ", label)# add predicted label into the frameIf label is not None:
cv2.putText(img, 'Action: {}'.format(label),(int(width-400), height-50), cv2.FONT_HERSHEY_COMPLEX, 0.9, (102, 255, 255), 2)                  # increment countercounter += 1# write the frame into the result video                    vid_writer.write(img)# compute the completion percentagepercentage = int(counter*100/tot_frames)# return the completion percentageyield "data:" + str(percentage) + "\n\n"analyze_done = time.time()print("Video processing finished in ", analyze_done - start)

应用程序运行结果

你需要一个带GPU的环境来运行这些ML模型。

结论

  • 学习了所有与人类行为识别有关的知识,也了解了它们的各种应用
  • 接下来,我们讨论了如何创建用于动作识别的应用程序。
  • 当我们详细介绍了Detectron2和LSTM的性能后,您很清楚我们为什么选择它们作为我们的解决方案。
  • 然后,您学习了使用PyTorch Lightning根据关键点训练LSTM模型进行动作分类。你看到了32帧连续序列如何帮助识别特定的动作。
  • 然后我们使用Detectron2和LSTM的组合进行推理。您了解到,所显示的结果实际上是由在输入视频上注释的推理管道检测到的操作。
  • 理解为什么FPS必须为实时视频流推断而优化。为此,您探索了各种方法,如模型的修剪和量化、间隔跳过帧和推断,以及多线程。
  • 接下来,您详细研究了应用程序中所有重要组件的给定代码。
  • 最后,我们构建了一个基于flask的示例web应用程序,用于对任何视频输入进行推理。

源码下载


http://chatgpt.dhexx.cn/article/3EyrTXeB.shtml

相关文章

短视频动作识别技术简述

1总体介绍 短视频在当前多媒体环境中占据着巨大流量&#xff0c;有效理解视频内容对于数据分发发挥着重要作用&#xff0c;动作识别是视频内容理解的一个重要方向。当前图像识别技术已趋于成熟&#xff0c;但动作识别仍未达到理想效果&#xff0c;相比于图像识别&#xff0c;动…

动作识别01:Understanding action recognition in still images

文章目录 摘要一、引言二、相关工作三、实验3.1 定义交互功能 四、结果总结 摘要 静止图像中的动作识别与姿态估计、目标识别、图像检索、视频动作识别和视频帧标记等计算机视觉任务密切相关。这个问题的重点是用单一的框架识别一个人的动作或行为。与视频中的动作识别不同——…

mediapipe 实现动作识别

环境 windows 10 64bitmediapipe 0.8.10.1 前言 本文使用 google 家的 mediapipe 机器学习框架&#xff0c;结合 opencv 和 numpy&#xff0c;实现了一个实时识别 站立、坐下、走动、挥手 共4个动作的简单系统。 mediapipe 能做的事情非常多&#xff0c;感兴趣的童鞋可以去研究…

行为动作识别

一、跌倒检测数据集 随着计算机学科与人工智能的发展和应用&#xff0c;视频分析技术迅速兴起并得到了广泛关注。视频分析中的一个核心就是人体行为识别&#xff0c;行为识别的准确性和快速性将直接影响视频分析系统后续工作的结果。因此&#xff0c;如何提高视频中人体行为识别…

基于骨骼的动作识别:PoseConv3D

Revisiting Skeleton-based Action Recognition解读 摘要1. 简介2. Related Work2.1 基于3D-CNN的rgb视频动作识别2.2 基于GCN的骨骼动作识别2.3 基于CNN的骨骼动作识别 3. Framework3.1 Pose Extraction3.2 From 2D Poses to 3D Heatmap Volumes3.3 基于骨骼的动作识别3D-CNN3…

视频动作识别调研(Action Recognition)

视频动作识别调研&#xff08;Action Recognition&#xff09; 本文首发于微信公众号“ StrongerTang”&#xff0c;可打开微信搜一搜&#xff0c;或扫描文末二维码&#xff0c;关注查看更多文章。 原文链接&#xff1a;( https://mp.weixin.qq.com/s?__bizMzg3NDEzOTAzMw&…

动作识别概况

文章目录 一、动作识别二、动作识别的难点三、动作识别现在常用的方法四、行为识别的两个方向五、常用数据集六、常用框架介绍 一、动作识别 主要目标是判断一段视频中人的行为的类别&#xff0c;所以也可以叫做 Human Action Recognition。 二、动作识别的难点 1.类内和类之…

动作/行为识别调研

动作识别调研 1. 简介1.1 基本概念1.2 难点 2. 人体动作识别系统2.1 传统方法2.1.1 iDT框架 2.2 深度学习方法2.2.1 Two-Stream双流架构2.2.2 3D卷积架构2.2.3 CNNLSTM架构2.2.4 GCN架构 相关文献 1. 简介 动作识别(Action Recognition)&#xff0c;就是从视频片段&#xff08…

2022广州大学计算机网络实验--使用网络协议分析器捕捉和分析协议数据包

广州大学学生实验报告 开课学院及实验室&#xff1a;计算机科学与工程实验室 2022年**月**日 学院 计算机科学与教育软件 年级、专业、班 ****** 姓名 **** 学号 *******39 实验课程名称 计算机网络实验 成绩 实验项目名称 使用网络协议分析器…

五个好用的网络协议分析工具(附下载地址)

Network Packet Analyzer&#xff0c;是一种网络分析程序&#xff0c;可以帮助网络管理员捕获、交互式浏览网络中传输的数据包和分析数据包信息等。这里给出了5个最好的网络数据包分析工具&#xff0c;具体如下&#xff1a; 1. Wireshark 相信大家都很熟悉&#xff0c;就不多…

网络协议安全分析

网络安全层次结构 物理层 在通信线路上保障不被搭线&#xff0c;不被偷听&#xff0c;尽可能检测出来。 数据链路层 a.点对点的链路上可以采用通信保密机进行加解密。 b.由第层硬件完成&#xff0c;对上层透明。 c.缺陷&#xff1a;无法适应多个路由器的网络&#xff0c;尤其I…

各网络协议分析

IP ip头 ![Image][IPstr] Wireshark ![Image][IPstr2] 名称值含义可选值占位IP版本0100IPV40110:IPV64bit头部长度010120bytes(5)可表示的最大值为1111(60bytes(15))4bit服务类型0x00默认转发(DF)8bit总长度52首部和数据之和最大为2^16-165535字节16bit标识0x239d它是一个…

网络协议分析(结合版)

初识协议 1.什么是协议&#xff1f; 数据从源地点传输到目的地点&#xff0c;网络上所有设备需要“讲”相同的“语言”。 描述网络通信中如何规范使用“语言” 的一组规则就是协议。 2.数据通信协议: 决定数据的格式和数据的传输的一组规则或者一组惯例 协议分层 ARP协议 …

计算机网络--使用网络协议分析器捕捉和分析协议数据包

实验目的 &#xff08;1&#xff09;、 熟悉ethereal的使用 &#xff08;2&#xff09;、 验证各种协议数据包格式 &#xff08;3&#xff09;、 学会捕捉并分析各种数据包。 实验环境 Window 10&#xff0c;ethereal&#xff0c;winpcap 实验内容 &#xff08;1&#xff…

网络协议分析-TCP协议分析

目录 一 . TCP协议的应用二 . TCP包结构三 . 实例化 一 . TCP协议的应用 二 . TCP包结构 源端口号&#xff08; 16 位&#xff09;&#xff1a;它&#xff08;连同源主机 IP 地址&#xff09;标识源主机的一个应用进程。 目的端口号&#xff08; 16 位&#xff09;&#xff1a…

计算机网络 实验三 使用网络协议分析器捕捉和分析协议数据包

学院 计算机学院 年级、专业、班 软件工程 姓名 涂山 学号 170****** 实验课程名称 计算机网络实验 成绩 实验项目名称 使用网络协议分析器捕捉和分析协议数据包 指导老师 &#xff08;1&#xff09;实验目的…

实例:使用网络分析仪进行电缆测试

本应用测试针对非标称50Ω的线缆&#xff0c;包括同轴、双绞线、差分高速数据线的测试&#xff0c;包括阻抗参数、S参数&#xff08;插损、驻波、Smith图等等&#xff09;&#xff0c;也可以绘制眼图。 根据电缆的性能&#xff0c;如频率范围、长度、是否差分&#xff0c;设置…

协议数据分析

实验目的 了解协议分析仪的使用方法和基本特点。 增强对网络协议的理解。 实验要求 要求在进行协议数据分析后&#xff0c;能够将网络数据与具体的网络操作相互映证&#xff0c;如实的记录实验结果&#xff0c;完成实验 实验环境 1&#xff0e;一台运行Windows 2000的计…

五个好用的网络协议分析工具

Network Packet Analyzer&#xff0c;是一种网络分析程序&#xff0c;可以帮助网络管理员捕获、交互式浏览网络中传输的数据包和分析数据包信息等。这里给出了5个最好的网络数据包分析工具&#xff0c;具体如下&#xff1a; 1. Wireshark 相信大家都很熟悉&#xff0c;就不多介…

【计算机网络】IP协议分析

实验目的 应用所学知识&#xff1a; ①熟悉IP报文格式以及关键字段含义。 ②掌握IP地址的分配方法。 ③理解路由器转发IP数据报的流程。 实验步骤与结果 1.任务一&#xff1a;观察路由表 打开Router0命令行输入指令查看路由表&#xff1a; Router0存在三条直接路由&#xf…