YOLOv10改进策略【注意力机制篇】| 2024 SCI TOP FCAttention 即插即用注意力模块,增强局部和全局特征信息交互

server/2024/10/9 6:11:21/

一、本文介绍

本文记录的是基于FCAttention模块的YOLOv10目标检测改进方法研究FCAttention是图像去雾领域新提出的模块能够有效整合全局和局部信息、合理分配权重的通道注意力机制,使得网络能够更准确地强调有用特征,抑制不太有用的特征,在目标检测领域中同样有效。

文章目录

  • 一、本文介绍
  • 二、FCA原理
    • 2.1 原理
    • 2.2 优势
  • 三、FCAttention的实现代码
  • 四、创新模块
    • 4.1 改进点1
    • 4.2 改进点2⭐
  • 五、添加步骤
    • 5.1 修改ultralytics/nn/modules/block.py
    • 5.2 修改ultralytics/nn/modules/__init__.py
    • 5.3 修改ultralytics/nn/modules/tasks.py
  • 六、yaml模型文件
    • 6.1 模型改进版本一
    • 6.2 模型改进版本二⭐
  • 七、成功运行结果


二、FCA原理

用于图像去雾的无监督双向对比重建和自适应细粒度通道注意网络

FCA(Adaptive Fine - Grained Channel Attention)模块设计的原理及优势如下:

2.1 原理

  • 特征图处理:首先,对包含全局空间信息的特征图F进行全局平均池化,将其转换为通道描述符U,用于获取通道信息。具体公式为: U n = G A P ( F n ) = 1 H × W ∑ i = 1 H ∑ j = 1 W F n ( i , j ) U_{n}=GAP(F_{n})=\frac{1}{H×W}\sum_{i=1}^{H}\sum_{j=1}^{W}F_{n}(i, j) Un=GAP(Fn)=H×W1i=1Hj=1WFn(i,j),其中 F ∈ R C × H × W F \in \mathbb{R}^{C×H×W} FRC×H×W C C C H H H W W W分别代表通道数、长度和宽度, U ∈ R C U \in \mathbb{R}^{C} URC G A P ( x ) GAP(x) GAP(x)为全局平均 pooling 函数。
  • 局部信息获取:为了在获取少量模型参数的同时获得局部通道信息,使用带矩阵B进行局部通道交互,设置 B = [ b 1 , b 2 , b 3 , . . . , b k ] B=[b_{1}, b_{2}, b_{3},..., b_{k}] B=[b1,b2,b3,...,bk],通过 U l c = ∑ i = 1 k U ⋅ b i U_{lc}=\sum_{i=1}^{k}U\cdot b_{i} Ulc=i=1kUbi计算局部信息 U l c U_{lc} Ulc,其中 U U U为通道描述符, k k k为相邻通道数。
  • 全局信息获取:利用对角矩阵D捕获所有通道之间的依赖关系作为全局信息,设置 D = [ d 1 , d 2 , d 3 , . . . , d c ] D=[d_{1}, d_{2}, d_{3},..., d_{c}] D=[d1,d2,d3,...,dc],通过 U g c = ∑ i = 1 c U ⋅ d i U_{gc}=\sum_{i=1}^{c}U\cdot d_{i} Ugc=i=1cUdi计算全局信息 U g c U_{gc} Ugc,其中 c c c为通道数。
  • 相关性捕获:通过交叉相关操作将全局信息 U g c U_{gc} Ugc与局部信息 U l c U_{lc} Ulc相结合,得到相关性矩阵 M = U g c ⋅ U l c T M = U_{gc}\cdot U_{lc}^{T} M=UgcUlcT,以捕获两者在不同粒度上的相关性。
  • 自适应融合:从相关性矩阵及其转置中提取行和列信息作为全局和局部信息的权重向量,通过可学习因子实现动态融合。具体公式为: U g c w = ∑ j c M i , j , i ∈ 1 , 2 , 3... c U_{gc}^{w}=\sum_{j}^{c}M_{i, j}, i \in 1,2,3...c Ugcw=jcMi,j,i1,2,3...c U l c w = ∑ j c ( U l c ⋅ U g c T ) i , j = ∑ j c M i , j T , i ∈ 1 , 2 , 3... c U_{lc}^{w}=\sum_{j}^{c}(U_{lc}\cdot U_{gc}^{T})_{i, j}=\sum_{j}^{c}M^{T}_{i, j}, i \in 1,2,3...c Ulcw=jc(UlcUgcT)i,j=jcMi,jT,i1,2,3...c W = σ ( σ ( θ ) × σ ( U g c w ) + ( 1 − σ ( θ ) ) × σ ( U l c w ) ) W=\sigma(\sigma(\theta)×\sigma(U_{gc}^{w})+(1 - \sigma(\theta))×\sigma(U_{lc}^{w})) W=σ(σ(θ)×σ(Ugcw)+(1σ(θ))×σ(Ulcw)),其中KaTeX parse error: Can't use function '\)' in math mode at position 11: U_{gc}^{w}\̲)̲和\(U_{lc}^{w}为融合后的全局和局部通道权重, θ \theta θ表示sigmoid激活函数。
  • 权重应用:将得到的权重与输入特征图相乘,得到最终输出特征图,即 τ ∗ = W ⊗ F \tau^{*}=W \otimes F τ=WF,其中 F F F为输入特征图, F ∗ F^{*} F为最终输出特征图。

