恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
计算机视觉必考知识点:从图像滤波到目标检测的完整链路
首页
资讯中心
/
计算机视觉必考知识点:从图像滤波到目标检测的完整链路
计算机视觉必考知识点:从图像滤波到目标检测的完整链路
发布时间:2026/10/16 0:17:02
简介这份资料是2024年北京交通大学计算机视觉课程必考知识点汇总面向选修该课或正在备考的本科生归拢了图像滤波、特征提取、SIFT、CNN等40个核心考点。全文以问答形式展开对卷积与相关定义、高斯核参数选择、Canny细边缘获取、Harris角点原理、SIFT双塔结构与描述子生成、残差模块、R-CNN到Faster R-CNN演变等高频问题给出了精炼解析并穿插代数与几何视角解释分类器公式、损失函数及训练技巧适合考前速览、对照查漏补缺。资源为1个PDF文档压缩包约9.69MB已有665人学习下载。内容按考点序号编排重点突出、可直接背诵或作为复习提纲使用能帮助快速建立知识框架减少整理笔记的时间。1. 计算机视觉课程必考知识点为什么值得逐题推一遍一门研究生计算机视觉课程把必考知识点压缩成 45 个问题从图像滤波一路问到 Faster R-CNN听起来像是纯粹的应试材料。但你把这些考点逐个过一遍就会发现它把 CV 领域四十年的技术主线压缩成了一条完整链路滤波是图像处理的底层操作SIFT 是特征工程的巅峰CNN 是表示学习的转折目标检测则是把前面所有知识串起来综合题。这份计算机视觉课程必考知识点汇总适合两类人一类是临考的学生另一类是准备 CV 岗位面试、想快速复查知识体系的从业者。我照着它把每道题都推了一遍下面是按我的理解拆成的可复现笔记。2. 图像滤波与特征检测从相关卷积到 Canny 的三件套滤波是整份考点的地基。第一题到第八题看起来在考定义实际上考的是你对“一个核在图像上滑动时到底发生了什么”的理解。这部分概念不清后面 SIFT 的梯度直方图和 CNN 的卷积层都会跟着出问题。2.1 相关、卷积、内积三种定义的本质差别相关Correlation是模板覆盖区域内逐元素相乘再累加结果写在模板中心对应的图像位置。卷积Convolution是把模板旋转 180 度之后再重复相关操作。内积Inner Product则是把二维区域展平成向量再做点积。import numpy as np def correlate2d(img, kernel): kh, kw kernel.shape pad_h, pad_w kh // 2, kw // 2 # 边缘填充用 edge 模式避免边界像素被直接丢弃 img_pad np.pad(img, ((pad_h, pad_h), (pad_w, pad_w)), modeedge) out np.zeros_like(img, dtypenp.float32) for i in range(img.shape[0]): for j in range(img.shape[1]): # 模板覆盖区域内逐元素相乘再累加 out[i, j] np.sum(img_pad[i:ikh, j:jkw] * kernel) return out def convolve2d(img, kernel): # 卷积 把核沿两个轴同时翻转再做相关 return correlate2d(img, kernel[::-1, ::-1])这段代码里最容易被忽略的是kernel[::-1, ::-1]。这个翻转是沿行和列两个方向同时做的不是转置。旋转前后核的响应位置完全不同如果拿一个不对称的 Sobel 核去试结果差异立刻就能看出来。内积在数值上等同于模板与图像区域展平后的点积但它描述的是一种“两个向量之间的关系”而滤波描述的是“一个核在整幅图上滑动”的过程。工程上最常见的坑在这里主流深度学习框架里的“卷积层”实现的是相关而不是严格定义的卷积。原因是卷积核本身就是训练学出来的旋转不旋转对网络表达能力没有本质区别而实现相关可以直接复用矩阵乘法省掉一次翻转操作。面试里如果被问到这个点很能说明你真的上手写过而不是只背了定义。2.2 高斯核的 size 与 σ结果为什么相似、参数怎么定原题问“kernel 的 size 不同、σ 相同为什么结果类似”这是高斯核设计里一个很经典的反直觉现象。高斯核服从正态分布能量集中在均值附近3σ 之外的概率质量已经非常小。所以采样高斯核时尺寸取到 6σ 左右权重和已经趋近于 1核再大一倍多出来的那些位置的权重接近 0卷积结果自然没有明显变化。def gaussian_kernel(size, sigma): k (size - 1) / 2 x, y np.meshgrid(np.arange(-k, k1), np.arange(-k, k1)) # 二维高斯分布未归一化 g np.exp(-(x**2 y**2) / (2 * sigma**2)) return g / g.sum() # 归一化保证平滑不改变图像整体亮度参数设置上工程里常用的经验公式是size 2 * int(3 * sigma) 1也就是取 6σ 附近的最小奇数。σ 控制平滑程度σ 越小核越窄保留的细节越多σ 越大核越宽去噪越强但边缘也越模糊。size 只决定采样范围σ 才是真正影响滤波行为的参数。很多初学者只调 size 不调 σ或者反过来导致结果总是不对。2.3 滤波器组与 Harris 角点两组特征响应工具滤波器组Filter Bank是这一章的一个汇总性考点它把高斯核、LoG、高斯偏导核、高斯二阶偏导核放在一起对比。这几个滤波器的关系用下面这张表可以一次性理清滤波器图像处理用途视觉计算用途数学视角高斯核图像平滑检测斑点对图像求局部积分LoG图像锐化检测斑点先高斯平滑再求二阶偏导高斯偏导核边缘检测检测边与条带对高斯求一阶偏导后再卷积高斯二阶偏导核边缘检测检测边与条带对高斯求二阶偏导后再卷积高斯偏导核值得单独说一句它是“先平滑再去噪”和“求梯度”两个步骤的合并。直接在原图上用梯度算子做边缘检测噪声会被梯度放大得一塌糊涂先高斯平滑再求梯度会多一次卷积。把两步合成一个高斯偏导核等于用一次卷积完成两件事这是工程里常见的计算优化思路。Harris 算子的数学原理同样在这一组考点里。它的核心是把灰度变化公式里的 I(xu, yv) 做泰勒展开把 x、y 与 u、v 解耦最后得到一个二次型矩阵。这个矩阵是实对称矩阵可以做特征值分解两个特征值都大是角点只有一个大是边缘都小是平坦区域。工程实现里通常不直接做特征值分解而是用角点响应函数 R det(M) - k·trace(M)^2 替代因为行列式和迹比特征值分解便宜得多。2.4 Canny 细边缘与双阈值非极大值抑制的两处细节Canny 算子的“细边缘”靠的是非极大值抑制NMS遍历每个像素把它和梯度方向上相邻的两个像素比梯度幅值只有自己是最大值才保留。这里的细节是像素的梯度方向往往是任意角度而相邻像素只有上下左右和四个对角共 8 个位置所以需要做方向量化。def nms(mag, angle): h, w mag.shape out np.zeros_like(mag) # 角度量化为 0、45、90、135 四个方向 for i in range(1, h - 1): for j in range(1, w - 1): a angle[i, j] % 180 if a 22.5 or a 157.5: n1, n2 mag[i, j-1], mag[i, j1] # 水平方向 elif a 67.5: n1, n2 mag[i-1, j-1], mag[i1, j1] # 135 度方向 elif a 112.5: n1, n2 mag[i-1, j], mag[i1, j] # 垂直方向 else: n1, n2 mag[i-1, j1], mag[i1, j-1] # 45 度方向 if mag[i, j] n1 and mag[i, j] n2: out[i, j] mag[i, j] return out双阈值的设计思路是对 NMS 结果的第二次筛选。高阈值定出确定是边缘的强边缘低阈值定出可能是边缘的弱边缘。弱边缘只有与强边缘相连时才被保留这个“相连”规则能有效避免边缘断裂同时过滤掉孤立的噪声点。实际调参时低阈值一般取高阈值的 0.4 到 0.5 倍这个比例比绝对数值更值得先固定下来。3. SIFT 与视觉词典尺度空间到特征描述的完整链路SIFT 是特征工程时代的集大成者考点从第九题一路排到第十五题几乎每个环节都问了。刚看觉得碎其实它是一条完整的流水线先在不同尺度上找稳定关键点再给关键点分配方向最后生成描述子再把描述子聚类成视觉词典用于图像检索或分类。3.1 尺度选择与高斯金字塔特征尺度不是玄学自动尺度选择的基本思想是要构造一个函数 f(x, y, σ)当它在某个 σ 上取到局部极大值时说明这个尺度下的滤波器响应最强σ 就与特征的真实尺度建立了联系。这个函数通常用 LoG 实现用不同尺度 σ 的 LoG 核与信号做卷积当信号的最高点刚好与 LoG 核的零交叉点重合时内积达到最大值。这个物理意义很多人理解不了我换一种说法LoG 核的零交叉点对应的圆半径可以看作滤波器的“感受范围”。信号的尺度与滤波器的尺度匹配时卷积响应最大尺度差得越远响应越小。这就是特征尺度的物理意义。SIFT 的“双塔”结构指高斯金字塔和高斯差分金字塔的配合。高斯金字塔里上一层图像是下一层用更大 σ 高斯平滑的结果DoG 金字塔则是高斯金字塔相邻层相减用来近似 LoG因为减法比卷积便宜太多。# 高斯金字塔相邻层相减 - DoG # 第 o 组第 s 层的 σ 按倍数递增σ, kσ, k²σ, ... for s in range(S - 1): dog[o][s] gauss_pyr[o][s 1] - gauss_pyr[o][s]双塔结构的计算简化有四处一是大尺度平滑可以由小尺度平滑结果再用一个更大的核卷积得到不需要从头做二是跨组时把图像缩小一半用相同的小核继续卷积等效于用了更大的核三是下一组的第一层可以直接由上一组倒数第三层下采样得到四是用 DoG 近似 LoG把卷积换成减法。这四处优化把 SIFT 从“理论上可行”变成了“工程上可用”。3.2 方向分配与描述子生成投票细节决定匹配稳定性关键点找到之后要先定方向这是 SIFT 具备旋转不变性的基础。做法是以关键点为圆心、1.5σ 为半径画圆统计圆内所有像素的梯度方向直方图。直方图有 36 个 bin每 10 度一个。每个像素投票时权重等于梯度幅值乘以一个高斯权重离关键点越近权重越大。投票结束后峰值 bin 对应的方向作为主方向达到峰值 80% 的次峰作为副方向。def orientation_histogram(grad_angle, grad_mag, center, sigma, bins36): hist np.zeros(bins) bin_width 360 / bins radius int(1.5 * sigma) for x in range(center[0] - radius, center[0] radius 1): for y in range(center[1] - radius, center[1] radius 1): dist np.hypot(x - center[0], y - center[1]) if dist radius: continue # 离中心越近权重越大幅值越大权重越大 w np.exp(-dist**2 / (2 * (1.5 * sigma)**2)) * grad_mag[x, y] bin_idx int(grad_angle[x, y] // bin_width) % bins hist[bin_idx] w return hist描述子生成是在方向定好之后把关键点邻域旋转到主方向对齐然后划分成 4×4 的小区域每个小区域内统计 8 个方向的梯度直方图最终得到一个 4×4×8128 维向量再做归一化以抵抗光照变化。工程里最容易错的是忘记旋转对齐这一步——不旋转描述子就没有旋转不变性整个 SIFT 的匹配能力会大幅退化。3.3 视觉词典与纹理基元聚类在特征层的第一次落地视觉词典的构造逻辑很直接先用 SIFT 提取每幅图像的大量局部描述子把所有描述子堆成一个矩阵再用 K-means 聚类每个聚类中心就是一个视觉词汇所有聚类中心合起来就是视觉词典。from sklearn.cluster import KMeans # descriptors_all: (N, 128)N 是所有训练图像 SIFT 描述子总数 kmeans KMeans(n_clusters500, random_state0).fit(descriptors_all) # 推理时把新描述子映射到最近的聚类中心 def encode_image(descriptors, kmeans): # 每个描述子分配到最近的视觉词 words kmeans.predict(descriptors) # 统计直方图得到该图像的 bag-of-words 表示 hist np.bincount(words, minlengthkmeans.n_clusters) return hist / hist.sum()聚类数就是词典大小500 是常见的起点。词典太小区分度不够词典太大直方图稀疏且计算慢。纹理基元的构造过程本质相同区别在于特征输入不是 SIFT 描述子而是图像像素的 48 维向量颜色加局部统计量聚类之后用滑动窗口统计每个视觉词的出现次数直方图相似则判定为同一纹理区域。这两道题放在一起考是因为它们共享同一套“特征提取-聚类-直方图编码”的框架理解了视觉词典纹理基元就是换了个输入特征。4. 线性分类到神经网络W 矩阵、损失函数与隐藏层第十六题到第二十五题是整份考点里理论密度最高的部分。它从朴素贝叶斯、KNN、线性分类的关系切入讲到 W 矩阵的两种解释、损失函数、梯度更新策略最后落到神经网络隐藏层和 CNN 基础。这个段落一旦理通后面所有深度学习相关内容都有了解释的抓手。4.1 W 矩阵一个参数两种解释原题里的 s f(x, W) WxW 是得分函数的参数。代数视角下把 W 的每一行反扫描回图像尺寸每一行就是一个模板template每一行代表一个类别的平均模式。输入图像与每个模板做匹配得分越高越接近这个类别。几何视角下W 的每一行是一条决策线的法向量输出得分 s Wx 大于 0 表示 x 位于这条线的正方向一侧。n 个类别就有 n 条决策线最终取得分最高的那条线对应的类别。这里要注意几何视角是理解“线性分类器只能学一条直线”的关键。手工设计的特征如果线性不可分线性分类器必然表现差这就是引入神经网络隐藏层的直接动机。另外从生成式到判别式的过渡也在这个考点里朴素贝叶斯需要估计联合分布 P(X, Y) 再推条件概率KNN 是直接拿近邻样本的标签做预测线性分类器则是直接拟合 P(Y|X) 的决策边界。三者结构风险不同但目标一致。4.2 交叉熵与铰链损失损失函数量化了“W 有多差”损失函数就是评价 W 好坏的函数。softmax 的交叉熵损失把得分向量转成概率分布再取真实类别位置上的负对数概率。因为真实标签是 one-hot 编码计算时只需要把真实类别对应的那个输出取出来。def softmax_loss(scores, correct_index): exp_scores np.exp(scores - np.max(scores)) # 减最大值防止溢出 probs exp_scores / exp_scores.sum() return -np.log(probs[correct_index] 1e-12) # 加 epsilon 防止 log(0) def hinge_loss(scores, correct_index, delta1.0): margins np.maximum(0, scores - scores[correct_index] delta) margins[correct_index] 0 return margins.sum()交叉熵的数学解释是它衡量预测分布与真实分布之间的 KL 散度。铰链损失SVM 损失的解释是真实类别的得分至少要比其他类别高出 delta否则就产生惩罚。注意 softmax 的梯度永远不会为零因为 softmax 概率不会严格等于 0而 hinge 损失在满足间隔条件时梯度直接为 0这会影响训练时的更新行为。4.3 小批量更新与隐藏层训练效率和线性不可分“批块是不是越小越快”这个考点答案是不一定。当批小到一定程度每次迭代的计算开销主要由数据搬运和框架调度主导收益不再增加。但小批量更新确实有助于训练原因在于它的不稳定性全批量梯度下降时如果某个维度的梯度为 0训练会在这条“死路”上停滞小批量每次采样的数据不同损失曲面略有差异即使某次更新停在鞍点下一次更新大概率能借噪声冲出去。# 两层网络前向隐藏层做特征转换输出层做线性分类 h np.maximum(0, W1 x b1) # ReLU 激活隐藏层 s W2 h b2 # 线性得分隐藏层的作用从几何视角看是把线性不可分的空间映射到另一个空间让原本纠缠的类别变得线性可分从代数视角看是引入“分布式表示”——单隐层可以学到 100 个模板这些模板在 10 个类别间共享。表示一个类别时可能是多个模板的组合而不是像原始线性分类器那样一个类别只对应一个模板。模板数量变多梯度下降的优化就变麻烦这才需要反向传播算法来高效计算梯度。4.4 CNN 基础输出尺寸、参数数量与感受野CNN 这一组考点有两个必须记住的公式。输出特征图尺寸是 (N 2P - F) / S 1其中 N 是输入边长P 是 paddingF 是卷积核大小S 是步幅。参数数量是 (F×F×输入通道数 1)×卷积核个数加 1 是偏置项。感受野和权值共享是从神经计算视角理解 CNN 的关键。感受野是一个神经元能“看到”的输入区域大小权值共享指同一个卷积核在整张特征图上滑动时权重不变。MLP 中每条边都有自己的权重而卷积层的滤波器系数在空间上是共享的这正是卷积操作的定义决定的。这两个机制合起来让 CNN 的参数数量远小于同规模的全连接网络同时天然具备空间平移的鲁棒性。5. CNN 架构与训练避坑梯度消失、dropout 与残差模块第二十六题到第三十四题这组考点我建议当作“血泪经验集”来读。AlexNet 的每个设计点在今天看来都是理所当然但当年每一处都是踩过坑之后才补上的。这一章我把这些考点按“现象-原因-解决”重写成一份排查手册你照着顺序检查自己的网络能省很多调参时间。5.1 Sigmoid 梯度消失现象、原因、解决现象网络层数加到五六层之后反向传播时前面几层的权重几乎不动训练 loss 怎么降都降不下去。原因Sigmoid 函数的导数最大值是 0.25且在输入绝对值大于 5 时导数趋近于 0。反向传播是链式法则的连乘每一层都乘以一个小于 0.25 的数乘到前几层时梯度已经接近 0。这就是梯度消失。解决换激活函数。ReLU 在正区间的导数为 1梯度可以无损通过负区间导数为 0同时带来了稀疏性。如果要更平滑可以用 LeakyReLU 或 GELU。另外配套的是初始化方法ReLU 配 He 初始化Sigmoid 配 Xavier 初始化初始化不合适会让梯度消失提前出现。5.2 dropout 与数据增广不确定性换精度现象网络在训练集上准确率很高验证集上明显下降典型的过拟合。原因CNN 不具备 SIFT 那种内置的尺度和旋转不变性模型只能死记训练集的特定像素模式同时如果网络容量过大某些神经元会被“霸占”成特定输入的响应器输出过度依赖它们。解决dropout 和 data augmentation。dropout 的原理是训练时每个神经元以概率 p常用 0.5随机置零模型必须学习更鲁棒的特征不能过度依赖某几个神经元数据增广则是通过随机裁剪、水平翻转、颜色抖动把训练分布扩大从根源上减少过拟合。这里有一个常被忽略的细节dropout 只应该在训练时开启推理时必须关闭。很多新手在验证阶段忘记关 dropout导致验证指标忽高忽低误以为模型没训练好实际上只是推理行为不对。5.3 小卷积核、1x1 卷积与 Momentum三个容易用错的设计细节小尺寸滤波器3×3的好处是三个角度叠加起来的两个 3×3 卷积堆叠感受野等于 5×5三个堆叠等于 7×7。参数数量上三个 3×3 是 27C²一个 7×7 是 49C²省了近一半。另一层好处是每多一次卷积就多一次非线性激活三个 3×3 比一个 7×7 有更强的非线性表达能力。唯一的坑是显存中间的卷积层需要保存中间特征图堆叠多了会明显占用显存。1×1 卷积的作用有三个一是在不改变空间尺寸的前提下对通道做线性组合再接激活函数就是非线性映射二是通过控制卷积核个数实现降维减少后续计算量三是可以反过来升维增加通道数。你把它理解成“跨通道的线性变换层”就对了。Momentum 的物理类比是惯性更新方向不仅考虑当前梯度还保留上一次更新方向的惯性公式是 v μv - lr·g。μ 取 0.9 是常见起点。它解决的核心问题是损失曲面在某个方向上特别陡、另一个方向上特别平缓时纯 SGD 会在陡的方向来回震荡而 Momentum 会沿平缓方向惯性前进。# Momentum 更新mu 通常取 0.9 v mu * v - lr * grad w w v5.4 全卷积与转置卷积输出尺寸回不去的坑现象把分类网络迁移到分割或检测任务时全连接层要求固定输入尺寸而且丢失空间位置信息想把特征图恢复到原图大小直接用插值效果粗糙用卷积又没法变大。原因全连接层把空间维度全部拉平位置信息被揉碎而普通卷积只做下采样不改变分辨率无法完成从低分辨率特征图到高分辨率预测图的映射。解决全卷积网络把全连接层替换成卷积层让网络接受任意尺寸输入并输出空间预测图。转置卷积Transposed Convolution是上采样的实现方式之一它不是卷积的逆运算而是把卷积的前向和反向传播方向对调。输出尺寸计算公式是 (in - 1) × stride - 2 × padding kernel。最容易翻车的点是转置卷积的输出尺寸会出现棋盘伪影原因是 stride 与 kernel 尺寸不整除工程上建议用双线性插值先上采样再接普通卷积或者用 PixelShuffle 这类专门设计的上采样方式替代。5.5 训练 DNN 的参数顺序与验证策略这一题在考点里只有标题没有展开但在实操里它是整套流程的收口。我把它做成一张可以直接对照的检查表检查项建议值失效表现学习率从 1e-3 起按 loss 是否下降调loss 震荡或始终不降初始化ReLU 配 HeSigmoid 配 Xavier前几层梯度为 0批大小32-128按显存取最大值过小收敛慢过大泛化差正则dropout 0.5weight decay 5e-4训练高验证低激活函数首选 ReLU 及其变体深层网络梯度消失验证策略每个 epoch 后跑 val记录最优权重训练 loss 降但 val 不降调参顺序我一般固定为先确认 loss 能下降学习率和初始化有问题的话这里就暴露了再检查是否有过拟合最后才调 batch size 和数据增广强度。跳过前两步直接调正则等于没找到病因就乱开药。6. 目标检测主线从 R-CNN 到 Faster R-CNN 的工程取舍第三十五题到第四十题实际上是一个完整的技术演进故事。R-CNN、Fast R-CNN、Faster R-CNN 三代网络的核心矛盾只有一个重复计算如何被一步步消除。把这根主线抓住RPN、NMS、PR 曲线这些考点就都有位置了。6.1 三次演进重复计算如何一步步被消除R-CNN 的做法是先用 Selective Search 生成约 2000 个候选区域每个候选区域裁剪缩放后独立跑一遍 CNN 提取特征再用 SVM 分类、线性回归精修框。问题显而易见2000 个区域就有 2000 次前向计算而且训练要分阶段做特征存储开销极高。Fast R-CNN 的关键改进是让整张图只过一次 CNN得到共享特征图再用 RoI Pooling 把每个候选区域对应的特征区域池化成固定尺寸。这样卷积计算只做一次分类和回归通过多任务损失联合训练。它的瓶颈还剩一个候选区域仍然由 Selective Search 在 CPU 上生成速度慢且无法和检测网络联合优化。Faster R-CNN 的优化点是引入 RPNRegion Proposal Network用一个小网络在特征图上滑动窗口每个位置生成一组锚点anchor同时做二分类前景/背景和边界框回归。RPN 和检测网络共享特征图可以端到端训练。# RPN 锚点回归4 个偏移量转成实际框坐标 # dx, dy 是中心偏移dw, dh 是宽高缩放 x anchor_x dx * anchor_w y anchor_y dy * anchor_h w anchor_w * np.exp(dw) h anchor_h * np.exp(dh)这里要注意RPN 的回归目标是偏移量而不是绝对坐标因为偏移量的量纲更稳定网络更容易学习。训练时锚点与真实框的 IoU 大于 0.7 视为正样本小于 0.3 视为负样本中间部分不参与训练。6.2 NMS 与 AP检测结果的后处理与评估NMS 是目标检测推理阶段必须做的一步。它的思路是贪心选择每次取置信度最高的框把与它 IoU 超过阈值的框全部移除重复直到候选框清空。def nms(boxes, scores, iou_threshold0.5): order scores.argsort()[::-1] # 按置信度降序 keep [] while order.size 0: i order[0] keep.append(i) ious compute_iou(boxes[i], boxes[order[1:]]) order order[1:][ious iou_threshold] return keepPR 曲线和 AP 是评估检测精度的标准协议。把预测框按置信度降序排列逐个累加计算 precision 和 recall以 recall 为横轴、precision 为纵轴画出曲线AP 就是曲线下的面积。多类别时把每个类别的 AP 平均得到 mAP。NMS 的阈值会直接影响 AP阈值太高会保留一堆重叠框precision 被打低阈值太低又可能把两个相邻目标合并成一个框。我最早跑检测模型时把 NMS 阈值从 0.5 调到 0.7mAP 掉了两个点都没想通后来翻代码发现是阈值扫描没做。从那以后我每次跑完训练都强制走一遍“训练-验证-NMS 阈值扫描”的流程先固定阈值再调置信度最后才动 IoU这套顺序能少踩很多坑。希望帮到你。本文还有配套的精品资源点击获取