【深度学习】#12 计算机视觉
主要参考学习资料:
《动手学深度学习》阿斯顿·张 等 著
【动手学深度学习 PyTorch版】哔哩哔哩@跟李沐学AI
目录
- 目标检测
- 锚框
- 交并比(IoU)
- 锚框标注
- 真实边界框分配
- 偏移量计算
- 损失函数
- 非极大值抑制预测
- 多尺度目标检测
- 单发多框检测(SSD)
- 类别预测层
- 边界框预测层
- 区域卷积神经网络(R-CNN)
- R-CNN
- 选择性搜索
- 支持向量机
- Fast R-CNN
- 兴趣区域汇聚层
- Faster R-CNN
- YOLO
- 语义分割
- 转置卷积
- 基本操作
- 填充、步幅和多通道
- 全卷积网络(FCN)
- 风格迁移
在卷积神经网络和现代卷积神经网络两章中,我们只介绍了图像分类模型。由于深度神经网络可以有效地表示多个层次的图像,现今其已被成功应用于更多计算机视觉任务。本章将讨论目标检测、语义分割和风格迁移三种任务,在有限的篇幅内,重点介绍目标检测部分基础模型的设计思路,简要介绍语义分割和风格迁移的基本原理。
目标检测
图像分类假定图像中只有一个目标,我们只关注如何识别其类别。然而,很多时候图像中有多个我们感兴趣的目标,我们不仅想知道它们的类别,还想得到它们在图像中的具体位置,这类任务称为目标检测。
在目标检测中,我们通常使用边界框来描述对象的空间位置。边界框是矩形的,由左上角以及右下角的 x x x坐标或 y y y坐标确定,也可用边界框中心的轴坐标 ( x , y ) (x,y) (x,y)以及框的宽度和高度表示。
下图中狗和猫的边界框左上角以及右下角的坐标分别为 [ ( 60 , 45 ) , ( 378 , 516 ) ] [(60,45),(378,516)] [(60,45),(378,516)]和 [ ( 400 , 112 ) , ( 655 , 493 ) ] [(400,112),(655,493)] [(400,112),(655,493)]
锚框
目标检测算法通常会在输入图像中抽样大量的区域,然后判断这些区域中是否包含我们感兴趣的目标,并调整区域边界,从而更准确地预测目标的真实边界框。其中一种方法是以每个像素为中心,生成多个缩放比和宽高比不同的边界框,这些边界框被称为锚框(先验框)。
基于锚框的目标检测算法流程如下:
- 提出多个锚框区域;
- 预测每个锚框里是否含有关注的物体;
- 如果是,预测从这个锚框到真实边缘框的偏移。
假设输入图像的高度为 h h h,宽度为 w w w。对于缩放比为 s ∈ ( 0 , 1 ] s\in(0,1] s∈(0,1]、宽高比为 r > 0 r>0 r>0的锚框,其宽度和高度分别为 h s r hs\sqrt r hsr和 h s / r hs/\sqrt r hs/r。我们只需设置一系列缩放比取值 s 1 , ⋯ , s n s_1,\cdots,s_n s1,⋯,sn和宽高比取值 r 1 , ⋯ , r m r_1,\cdots,r_m r1,⋯,rm,就能以每个像素为中心生成多个不同形状的锚框。
但是如果将缩放比和宽高比的取值两两组合,将会在输入图像中生成 w ⋅ h ⋅ n ⋅ m w\cdot h\cdot n\cdot m w⋅h⋅n⋅m个锚框,很容易导致过高的计算复杂度,在实践中,我们只考虑包含 s 1 s_1 s1或 r 1 r_1 r1的组合
( s 1 , r 1 ) , ( s 1 , r 2 ) , ⋯ , ( s 1 , r m ) , ( s 2 , r 1 ) , ( s 3 , r 1 ) , ⋯ , ( s n , r 1 ) (s_1,r_1),(s_1,r_2),\cdots,(s_1,r_m),(s_2,r_1),(s_3,r_1),\cdots,(s_n,r_1) (s1,r1),(s1,r2),⋯,(s1,rm),(s2,r1),(s3,r1),⋯,(sn,r1)
此时对于整个输入图像将生成 w h ( n + m − 1 ) wh(n+m-1) wh(n+m−1)个锚框。
下图以 ( 250 , 250 ) (250,250) (250,250)为中心生成了一系列不同缩放比和宽高比的锚框:
交并比(IoU)
对于生成的锚框,如果已知目标的真实边界框,我们需要度量二者之间的相似性。杰卡德指数可以度量两个集合的相似性,给定集合 A A A和 B B B,它们的杰卡德指数是它们交集的大小除以它们并集的大小
J ( A , B ) = ∣ A ∩ B ∣ ∣ A ∪ B ∣ J(A,B)=\frac{|A\cap B|}{|A\cup B|} J(A,B)=∣A∪B∣∣A∩B∣
通过将任何边界框的像素区域视为像素的集合,我们可以通过其像素集的杰卡德指数来度量两个边界框的相似性。通常两个边界框的杰卡德指数被称为交并比(IoU),即两个边界框相交面积与相并面积之比。交并比的范围在 0 0 0到 1 1 1之间,交并比越大,两个边界框重合面积占比越大,相似性越高。
锚框标注
在开始训练之前,我们需要为训练集进行标注,每个锚框都是训练集的一个训练样本。样本的标签包括类别和偏移量。标注的流程大致如下:
- 根据IoU为每个锚框分配一个真实边界框,或视为背景,不分配真实边界框。
- 根据真实边界框的分配情况为每个锚框打上类别标签,非背景锚框被称为正类锚框,并且被打上其对应真实边界框的类别,而背景锚框被称为负类锚框。
- 对于非背景锚框,计算并标注其与对应真实边界框之间的偏移量。
真实边界框分配
下面介绍分配真实边界框的一种方法。
给定图像,假设锚框为 A 1 , A 2 , ⋯ , A n a A_1,A_2,\cdots,A_{n_a} A1,A2,⋯,Ana,真实边界框为 B 1 , B 2 , ⋯ , B n b B_1,B_2,\cdots,B_{n_b} B1,B2,⋯,Bnb,其中 n a ⩾ n b n_a\geqslant n_b na⩾nb,则分配真实边界框的步骤为:
- 遍历并计算所有锚框与真实边界框之间的IoU,得到一个矩阵 X ∈ R n a × n b X\in\mathbb R^{n_a\times n_b} X∈Rna×nb,其中第 i i i行、第 j j j列的元素 x i j x_{ij} xij是锚框 A i A_i Ai和真实边界框 B j B_j Bj的IoU。
- 保证 n b n_b nb个真实边界框都至少被分配到一个锚框。
- 在矩阵 X X X中找到最大的元素,其行索引和列索引记为 i 1 i_1 i1和 j 1 j_1 j1,然后将真实边界框 B j 1 B_{j_1} Bj1分配给锚框 A i 1 A_{i_1} Ai1,并丢弃矩阵中第 i 1 i_1 i1行和第 j 1 j_1 j1列中的所有元素(防止锚框和真实边界框被重复分配)。
- 在矩阵 X X X的剩余元素中找到最大的元素,其行索引和列索引记为 i 2 i_2 i2和 j 2 j_2 j2,然后采取同样的操作。
- 延续上述操作,直至矩阵 X X X中的所有元素都被丢弃,此时 n b n_b nb个真实边界框都被分配到了一个锚框。
- 遍历并分配剩余的 n a − n b n_a-n_b na−nb个锚框。对于锚框 A i A_i Ai,在矩阵 X X X的第 i i i行中找到与 A i A_i Ai的IoU最大的真实边界框 B j B_j Bj,如果这个IoU大于预定义的阈值,则将 B j B_j Bj分配给 A i A_i Ai,否则将 A i A_i Ai视为背景。
下图展示了第二大步的操作,蓝色格子为剩余的元素,标记出的元素为被分配的锚框-真实边界框:
偏移量计算
给定锚框 A A A和真实边界框 B B B,它们的中心坐标分别为 ( x a , y a ) (x_a,y_a) (xa,ya)和 ( x b , y b ) (x_b,y_b) (xb,yb),宽度分别为 w a w_a wa和 w b w_b wb,高度分别为 h a h_a ha和 h b h_b hb,则 A A A的偏移量 ( Δ x , Δ y , Δ w , Δ h ) (\Delta x,\Delta y,\Delta w,\Delta h) (Δx,Δy,Δw,Δh)为
( x b − x a w a − μ x σ x , y b − y a h a − μ y σ y , log w b w a − μ w σ w , log h b h a − μ h σ h , ) \left(\frac{\displaystyle\frac{x_b-x_a}{w_a}-\mu_x}{\sigma_x},\frac{\displaystyle\frac{y_b-y_a}{h_a}-\mu_y}{\sigma_y},\frac{\log\displaystyle\frac{w_b}{w_a}-\mu_w}{\sigma_w},\frac{\log\displaystyle\frac{h_b}{h_a}-\mu_h}{\sigma_h},\right) σxwaxb−xa−μx,σyhayb−ya−μy,σwlogwawb−μw,σhloghahb−μh,
四个数值分别衡量 A A A与 B B B的横坐标偏移、纵坐标偏移、宽度比和高度比。 μ \mu μ和 σ \sigma σ用于规范化,其默认值为 μ x = μ y = μ w = μ h = 0 \mu_x=\mu_y=\mu_w=\mu_h=0 μx=μy=μw=μh=0, σ x = σ y = 0.1 \sigma_x=\sigma_y=0.1 σx=σy=0.1, σ w = σ h = 0.2 \sigma_w=\sigma_h=0.2 σw=σh=0.2。
损失函数
锚框的损失函数 L L L由类别标签的分类损失 L c l s L_{cls} Lcls和偏移量标签的回归损失 L r e g L_{reg} Lreg组成,可计算如下
L = L c l s + λ L r e g L=L_{cls}+\lambda L_{reg} L=Lcls+λLreg
分类损失可使用交叉熵损失计算,回归损失可使用平滑L1损失计算。
非极大值抑制预测
在预测时,我们先为图像生成多个锚框,再为这些锚框一一预测类别。如果锚框被预测为非背景锚框,则进一步计算它的偏移量,并根据偏移量对锚框进行偏移得到真正的预测框。对于锚框 A A A的初始位置和大小 ( x a , y a , w a , h a ) (x_a,y_a,w_a,h_a) (xa,ya,wa,ha)及其偏移量 ( Δ x , Δ y , Δ w , Δ h ) (\Delta x,\Delta y,\Delta w,\Delta h) (Δx,Δy,Δw,Δh),调整后的预测框位置和大小计算如下
x = x a + w a Δ x y = y a + h a Δ y w = w a e Δ w h = h a e Δ h \begin{split} x&=x_a+w_a\Delta x\\ y&=y_a+h_a\Delta y\\ w&=w_ae^{\Delta w}\\ h&=h_ae^{\Delta h} \end{split} xywh=xa+waΔx=ya+haΔy=waeΔw=haeΔh
最终,模型可能会输出许多相似的具有明显重叠的预测框,它们都围绕同一个目标。为了简化输出,我们可以使用非极大值抑制合并属于同一目标的相似的预测框,其步骤如下:
- 对每个预测框 B B B,取其对每个类别预测概率的最大值 p p p作为其置信度,该概率对应的类别即为预测类别。
- 将所有预测框根据置信度按降序排序,生成列表 L L L。
- 从 L L L中选取置信度最高的预测框 B 1 B_1 B1作为基准,将所有与 B 1 B_1 B1的IoU超过预定阈值 ϵ \epsilon ϵ的预测框从 L L L中移除,即移除了与 B 1 B_1 B1相似但置信度低于 B 1 B_1 B1的预测框。
- 从 L L L中选取置信度次高的预测框 B 2 B_2 B2作为基准,然后采取同样的操作。
- 重复上述过程,直至 L L L中剩余的预测框都曾被选为基准,此时 L L L中任意一对预测框的IoU都小于阈值 ϵ \epsilon ϵ,即没有一对预测框过于相似。
- 输出 L L L中的所有预测框。
下图展示了非极大值抑制的操作效果:
多尺度目标检测
即使我们已经缩减了锚框缩放比和高宽比的组合,但是为每个像素都生成锚框仍会导致过大的计算量。一个进一步减少图像上锚框数量的方法是多尺度锚框。
多尺度锚框考虑到,在不同尺度下,较小的目标相对于较大的目标在图像上出现的可能性更为多样,例如在一张 2 × 2 2\times2 2×2像素的图像中, 1 × 1 1\times1 1×1像素、 1 × 2 1\times2 1×2像素和 2 × 2 2\times2 2×2像素的目标可以分别以 4 4 4种、 2 2 2种和 1 1 1种可能的方式出现。因此,当使用较小的锚框检测较小的目标时,我们可以抽样较多的取区域,而对于较大的目标,我们可以抽样较少的区域。
一种控制不同尺度抽样数量的方法是对于不同的尺度,根据尺度的大小在图像上选取一系列均匀分布的像素点作为锚框中心,并生成该尺度下一系列高宽比的锚框。
下图分别展示了尺度 s s s为 0.15 0.15 0.15、 0.4 0.4 0.4和 0.8 0.8 0.8时选取的像素中心及生成的锚框:
基于卷积神经网络的多尺度目标检测方法通常不直接在输入图像上生成不同尺度的锚框,而是利用卷积层提取输入图像不同尺度的特征,相应的特征输出被称为特征图。越靠后的卷积层输出的特征图的每个单元在输入图像上具有更大的感受野,因此不同特征图的一个单元就对应着输入图像上不同尺度的锚框。
单发多框检测(SSD)
单发多框检测(SSD)是一种简单、快速且被广泛使用的目标检测模型,其主要由一个基础网络块和若干多尺度特征块组成:
基础网络块用于从输入图像中提取特征,因此可以使用深度卷积神经网络(其设计者使用VGG块,现在也常用ResNet块)。基础网络块的输出将设置较大的高和宽,以便生成更多的锚框用于检测较小的目标。接下来的每个多尺度特征块将上一层提供的特征图的高和宽缩小,使得特征图中每个单元在输入图像上的感受野变大,从而检测更大的目标。
类别预测层
假设特征图的高和宽分别为 h h h和 w w w,以其中每个单元为中心生成 a a a个锚框,则我们需要对 h w a hwa hwa个锚框进行分类。又假设目标类别的数量为 q q q,则加上背景类别 0 0 0,锚框共有 q + 1 q+1 q+1个类别。如果使用全连接层分类很容易导致庞大的参数,因此我们使用NiN提供的思路(参见现代卷积神经网络一章),将通道维度视为特征维度,使用卷积层分类。卷积层要求输入和输出的特征图大小一致,以保证二者的坐标一一对应,而输出特征图上坐标 ( x , y ) (x,y) (x,y)的通道将包含以输入特征图上坐标 ( x , y ) (x,y) (x,y)为中心生成的 a a a个锚框关于 q + 1 q+1 q+1个类别的预测,因此输出通道数为 a ( q + 1 ) a(q+1) a(q+1),其中第 i ( q + 1 ) + j ( 0 ⩽ j ⩽ q ) i(q+1)+j(0\leqslant j\leqslant q) i(q+1)+j(0⩽j⩽q)个通道代表第 i i i个锚框被预测为类别 j j j的概率。
边界框预测层
边界框预测层的设计与类别预测层类似,只是其输出通道是对每个锚框的四个偏移量的预测,因此输出通道数为 4 a 4a 4a。
简而言之,SSD的预测过程如下:
- 输入图像经基础网络块和一系列多尺度特征块,得到一系列不同尺度的输出特征图。
- 在每个输出特征图上以每个单元为中心生成 a a a个锚框,并对这些锚框进行类别和偏移量预测得到一系列预测框。
- 对所有预测框进行非极大值抑制处理,得到最终输出的预测框。
区域卷积神经网络(R-CNN)
R-CNN及其一系列改进方法是将深度模型应用于目标检测的另一个开创性工作。限于篇幅本节对部分方法只作简要解释。
R-CNN
R-CNN的预测过程如下:
- 对输入图像使用选择性搜索选取多个高质量的提议区域。
- 通过各向异性缩放(直接拉伸)或各向同性缩放(先填充再按比例拉伸)将提议区域缩放为固定大小。
- 选择一个预训练的卷积神经网络,提取每个提议区域的特征。
- 类别预测:为每个类别(除了背景类别)训练一个二分类支持向量机,使用每个支持向量机根据提议区域的特征判断其是否属于某个类别。
- 边界框预测:使用线性回归模型根据提议区域的特征预测每个提议区域的偏移量,进而得到每个提议区域的预测框。
- 对所有预测框进行非极大值抑制处理,得到最终输出的预测框。
选择性搜索
选择性搜索是一种传统计算机视觉算法,其目标是生成可能包含物体的候选区域。选择性搜索的过程为:
- 使用Felzenswalb图像分割算法(基于图像边缘信息)将图像分割为超像素(像素集),得到一系列初始区域的集合 R = { r 1 , r 2 , ⋯ , r n } R=\{r_1,r_2,\cdots,r_n\} R={r1,r2,⋯,rn}。
- 对每个相邻区域 ( r i , r j ) (r_i,r_j) (ri,rj),分别计算它们的颜色、纹理、大小和形状相似度。
- 每次迭代选择综合相似度最高的区域将相邻区域合并为新区域并更新新区域的特征,直到整张图像成为一个区域。
- 在合并过程中记录所有中间区域的边界框作为候选区域,最后使用非极大值抑制移除高度重叠的冗余框(通常保留约2000个候选区域)。
支持向量机
支持向量机是一种非神经网络的机器学习分类模型,其原理为:
- 通过核函数将数据集映射到高维空间,使之线性可分(能用一个超平面将不同类别的特征分割)。
- 找到一个超平面将两类特征分开,并最大化支持向量(距离超平面最近的样本点)到超平面的距离。
- 使用超平面作为决策边界对输入进行分类。
Fast R-CNN
R-CNN的缺点在于,其第二步的卷积神经网络对每个提议区域独立处理,因此对于提议区域中相互重叠的部分会重复计算。Fast R-CNN采取的改进是通过直接对整张图像进行处理来减少不必要的计算,其步骤如下:
- 对输入图像使用选择性搜索生成多个提议区域。
- 将整个输入图像作为卷积神经网络的输入提取共享特征。
- 由提议区域在共享特征上标出一系列兴趣区域,使用兴趣区域汇聚层将其处理为固定形状。
- 通过全连接层进一步调整形状后进行预测。
兴趣区域汇聚层
兴趣区域汇聚层接收整张图像的特征和候选区域为输入,输出固定大小的候选区域特征,其步骤如下:
- 将候选区域按坐标比例缩放后投影到特征图上,选出共享特征中与候选区域对应的部分。
- 将投影区域平均划分为 m × n m\times n m×n的网格。
- 每个网格进行最大汇聚操作(取最大值作为输出),得到 m × n m\times n m×n的固定形状输出。
Faster R-CNN
Faster R-CNN在Fast R-CNN的基础上,将生成提议区域的方法由选择性搜索替换为区域提议网络(RPN),进一步减少了提议区域生成的数量,并确保目标检测的精确度。
RPN本质上是一个轻量级目标检测模型,以更低的计算成本快速对可能包含物体的区域进行粗筛(只对是否包含物体进行二元分类),相当于在仔细观察之前先进行了一次扫视。
使用RPN让R-CNN更加近似地实现了端到端的学习范式,即从输入到输出由统一的模型完成,所有模块可以联合训练。而在R-CNN和Fast R-CNN中,选择性搜索、支持向量机模块脱离了神经网络,都需要独立训练。除此之外,神经网络相较其他方式可以利用GPU实现高效计算,运行在CPU的选择性搜索算法生成2000个候选框需要约2秒,而RPN仅需约10ms。
YOLO
YOLO是目标检测领域最具影响力的算法之一,以极快的速度和端到端的设计著称。和R-CNN系列的双阶段检测不同,YOLO将检测任务视为单次回归问题,直接在图像上预测边界框和类别,实现了真正的实时检测。
YOLO的核心思路为将图像划分为 S × S S\times S S×S的网格,每个网格负责预测中心落在该区域的目标,直接生成 B B B个预测框的坐标和置信度,无需生成候选框。YOLO经过数年迭代,融入许多改进点,其系列已演进到YOLOv8,本文暂不深入展开。
语义分割
语义分割重点关注如何将图像分割成属于不同语义类别的区域。与目标检测不同,语义分割可以识别并理解图像中每个像素的内容,其语义区域的标注和预测是像素级的。
转置卷积
我们目前介绍的卷积神经网络层通常会减少下采样输入图像的空间维度(高和宽),如果输入图像和输出图像的空间维度相同,在以像素级分类的语义分割中将会很方便。转置卷积可以逆转下采样导致的空间维度减小,增加上采样中间层特征图的空间维度。
基本操作
转置卷积可以理解为卷积的逆操作。在转置卷积中,卷积核并不是和输入图像上与之形状相同的区域做按元素乘法并求和的运算,而是每次选中一个元素,该元素分别和卷积核的每个元素做乘法得到和卷积核形状相同的输出。将输入图像中每个元素和卷积核运算的输出按步幅叠加即可得到放大的输出。
填充、步幅和多通道
与常规卷积不同,转置卷积的填充被应用于输出,且填充操作实际上是裁剪输出边缘对应数量的行和列,这也可以从卷积的逆操作来理解。
同样地,步幅也是为输出而非输入指定的,其表示每次卷积核操作之后输出位置的滑移量,下图展示了步幅为2的转置卷积:
对于多输入输出通道,转置卷积与常规卷积以相同的方式操作,即每个输入通道都会被分配与输出通道数目相同的卷积核,每个卷积核负责一个输入通道到一个输出通道的计算。
全卷积网络(FCN)
全卷积网络(FCN)通过引入转置卷积,采用卷积神经网络实现了从图像像素到像素类别的转换。FCN开创了全卷积架构的先河,奠定了现代分割网络的基础。
FCN的核心改进在于将传统卷积神经网络的全连接层替换为了转置卷积层。FCN先使用卷积神经网络提取图像特征,然后通过 1 × 1 1\times1 1×1卷积层将通道数转换为类别数,再通过转置卷积层将特征图的高和宽转换为输入图像的大小,而每个像素的每个输出通道表示该像素被预测为对应类别的概率。
风格迁移
风格迁移是一种将艺术风格与图像内容相结合的计算机视觉技术,它接收两张图像作为输入,一张是内容图像,另一张是风格图像。模型将修改内容图像,使其在风格上接近风格图像。
一种基于卷积神经网络的风格迁移模型如下图所示,实线箭头和虚线箭头分别表示前向传播和反向传播:
该模型中,每个图像都由一个预训练好的卷积神经网络处理,在训练中无需更新。该卷积神经网络凭借多个层逐级提取图像的特征,其中某些层被指定输出内容特征或风格特征。
模型在风格迁移过程中所需迭代的模型参数即合成图像,其迭代流程如下:
- 初始化合成图像,通常使用内容图像,合成图像将在内容图像的基础上不断演进。
- 使用卷积神经网络提取内容图像和风格图像的内容特征和风格特征。
- 迭代合成图像:
- 使用卷积神经网络提取合成图像的内容特征和风格特征。
- 计算合成图像与内容图像之间的内容损失、合成图像与风格图像之间的风格损失和合成图像的全变分损失(总变差损失)。
- 三个损失通过反向传播对合成图像进行优化。
- 重复上述操作。
- 迭代一定次数后得到最终的合成图像。
其中,内容(风格)损失均通过平方误差函数度量合成图像与内容(风格)图像在特征上的差异得到。而全变分损失度量邻近像素值的差异,用于去除合成图像中大量的高频噪点,即特别亮或特别暗的像素。假设 x i , j x_{i,j} xi,j表示坐标 ( i , j ) (i,j) (i,j)处的像素值,则全变分损失计算如下:
∑ i , j ∣ x i , j − x i + 1 , j ∣ + ∣ x i , j − x i , j + 1 ∣ \sum_{i,j}|x_{i,j}-x_{i+1,j}|+|x_{i,j}-x_{i,j+1}| i,j∑∣xi,j−xi+1,j∣+∣xi,j−xi,j+1∣
相关文章:
【深度学习】#12 计算机视觉
主要参考学习资料: 《动手学深度学习》阿斯顿张 等 著 【动手学深度学习 PyTorch版】哔哩哔哩跟李沐学AI 目录 目标检测锚框交并比(IoU)锚框标注真实边界框分配偏移量计算损失函数 非极大值抑制预测 多尺度目标检测单发多框检测(S…...
QT学习3
QT项目视图 1、List View清单视图 private:QListView *listview1; private slots:void slotClickedFunc(const QModelIndex &index); #include "widget.h" #include "ui_widget.h"#include <QStringListModel>//字符串列表模型 #include <QS…...
Vue 3 动态 ref 的使用方式(表格)
一、问题描述 先给大家简单介绍一下问题背景。我正在开发的项目中,有一个表格组件,其中一列是分镜描述,需要支持视频上传功能。用户可以为每一行的分镜描述上传对应的视频示例。然而,在实现过程中,出现了一个严重的问…...
FAST-DDS源码分析PDP(一)
准备开一个FAST-DDS源码分析系列,源码版本FAST-DDS 1.1.0版本。 FAST-DDS这种网络中间件是非常复杂的,所以前期先去分析每个类的作用是什么,然后在结合RTPS DOC,FAST-DDS DEMO,以及FAST-DDS的doc去串起来逻辑。 Builtin Discovery…...
Flutter与Kotlin Multiplatform(KMP)深度对比及鸿蒙生态适配解析
Flutter 与 Kotlin Multiplatform(KMP)深度对比及鸿蒙生态适配解析 在跨平台开发领域,Flutter 与 Kotlin Multiplatform(KMP)代表了两种不同的技术路线:前者以 “统一 UI 体验” 为核心,后者以…...
深入了解linux系统—— 基础IO(上)
文件 在之前学习C语言文件操作时,我们了解过什么是文件,这里简单回顾一下: 文件存在磁盘中,文件有分为程序文件、数据文件;二进制文件和文本文件等。 详细描述见文章:文件操作——C语言 文件在磁盘里&a…...
C++ map multimap 容器:赋值、排序、大小与删除操作
概述 map和multimap是C STL中的关联容器,它们存储的是键值对(key-value pairs),并且会根据键(key)自动排序。两者的主要区别在于: map不允许重复的键multimap允许重复的键 本文将详细解析示例代码中涉及的map操作,包括赋值、排…...
EmuEdit
EmuEdit详解:统一多任务图像编辑的扩展性范式 引言:图像编辑的困境 近年来,扩散模型(Diffusion Models)在图像合成和编辑方面取得了巨大进展,如 Prompt-to-Prompt (P2P)、InstructPix2Pix、DiffEdit 等方法…...
Linux编译rpm包与deb包
注意: 本文内容于 2025-05-14 23:55:53 创建,可能不会在此平台上进行更新。如果您希望查看最新版本或更多相关内容,请访问原文地址:编译rpm包与deb包。感谢您的关注与支持! 近期在通过源码编译安装一些软件包时&#…...
GitHub 趋势日报 (2025年05月17日)
本日报由 TrendForge 系统生成 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日整体趋势 Top 10 排名项目名称项目描述今日获星总星数语言1TapXWorld/ChinaTextbookPDF教材。⭐ 2471⭐ 22302Roff2public-apis/public-a…...
[创业之路-362]:企业战略管理案例分析-3-战略制定-华为使命、愿景、价值观的演变过程
一、华为使命、愿景、价值观的演变过程 1、创业初期(1987 - 1994 年):生存导向,文化萌芽 使命愿景雏形:1994年华为提出“10年之后,世界通信行业三分天下,华为将占一份”的宏伟梦想,…...
Android 性能优化入门(二)—— 内存优化
1、概述 1.1 Java 对象的生命周期 各状态含义: 创建:分配内存空间并调用构造方法应用:使用中,处于被强引用持有(至少一个)的状态不可见:不被强引用持有,应用程序已经不再使用该对象…...
(5)python爬虫--BeautifulSoup(bs4)
文章目录 [TOC](文章目录) 前言一、安装bs4二、bs4的基础使用2.1 创建soup对象2.2 根据标签名查找节点2.3 根据函数来查找节点1. find函数2. find_all函数3. select函数 三、使用bs4获取节点信息3.1 获取节点内容3.2 获取节点的属性3.3 获取节点的属性值 四、测试练习 总结 前言…...
如何利用DeepSeek提升工作效率
1. 代码开发辅助 1.1 代码生成 根据需求描述生成代码框架 自动补全代码片段 生成单元测试用例 创建项目文档 1.2 代码优化 代码重构建议 性能优化方案 最佳实践推荐 设计模式应用 2. 问题诊断与解决 2.1 错误分析 编译错误解析 运行时错误诊断 内存泄漏检测 性…...
游戏引擎学习第292天:实现蛇
每次VLC 读取OSD 会有bug 修复一下 回顾并计划实现一种漂浮的移动方式,并制作一个贪吃蛇 虽然不完全记得之前具体计划,但感觉是想实现一个小蛇形生物,之前一直没来得及做。我们还打算让熟悉的伙伴能漂浮移动,所以今天会继续进行一…...
菱形继承原理
在C中,菱形继承的内存模型会因是否使用虚继承产生本质差异。我们通过具体示例说明两种场景的区别: 一、普通菱形继承的内存模型 class A { int a; }; class B : public A { int b; }; class C : public A { int c; }; class D : public B, public C { i…...
C++编程起步项目
员工信息管理系统 需求 Employee.h #pragma once#include<iostream> #include<string>using namespace std;class Employee { public:int id; // 编号string name; // 姓名string position; // 岗位int deptId; // 部门编号Employee();Employee(int id, string n…...
c++编写中遇见的错误
目录 一.获取动态数组的长度二.编译错误三、内存泄露 一.获取动态数组的长度 首先想到获取数组的长度的代码是: sizeof(arr) / sizeof(arr[0]);但是当将其使用到动态数组上时就会产生错误; int* help new int[3];for (int i 0; i < 3; i) {help[…...
股票数据源对接技术指南:印度尼西亚、印度、韩国
一、多国数据对接全景图 1. 核心数据领域对比 国家金融市场数据源宏观经济指标特色数据资源印度NSE/BSE实时行情RBI经济统计库UPI支付数据/GST税务记录印尼IDX交易所数据流BPS官方统计棕榈油产业数据/群岛物流信息韩国KRX综合指数KOSTAT国家统计K-POP消费趋势/半导体出口数据…...
常见面试题:Webpack的构建流程简单说一下。
文章目录 前言一、Webpack 的核心使命:模块化打包二、Webpack 构建流程详解三、构建流程的可视化演示项目结构构建流程图 四、构建流程中的关键技术点1. 依赖图的构建与优化2. 哈希与缓存策略3. 开发环境优化 五、简易版概括构建流程 总结 前言 在前端工程化中&…...
Elasticsearch基础篇-java程序通过RestClient操作es
目录 1.引入 2 初始化RestClient 1)引入es的RestHighLevelClient依赖: 2)因为SpringBoot默认的ES版本是7.17.10,所以我们需要覆盖默认的ES版本: 3)初始化RestHighLevelClient: 4)…...
SuperYOLO:多模态遥感图像中的超分辨率辅助目标检测之论文阅读
摘要 在遥感影像(RSI)中,准确且及时地检测包含数十像素的多尺度小目标仍具有挑战性。现有大多数方法主要通过设计复杂的深度神经网络来学习目标与背景的区分特征,常导致计算量过大。本文提出一种兼顾检测精度与计算代价的快速准确…...
k6学习k6学习k6学习k6学习k6学习k6学习
1.安装go 2.安装 xk6 (k6 扩展构建工具): go install go.k6.io/xk6/cmd/xk6latest3.构建自定义 k6 二进制文件(集成 faker 扩展): xk6 build --with github.com/gkarthiks/xk6-fakerlatest构建报错处理(代码拉取失败)࿱…...
ubuntu 安装mq
一、安装依赖 编译 Erlang 需要以下依赖库和工具: sudo apt update sudo apt install -y build-essential autoconf libncurses5-dev libssl-dev m4 unixodbc-dev libwxgtk3.0-gtk3-dev libgl1-mesa-dev libglu1-mesa-dev 二、解压源码包 tar -xzvf otp_src_21.…...
优化 Spring Boot 应用启动性能的实践指南
1. 引言 Spring Boot 以其“开箱即用”的特性深受开发者喜爱,但随着项目复杂度的增加,应用的启动时间也可能会变得较长。对于云原生、Serverless 等场景而言,快速启动是一个非常关键的指标。 2. 分析启动过程 2.1 启动阶段概述 Spring Boot 的启动流程主要包括以下几个阶…...
ubuntu18.04编译qt5.14.2源码
ubuntu18.04编译qt5.14.2源码 文章目录 ubuntu18.04编译qt5.14.2源码[toc]1 前言2 参考文档3 下载源码3.1 方法13.2 方法23.3 方法3 4 ubuntu编译qt源码4.1 环境准备4.2 设置交换分区大小4.3 编译源码4.4 添加环境变量4.5 验证编译结果4.6 编译帮助文档(qch…...
leetcodehot100刷题——排序算法总结
排序算法总结 冒泡排序介绍步骤(以升序排序为例)算法实现复杂度分析时间复杂度空间复杂度 是否为稳定排序:是稳定排序的定义 选择排序介绍步骤(以升序排序为例)算法实现复杂度分析时间复杂度空间复杂度 是否为稳定排序…...
多用途商务,电子产品发布,科技架构,智能手表交互等发布PPT模版20套一组分享
产品发布类PPT模版20套一组:产品发布PPT模版https://pan.quark.cn/s/25c8517b0be3 第一套PPT模版是一个总结用的PPT封面,背景浅灰色,有绿色叶片和花朵装饰,深绿色标题,多个适用场景和占位符。突出其清新自然的设计和商…...
2025年- H29-Lc137- 19.删除链表的倒数第N个节点(快慢指针)---java版
1.题目描述 2.思路 快慢指针都在虚拟头节点,然后让快指针先走n1步,接下来,快慢指针以前移动,直到快指针指向null,慢指针指向被删节点的前一个节点。 3.代码实现 方法一:不带测试用例 /*** Definition …...
新电脑软件配置二:安装python,git, pycharm
安装python 地址 https://www.python.org/downloads/ 不是很懂为什么这么多版本 安装windows64位的 这里我是凭自己感觉装的了 然后cmd输入命令没有生效,先重启下? 重启之后再次验证 环境是成功的 之前是输入的python -version 命令输入错误 安装pyc…...
医学影像开发的开源生态与技术实践:从DCMTK到DICOMweb的全面探索
🧑 博主简介:CSDN博客专家、CSDN平台优质创作者,高级开发工程师,数学专业,10年以上C/C++, C#, Java等多种编程语言开发经验,拥有高级工程师证书;擅长C/C++、C#等开发语言,熟悉Java常用开发技术,能熟练应用常用数据库SQL server,Oracle,mysql,postgresql等进行开发应用…...
【HarmonyOS 5开发入门】DevEco Studio安装配置完全指南
⭐本期内容:【HarmonyOS4+NEXT】Button组件核心特性 🏆系列专栏:鸿蒙HarmonyOS:探索未来智能生态新纪元 文章目录 前言下载开发工具安装开发工具配置开发环境新建项目项目结构概述运行项目Preview预览模拟器运行 报错处…...
出现 Uncaught ReferenceError: process is not defined 错误
在浏览器环境中,process 对象是 Node.js 环境特有的,因此当你在浏览器中运行代码时,会出现 Uncaught ReferenceError: process is not defined 错误。这个错误是因为代码里使用了 process.env.BASE_URL,而浏览器环境下并没有 proc…...
如何实现RTSP和RTMP低至100-200ms的延迟:直播SDK的技术突破
在实时音视频传输中,低延迟是直播应用的核心技术要求之一。无论是在线教育、远程医疗,还是实时互动直播,延迟过大会影响用户体验,甚至导致应用无法正常使用。大牛直播SDK(SmartMediaKit)在RTSP和RTMP播放器…...
linux-----------------库制作与原理(下)
1.ELF文件 要理解编译链链接的细节,我们不得不了解⼀下ELF⽂件。其实有以下四种⽂件其实都是ELF⽂件: • 可重定位⽂件(Relocatable File ) :即 xxx.o ⽂件。包含适合于与其他⽬标⽂件链接来创 建可执⾏⽂件或者共享…...
一种开源的高斯泼溅实现库——gsplat: An Open-Source Library for Gaussian Splatting
一种开源的高斯泼溅实现库——gsplat: An Open-Source Library for Gaussian Splatting 文章目录 一种开源的高斯泼溅实现库——gsplat: An Open-Source Library for Gaussian Splatting摘要Abstract1. 基本思想1.1 设计1.2 特点 2. Nerfstudio&Splatfacto2.1 Nerfstudio2.…...
Embedding 模型详解:架构、训练与 LLM 的区别
1. 什么是 Embedding 模型? Embedding 模型的核心使命是将离散的、高维的文本数据(例如单个词语、短语、句子、段落乃至整篇文档)转化为稠密的 (dense)、低维的 (low-dimensional)、连续的 (continuous) 向量表示。这些向量被称作“嵌入 (Em…...
网络的知识的一些概念
1.什么是局域网,什么是广域网 局域网(Local area network)也可以称为本地网,内网,局域网有这几个发展经历: 最开始电脑与电之间是直接用网线连接的 再后来有了集线器() 再后来出…...
NAT(网络地址转换)逻辑图解+实验详解
原理 NAT(Network Address Translation,网络地址转换) 是一种网络技术,用于在IP数据包通过路由器或防火墙时,修改其源IP地址或目标IP地址,以实现不同网络之间的通信。 基础概念 本来NAT是来解决 IPv4 地…...
深入解析Spring Boot与Kafka集成:构建高性能消息驱动应用
深入解析Spring Boot与Kafka集成:构建高性能消息驱动应用 引言 在现代分布式系统中,消息队列是实现异步通信和解耦的重要组件。Apache Kafka作为一种高性能、分布式的消息系统,被广泛应用于大数据和实时数据处理场景。本文将详细介绍如何在…...
Linux的内存泄漏问题及排查方法
内存泄漏是指在计算机程序中,已不再被使用的内存未被正确释放,导致内存占用随时间累积,进而引发系统内存不足、性能下降甚至崩溃的问题。在Linux系统中,开发者和运维人员可通过以下方法排查和解决内存泄漏问题: 1. 使…...
Java基础知识总结(超详细整理)
一:概述 1.1Java类及类的成员 属性、方法、构造器、代码块、内部类 (1)数组 java虚拟机内存划分 各区域作用 内存解析 基本使用 两个变量指向一个一维数组 没有new就不会在堆里新开辟空间 (2)对象数组 (3&a…...
Qt Widgets模块功能详细说明,基本控件:QPushButton(二)
一、基本控件(Widgets) Qt 提供了丰富的基本控件,如按钮、标签、文本框、复选框、单选按钮、列表框、组合框、菜单、工具栏等。 1、QPushButton 1.1、概述 (用途、继承关系) QPushButton 是 Qt 框架中用于创建按钮的控件,它的主…...
【MySQL成神之路】MySQL常见命令汇总
目录 MySQL常用命令总结 1. 数据库操作 2. 表操作 3. 数据操作(DML) 4. 索引与优化 5. 用户与权限管理 6. 备份与恢复 7. 事务控制 8. 常用函数 9. 系统状态与日志 总结 MySQL常用命令总结 MySQL作为最流行的关系型数据库之一,提供…...
UnLua源码分析(一)初始化流程
UnLua源码分析(一)初始化流程 接入插件启动注册设置默认参数集注册回调SetActivePostLoadMapWithWorldULuaEnvLocator启动Lua虚拟机初始化UE相关的Lua Lib创建与Lua交互的数据结构注册静态导出的类,函数,枚举Lua层初始化 UUnLuaMa…...
非线性1 修改
第一章为读者介绍了非线性动力学与混沌理论的基本概念、发展历史以及应用领域。 1.1 动力学简史: 从牛顿力学开始,介绍动力学作为物理学分支的发展历程。重点介绍了庞加莱对混沌现象的早期探索,以及20世纪60年代洛伦兹方程的发现࿰…...
系统性能不达标,如何提升用户体验?
当系统性能不达标时,要想有效提升用户体验,必须从性能优化、前后端协同、用户感知改善、监控预警机制四个关键维度切入。其中,性能优化是最直接有效的策略,它通过代码优化、资源压缩、缓存机制、CDN加速等手段,显著提升…...
【Linux】进程的基本概念
目录 概念描述进程-PCB如何查看进程通过系统目录进行查看通过ps指令进行查看 通过系统调用获取进程的PID和PPID(进程标⽰符)通过系统调用创建子进程通过一段代码来介绍fork为什么要有子进程?fork为什么给子进程返回0,给父进程返回子进程的PIDfork函数到底…...
mongodb管理工具的使用
环境: 远程服务器的操作系统:centOS stream 9; mongoDB version:8.0; 本地电脑 navicat premium 17.2 ; 宝塔上安装了mongoDB 目的:通过本地的navicat链接mongoDB,如何打通链接,分2步: 第一步:宝塔-&…...
面试中的线程题
原文链接:线程题大全 Java 并发库同步辅助类 CountDownLatch 工作机制:初始化一个计数器,此计数器的值表示需要等待的事件数量。 提供了两个主要方法: await():当一个线程调用此方法时,它将阻塞&#…...