在这里插入图片描述

2.2 优势

  • 有效整合信息:能够有效整合全局和局部信息,通过相关性矩阵捕获两者在不同粒度上的相关性,促进了全局和局部信息的有效交互。
  • 合理分配权重:采用自适应融合策略,避免了局部和全局信息之间冗余的交叉相关操作,进一步促进了它们的交互,能够更精确地为去雾相关特征分配权重。
  • 提升去雾性能:在网络去雾过程中,充分利用全局和局部通道信息,提高了网络去雾性能,使得网络能够更准确地强调有用特征,抑制不太有用的特征。

论文:https://doi.org/10.1016/j.neunet.2024.106314
源码:https://github.com/Lose-Code/UBRFC-Net

三、FCAttention的实现代码

FCAttention模块的实现代码如下:

class Mix(nn.Module):def __init__(self, m=-0.80):super(Mix, self).__init__()w = torch.nn.Parameter(torch.FloatTensor([m]), requires_grad=True)w = torch.nn.Parameter(w, requires_grad=True)self.w = wself.mix_block = nn.Sigmoid()def forward(self, fea1, fea2):mix_factor = self.mix_block(self.w)out = fea1 * mix_factor.expand_as(fea1) + fea2 * (1 - mix_factor.expand_as(fea2))return outclass FCAttention(nn.Module):def __init__(self,channel,b=1, gamma=2):super(FCAttention, self).__init__()self.avg_pool = nn.AdaptiveAvgPool2d(1)#全局平均池化#一维卷积t = int(abs((math.log(channel, 2) + b) / gamma))k = t if t % 2 else t + 1self.conv1 = nn.Conv1d(1, 1, kernel_size=k, padding=int(k / 2), bias=False)self.fc = nn.Conv2d(channel, channel, 1, padding=0, bias=True)self.sigmoid = nn.Sigmoid()self.mix = Mix()def forward(self, input):x = self.avg_pool(input)x1 = self.conv1(x.squeeze(-1).transpose(-1, -2)).transpose(-1, -2)#(1,64,1)x2 = self.fc(x).squeeze(-1).transpose(-1, -2)#(1,1,64)out1 = torch.sum(torch.matmul(x1,x2),dim=1).unsqueeze(-1).unsqueeze(-1)#(1,64,1,1)#x1 = x1.transpose(-1, -2).unsqueeze(-1)out1 = self.sigmoid(out1)out2 = torch.sum(torch.matmul(x2.transpose(-1, -2),x1.transpose(-1, -2)),dim=1).unsqueeze(-1).unsqueeze(-1)#out2 = self.fc(x)out2 = self.sigmoid(out2)out = self.mix(out1,out2)out = self.conv1(out.squeeze(-1).transpose(-1, -2)).transpose(-1, -2).unsqueeze(-1)out = self.sigmoid(out)return input*out

四、创新模块

4.1 改进点1

模块改进方法1️⃣:直接加入FCAttention模块
FCAttention模块添加后如下:

在这里插入图片描述

注意❗:在5.2和5.3小节中需要声明的模块名称为:FCAttention

4.2 改进点2⭐

模块改进方法2️⃣:基于FCAttention模块C2f

第二种改进方法是对YOLOv10中的C2f模块进行改进,将FCAttention注意力模块加入后,能够充分利用全局和局部通道信息,使得网络能够更准确地强调有用特征,抑制不太有用的特征。并且其中的自适应融合策略,避免了局部和全局信息之间冗余的交叉相关操作,进一步促进了它们的交互,能够更精确地进行特征分配权重。

改进代码如下:

class C2f_FCA(nn.Module):"""Faster Implementation of CSP Bottleneck with 2 convolutions."""def __init__(self, c1, c2, n=1, shortcut=False, g=1, e=0.5):"""Initialize CSP bottleneck layer with two convolutions with arguments ch_in, ch_out, number, shortcut, groups,expansion."""super().__init__()self.c = int(c2 * e)  # hidden channelsself.cv1 = Conv(c1, 2 * self.c, 1, 1)self.cv2 = Conv((2 + n) * self.c, c2, 1)  # optional act=FReLU(c2)self.m = nn.ModuleList(Bottleneck(self.c, self.c, shortcut, g, k=((3, 3), (3, 3)), e=1.0) for _ in range(n))self.att = FCAttention(c2)def forward(self, x):"""Forward pass through C2f layer."""y = list(self.cv1(x).chunk(2, 1))y.extend(m(y[-1]) for m in self.m)return self.att(self.cv2(torch.cat(y, 1)))def forward_split(self, x):"""Forward pass using split() instead of chunk()."""y = list(self.cv1(x).split((self.c, self.c), 1))y.extend(m(y[-1]) for m in self.m)return self.att(self.cv2(torch.cat(y, 1)))

在这里插入图片描述

注意❗:在5.2和5.3小节中需要声明的模块名称为:C2f_FCA


五、添加步骤

5.1 修改ultralytics/nn/modules/block.py

此处需要修改的文件是ultralytics/nn/modules/block.py

block.py中定义了网络结构的通用模块,我们想要加入新的模块就只需要将模块代码放到这个文件内即可。

FCAttentionC2f_FCA模块代码添加到此文件下。

5.2 修改ultralytics/nn/modules/init.py

此处需要修改的文件是ultralytics/nn/modules/__init__.py

__init__.py文件中定义了所有模块的初始化,我们只需要将block.py中的新的模块命添加到对应的函数即可。

FCAttentionC2f_FCAblock.py中实现,所有要添加在from .block import

from .block import (C1,C2,...FCAttention,C2f_FCA
)

在这里插入图片描述

5.3 修改ultralytics/nn/modules/tasks.py

tasks.py文件中,需要在两处位置添加各模块类名称。

首先:在函数声明中引入FCAttentionC2f_FCA

在这里插入图片描述

在这里插入图片描述

其次:在parse_model函数中注册FCAttentionC2f_FCA模块

在这里插入图片描述

在这里插入图片描述


六、yaml模型文件

6.1 模型改进版本一

在代码配置完成后,配置模型的YAML文件。

此处以ultralytics/cfg/models/v10/yolov10m.yaml为例,在同目录下创建一个用于自己数据集训练的模型文件yolov10m-FCA.yaml

yolov10m.yaml中的内容复制到yolov10m-FCA.yaml文件下,修改nc数量等于自己数据中目标的数量。
在骨干网络的最后一层添加FCAttention模块只需要填入一个参数,通道数

# Ultralytics YOLO 🚀, AGPL-3.0 license
# YOLOv8 object detection model with P3-P5 outputs. For Usage examples see https://docs.ultralytics.com/tasks/detect# Parameters
nc: 1 # number of classes
scales: # model compound scaling constants, i.e. 'model=yolov8n.yaml' will call yolov8.yaml with scale 'n'# [depth, width, max_channels]m: [0.67, 0.75, 768] # YOLOv8m summary: 295 layers, 25902640 parameters, 25902624 gradients,  79.3 GFLOPs# YOLOv8.0n backbone
backbone:# [from, repeats, module, args]- [-1, 1, Conv, [64, 3, 2]] # 0-P1/2- [-1, 1, Conv, [128, 3, 2]] # 1-P2/4- [-1, 3, C2f, [128, True]]- [-1, 1, Conv, [256, 3, 2]] # 3-P3/8- [-1, 6, C2f, [256, True]]- [-1, 1, SCDown, [512, 3, 2]] # 5-P4/16- [-1, 6, C2f, [512, True]]- [-1, 1, SCDown, [1024, 3, 2]] # 7-P5/32- [-1, 3, C2fCIB, [1024, True]]- [-1, 1, FCAttention, [1024]]- [-1, 1, SPPF, [1024, 5]] # 10- [-1, 1, PSA, [1024]] # 11# YOLOv8.0n head
head:- [-1, 1, nn.Upsample, [None, 2, "nearest"]]- [[-1, 6], 1, Concat, [1]] # cat backbone P4- [-1, 3, C2f, [512]] # 14- [-1, 1, nn.Upsample, [None, 2, "nearest"]]- [[-1, 4], 1, Concat, [1]] # cat backbone P3- [-1, 3, C2f, [256]] # 17 (P3/8-small)- [-1, 1, Conv, [256, 3, 2]]- [[-1, 14], 1, Concat, [1]] # cat head P4- [-1, 3, C2fCIB, [512, True]] # 20 (P4/16-medium)- [-1, 1, SCDown, [512, 3, 2]]- [[-1, 11], 1, Concat, [1]] # cat head P5- [-1, 3, C2fCIB, [1024, True]] # 23 (P5/32-large)- [[17, 20, 23], 1, v10Detect, [nc]] # Detect(P3, P4, P5)

6.2 模型改进版本二⭐

此处同样以ultralytics/cfg/models/v10/yolov10m.yaml为例,在同目录下创建一个用于自己数据集训练的模型文件yolov10m-C2f_FCA.yaml

yolov10m.yaml中的内容复制到yolov10m-C2f_FCA.yaml文件下,修改nc数量等于自己数据中目标的数量。

📌 模型的修改方法是将骨干网络中的所有C2f模块替换成C2f_FCA模块

# Ultralytics YOLO 🚀, AGPL-3.0 license
# YOLOv8 object detection model with P3-P5 outputs. For Usage examples see https://docs.ultralytics.com/tasks/detect# Parameters
nc: 1 # number of classes
scales: # model compound scaling constants, i.e. 'model=yolov8n.yaml' will call yolov8.yaml with scale 'n'# [depth, width, max_channels]m: [0.67, 0.75, 768] # YOLOv8m summary: 295 layers, 25902640 parameters, 25902624 gradients,  79.3 GFLOPs# YOLOv8.0n backbone
backbone:# [from, repeats, module, args]- [-1, 1, Conv, [64, 3, 2]] # 0-P1/2- [-1, 1, Conv, [128, 3, 2]] # 1-P2/4- [-1, 3, C2f_FCA, [128, True]]- [-1, 1, Conv, [256, 3, 2]] # 3-P3/8- [-1, 6, C2f_FCA, [256, True]]- [-1, 1, SCDown, [512, 3, 2]] # 5-P4/16- [-1, 6, C2f_FCA, [512, True]]- [-1, 1, SCDown, [1024, 3, 2]] # 7-P5/32- [-1, 3, C2fCIB, [1024, True]]- [-1, 1, SPPF, [1024, 5]] # 9- [-1, 1, PSA, [1024]] # 10# YOLOv8.0n head
head:- [-1, 1, nn.Upsample, [None, 2, "nearest"]]- [[-1, 6], 1, Concat, [1]] # cat backbone P4- [-1, 3, C2f, [512]] # 13- [-1, 1, nn.Upsample, [None, 2, "nearest"]]- [[-1, 4], 1, Concat, [1]] # cat backbone P3- [-1, 3, C2f, [256]] # 16 (P3/8-small)- [-1, 1, Conv, [256, 3, 2]]- [[-1, 13], 1, Concat, [1]] # cat head P4- [-1, 3, C2fCIB, [512, True]] # 19 (P4/16-medium)- [-1, 1, SCDown, [512, 3, 2]]- [[-1, 10], 1, Concat, [1]] # cat head P5- [-1, 3, C2fCIB, [1024, True]] # 22 (P5/32-large)- [[16, 19, 22], 1, v10Detect, [nc]] # Detect(P3, P4, P5)

七、成功运行结果

分别打印网络模型可以看到FCA模块C2f_FCA已经加入到模型中,并可以进行训练了。

yolov10m-FCA

                   from  n    params  module                                       arguments                     0                  -1  1      1392  ultralytics.nn.modules.conv.Conv             [3, 48, 3, 2]                 1                  -1  1     41664  ultralytics.nn.modules.conv.Conv             [48, 96, 3, 2]                2                  -1  2    111360  ultralytics.nn.modules.block.C2f             [96, 96, 2, True]             3                  -1  1    166272  ultralytics.nn.modules.conv.Conv             [96, 192, 3, 2]               4                  -1  4    813312  ultralytics.nn.modules.block.C2f             [192, 192, 4, True]           5                  -1  1     78720  ultralytics.nn.modules.block.SCDown          [192, 384, 3, 2]              6                  -1  4   3248640  ultralytics.nn.modules.block.C2f             [384, 384, 4, True]           7                  -1  1    228672  ultralytics.nn.modules.block.SCDown          [384, 576, 3, 2]              8                  -1  2   1689984  ultralytics.nn.modules.block.C2fCIB          [576, 576, 2, True]           9                  -1  1    332646  ultralytics.nn.modules.block.FCAttention     [576, 576]                    10                  -1  1    831168  ultralytics.nn.modules.block.SPPF            [576, 576, 5]                 11                  -1  1   1253088  ultralytics.nn.modules.block.PSA             [576, 576]                    12                  -1  1         0  torch.nn.modules.upsampling.Upsample         [None, 2, 'nearest']          13             [-1, 6]  1         0  ultralytics.nn.modules.conv.Concat           [1]                           14                  -1  2   1993728  ultralytics.nn.modules.block.C2f             [960, 384, 2]                 15                  -1  1         0  torch.nn.modules.upsampling.Upsample         [None, 2, 'nearest']          16             [-1, 4]  1         0  ultralytics.nn.modules.conv.Concat           [1]                           17                  -1  2    517632  ultralytics.nn.modules.block.C2f             [576, 192, 2]                 18                  -1  1    332160  ultralytics.nn.modules.conv.Conv             [192, 192, 3, 2]              19            [-1, 14]  1         0  ultralytics.nn.modules.conv.Concat           [1]                           20                  -1  2    831744  ultralytics.nn.modules.block.C2fCIB          [576, 384, 2, True]           21                  -1  1    152448  ultralytics.nn.modules.block.SCDown          [384, 384, 3, 2]              22            [-1, 11]  1         0  ultralytics.nn.modules.conv.Concat           [1]                           23                  -1  2   1911168  ultralytics.nn.modules.block.C2fCIB          [960, 576, 2, True]           24        [17, 20, 23]  1   2282134  ultralytics.nn.modules.head.v10Detect        [1, [192, 384, 576]]          
YOLOv10m-FCA summary: 505 layers, 16817932 parameters, 16817916 gradients, 64.0 GFLOPs

yolov10m-C2f_FCA

                   from  n    params  module                                       arguments                     0                  -1  1      1392  ultralytics.nn.modules.conv.Conv             [3, 48, 3, 2]                 1                  -1  1     41664  ultralytics.nn.modules.conv.Conv             [48, 96, 3, 2]                2                  -1  2    148808  ultralytics.nn.modules.block.C2f_FCA         [96, 96, True]                3                  -1  1    166272  ultralytics.nn.modules.conv.Conv             [96, 192, 3, 2]               4                  -1  4   1185048  ultralytics.nn.modules.block.C2f_FCA         [192, 192, True]              5                  -1  1     78720  ultralytics.nn.modules.block.SCDown          [192, 384, 3, 2]              6                  -1  4   4729368  ultralytics.nn.modules.block.C2f_FCA         [384, 384, True]              7                  -1  1    228672  ultralytics.nn.modules.block.SCDown          [384, 576, 3, 2]              8                  -1  2   1689984  ultralytics.nn.modules.block.C2fCIB          [576, 576, 2, True]           9                  -1  1    831168  ultralytics.nn.modules.block.SPPF            [576, 576, 5]                 10                  -1  1   1253088  ultralytics.nn.modules.block.PSA             [576, 576]                    11                  -1  1         0  torch.nn.modules.upsampling.Upsample         [None, 2, 'nearest']          12             [-1, 6]  1         0  ultralytics.nn.modules.conv.Concat           [1]                           13                  -1  2   1993728  ultralytics.nn.modules.block.C2f             [960, 384, 2]                 14                  -1  1         0  torch.nn.modules.upsampling.Upsample         [None, 2, 'nearest']          15             [-1, 4]  1         0  ultralytics.nn.modules.conv.Concat           [1]                           16                  -1  2    517632  ultralytics.nn.modules.block.C2f             [576, 192, 2]                 17                  -1  1    332160  ultralytics.nn.modules.conv.Conv             [192, 192, 3, 2]              18            [-1, 13]  1         0  ultralytics.nn.modules.conv.Concat           [1]                           19                  -1  2    831744  ultralytics.nn.modules.block.C2fCIB          [576, 384, 2, True]           20                  -1  1    152448  ultralytics.nn.modules.block.SCDown          [384, 384, 3, 2]              21            [-1, 10]  1         0  ultralytics.nn.modules.conv.Concat           [1]                           22                  -1  2   1911168  ultralytics.nn.modules.block.C2fCIB          [960, 576, 2, True]           23        [16, 19, 22]  1   2282134  ultralytics.nn.modules.head.v10Detect        [1, [192, 384, 576]]          
YOLOv10m-C2f_FCA summary: 627 layers, 18375198 parameters, 18375182 gradients, 70.7 GFLOPs

http://www.ppmy.cn/server/129135.html

相关文章

ffmpeg录制视频功能

本文目录 1.环境配置2.ffmpeg编解码的主要逻辑:3. 捕获屏幕帧与写入输出文件4. 释放资源 在录制结束时,释放所有分配的资源。5.自定义I/O上下文6.对于ACC编码器注意事项 1.环境配置 下载并安装FFmpeg库 在Windows上 从FFmpeg官方网站下载预编译的FFmpeg…

关系数据库标准语言SQL(11,12)

目录 带有EXISTS谓词的子查询 exists谓词 例子 not exists谓词 例子 不同形式的查询间的替换 用EXISTS/NOT EXISTS实现全称量词 用EXISTS/NOT EXISTS:实现逻辑蕴涵 集合查询 并操作UNION 交操作INTERSECT 差操作EXCEPT 基于派生表的查询 select语句的基本格式 带有…

为什么MySQL不建议使用delete删除数据

在MySQL数据库管理中,虽然DELETE语句是一个常用的操作,用于从表中删除记录,但在某些情况下,频繁使用DELETE删除数据可能会带来一系列潜在的问题。以下是对MySQL不建议使用DELETE删除数据的详细解释: 1. 磁盘空间浪费与…

pymupdf 解析 PDF

使用大模型处理文档时,需要对二进制格式的文档进转解析提取文字和图片,本文使用 pymupdf 开源库,对 PDF 进行解析提取文字和图片。 安装依赖 首先安装 pymupdf 依赖 pymupdf4llm0.0.17 pymupdf1.24.10 apscheduler3.10.4PDF 转 Markdown …

爱心曲线公式大全

local r a*((math.sin(angle) * math.sqrt(math.abs(math.cos(angle)))) / (math.sin(angle) 1.4142) - 2 * math.sin(angle) 2) local x r * math.cos(angle) -- 计算对应的x值 local z r * math.sin(angle) 1.5*a - --曲线公式绘画 local function generateParabola()…

一篇文章快速认识YOLO11 | 关键改进点 | 安装使用 | 模型训练和推理

前言 本文分享YOLO11的关键改进点、性能对比、安装使用、模型训练和推理等内容。 YOLO11 是 Ultralytics 最新的实时目标检测器,凭借更高的精度、速度和效率重新定义了可能性。 除了传统的目标检测外,YOLO11 还支持目标跟踪、实例分割、姿态估计、OBB…

【算法】- 查找 - 多路查找树(B树)

文章目录 前言一、多路查找树(B树)二、2-3树的查找2-3树查找代码 三、2-3树的插入2-3树代码 2-3树代码总结 前言 上次我们学了如何用平衡二叉树来插入和查找。这些算法都是在内存中进行,若我们要操作的数据非常大,大到内存没办法处…

无人机高精度地形测量技术详解!

一、无人机技术 无人机作为搭载各种高精度传感器的平台,能够在不同高度和角度进行灵活飞行,覆盖各种复杂地形和环境,实现地表信息的全方位获取。 二、高精度传感器技术 GPS/GLONASS等卫星定位系统:无人机通过卫星定位系统实现高…