改进YOLOv5系列:ResNeXt融合特征金字塔,引领YOLOv5目标检测

news2024/11/28 14:44:03

目录

    • 一、介绍
      • 1、YOLOv5简介
      • 2、ResNeXt简介
      • 3、目标检测简介
    • 二、YOLOv5及其局限性
      • 1、YOLOv5的架构与原理
      • 2、YOLOv5的优势
      • 3、YOLOv5的局限性
    • 三、ResNeXt与特征金字塔融合
      • 1、ResNeXt的基本原理
      • 2、ResNeXt的优势
      • 3、特征金字塔的基本原理
      • 4、特征金字塔的优势
      • 5、ResNeXt与特征金字塔的融合
    • 四、创新特征金字塔融合的实现
      • 1、数据准备
      • 2、YOLOv5代码结构概述
      • 3、特征金字塔融合的具体实现
    • 五、实验与结果
      • 1、实验设置
      • 2、实验结果分析

大家好,我是哪吒。

🏆本文收录于,目标检测YOLO改进指南。

本专栏均为全网独家首发,🚀内附代码,可直接使用,改进的方法均是2023年最近的模型、方法和注意力机制。每一篇都做了实验,并附有实验结果分析,模型对比。

一、介绍

1、YOLOv5简介

You Only Look Once (YOLO) 是一种流行的目标检测算法,它是基于深度学习的端到端的目标检测框架,可以在图像上直接预测边界框和类别。

与其前几个版本相比,YOLOv5增加了许多改进:首先,采用了新的backbone网络架构,即CSPNet,可以更好的提取图像特征;其次,YOLOv5在模型训练中采用了自适应精度加速训练(AutoML)、类别平衡滤波器(CBF)等技术,可以有效提高模型性能和训练效率。

2、ResNeXt简介

ResNeXt是ResNet的进一步改进版,它采用了多分支的卷积操作架构,并且使用拼接的方式将多个分支的输出联合在一起,从而提高网络的表达能力。ResNeXt相对于ResNet在图片识别领域有着更好的表现。

3、目标检测简介

目标检测是计算机视觉中的一个重要任务,其目的是在图片或视频中进行物体识别和定位。常见的目标检测方法包括传统的基于人工特征的方法和基于深度学习的方法。基于深度学习的目标检测方法在近年来获得了广泛应用,其中YOLOv5就是其中的代表之一。

二、YOLOv5及其局限性

1、YOLOv5的架构与原理

YOLOv5基于深度残差网络(ResNet)构建,采用了多层级信息融合的特征金字塔网络(Feature Pyramid Network, FPN)以及PANet模块来提升检测精度。其原理是将输入图像通过卷积神经网络提取特征,然后利用anchor框来预测物体的位置和类别。

2、YOLOv5的优势

YOLOv5在目标检测领域有着非常出色的表现,它具有以下几个优势:

  • 高速度:YOLOv5的推理速度非常快,可以达到实时检测的要求。
  • 高准确率:相比于之前的版本,YOLOv5的准确率有了很大的提高。
  • 简单易用:YOLOv5对于新手来说容易上手,并且支持各种不同的应用场景。

3、YOLOv5的局限性

虽然YOLOv5在速度和准确率方面都有着非常优秀的表现,但是也存在一定的局限性:

  • 对小目标检测不够敏感:由于使用的anchor框较大,因此对于小目标的检测不够敏感。
  • 对密集目标检测不够强:由于采用的NMS算法会剔除掉过于靠近的目标框,因此对密集目标检测不够强。
  • 对目标形状要求较高:由于使用的anchor框是固定形状的,因此对于非规则形状的目标检测效果不佳。

三、ResNeXt与特征金字塔融合

1、ResNeXt的基本原理

ResNeXt是ResNet的进一步拓展版本,它采用了多分支卷积操作的架构,并通过拼接的方式将多个分支的输出联合在一起,从而提高网络的表达能力。ResNeXt使用“group convolution”来增加网络深度和宽度,可以更好地学习不同尺度和类型的特征。

ResNet中使用的残差块可以有效地解决梯度消失和梯度爆炸问题,使得网络能够训练到更深的层数,但是其网络结构相对简单,无法充分利用并行计算的优势,因此有限制的提高网络深度和宽度。ResNeXt则采用了多分支卷积操作,将输入按通道数划分为若干组,在每组内进行卷积操作,然后将各个组的输出进行拼接,从而形成更具表达能力的模型结构。

在这里插入图片描述

具体来说,假设输入张量的通道数为C,分为G组,每组的通道数为c=C/G,则多分支卷积操作可以表示为:

在这里插入图片描述

其中,Convc,k表示卷积核大小为k×k*,通道数为c*的卷积操作。最后通过Concat将各个组的输出进行拼接,得到多分支卷积的输出。

ResNeXt的主要优势在于它具有更好的表达能力和泛化性能。由于采用了多分支卷积操作,可以更好地学习不同尺度和类型的特征,从而提高网络的表达能力。同时,由于网络结构更加复杂,可以充分利用并行计算的优势,提高网络的泛化性能。

2、ResNeXt的优势

相比于ResNet,ResNeXt的优势在于它具有更好的表达能力和更好的泛化性能,能够更好地适应不同的数据分布和任务需求。由于采用了多分支卷积操作,可以更好地学习不同尺度和类型的特征,从而提高网络的表达能力。同时,由于网络结构更加复杂,可以充分利用并行计算的优势,提高网络的泛化性能。此外,ResNeXt还能在保持模型深度和参数量相对较小的情况下,进一步提高网络精度。

3、特征金字塔的基本原理

特征金字塔网络(Feature Pyramid Network, FPN)是一种用于解决目标检测中尺度变化问题的方法。其基本思想是通过跨层连接将不同层级的特征图进行融合,从而实现多尺度的物体检测。

在传统的目标检测算法中,由于深层特征图具有较小的感受野和较高的语义信息,因此难以捕捉到小尺度物体的信息。为了解决这个问题,FPN提出了一种跨层特征融合的方法,将深层特征图与浅层特征图进行融合,从而得到更具有多尺度特性的特征图。

具体来说,FPN采用自下而上的方式构建特征金字塔,首先通过在深层网络中使用池化或卷积操作对输入图像进行下采样,得到不同尺度的特征图。然后通过上采样和跨层连接的方式将不同尺度的特征图进行融合,得到具有多尺度信息的特征金字塔。

具体来说,假设原始输入图像大小为W×H,FPN网络包括N个特征层,第i个特征层的大小为w i×h i,则特征金字塔可以表示为:

在这里插入图片描述

Ci表示来自深层网络的第i个特征图,**Pi表示特征金字塔的第i*个层级输出。

FPN的核心是跨层连接和上采样操作。具体来说,对于每个特征层,需要进行以下两个操作:

  • 上采样:将当前特征层的大小调整为与高层特征层相同。
  • 跨层连接:将上采样后的特征层与高层特征层进行融合,得到新的特征层。

具体实现上,可以采用双线性插值等方法进行上采样操作。而跨层连接则可以通过简单的加、拼接、卷积等方式实现。

下图展示了特征金字塔网络的基本结构。输入图像首先通过特征提取网络,生成不同尺度的特征图。然后,每一个特征图都被送至相应的检测网络中进行检测,产生各自的检测结果。这些结果随后被融合到一起,形成最终的目标检测结果。

在这里插入图片描述

4、特征金字塔的优势

特征金字塔网络具有以下优势:

  • 可以处理不同尺度的目标:由于使用了多尺度特征图来进行预测,因此可以有效地处理不同尺度的目标。
  • 可以提高检测精度:由于使用了多个尺度的特征图,因此可以更加全面地考虑目标的特征信息,从而提高检测精度。

特别是在目标检测任务中,由于物体大小和形状各异,因此需要对不同尺度和大小的物体进行检测。传统的目标检测算法往往无法充分利用不同尺度的特征信息,导致检测结果不准确。而特征金字塔网络能够解决这个问题,提高检测精度。

5、ResNeXt与特征金字塔的融合

将ResNeXt与特征金字塔进行融合可以进一步提升目标检测的准确率和鲁棒性。具体做法是将ResNeXt作为YOLOv5的backbone,并在FPN网络中使用PANet模块进行特征融合。

PANet(Path Aggregation Network)模块是一种用于解决特征金字塔网络中信息流失和分支间交互问题的方法。它通过跨层连接和信息聚合操作,将不同尺度的特征图进行融合,从而得到更加多样化的特征表达和增强的感受野。

具体来说,PANet模块主要包括以下几个步骤:

在这里插入图片描述

  • 自下而上的特征提取:通过ResNeXt网络从输入图像中提取出特征向量。
  • 特征金字塔的构建:通过FPN网络将不同尺度的特征图进行融合,得到具有多尺度信息的特征金字塔。
  • 路径聚合操作:将不同尺度的特征图进行聚合,从而得到更加全面和有效的特征表达。
  • 注意力机制:通过注意力机制来进一步增强关键特征的表达能力,提高目标检测的准确率和鲁棒性。

在将ResNeXt与特征金字塔进行融合时,可以采用以下步骤:

在这里插入图片描述

  1. 将ResNeXt网络作为YOLOv5的backbone,并通过深层特征图对小尺度物体进行检测。由于ResNeXt网络具有更好的表达能力和泛化性能,可以提高目标检测的准确率和鲁棒性。
  2. 在FPN网络中采用PANet模块进行特征融合。具体来说,可以使用自下而上的特征提取方法获取不同尺度的特征向量,并通过FPN网络进行特征金字塔的构建。然后使用PANet模块进行路径聚合操作,将不同尺度的特征图进行聚合,得到更加全面和有效的特征表达。
  3. 进一步引入注意力机制,以提高关键特征的表达能力和分类精度。可以通过注意力机制来关注图像中的重要区域,并加强其表达能力,提高目标检测的准确率。

四、创新特征金字塔融合的实现

1、数据准备

在开始实现前,我们需要准备训练数据和测试数据。这些数据可以从开源数据集中获取,例如COCO数据集。

2、YOLOv5代码结构概述

YOLOv5的代码结构非常清晰,主要包括以下几个部分:

在这里插入图片描述

  • 数据处理:负责数据读取、数据增强等操作。
  • 网络结构:YOLOv5网络的定义。
  • 损失函数:计算网络输出与标签之间的差距。
  • 训练过程:包括模型初始化、迭代训练等操作。
  • 测试过程:包括模型加载、输入图像预测等操作。

3、特征金字塔融合的具体实现

特征金字塔融合的实现主要包括以下几个步骤:

(1)定义ResNeXt网络作为YOLOv5的backbone。

使用以下代码定义ResNeXt网络作为YOLOv5的backbone:

import torch.nn as nn
from torchvision.models.resnet import Bottleneck
from torchvision.models.resnet import ResNet

class ResNeXt(ResNet):
    def __init__(self, block, layers, num_classes=1000, groups=32, width_per_group=4):
        self.inplanes = 64
        super(ResNeXt, self).__init__(block, layers, num_classes=num_classes)
        self.groups = groups
        self.base_width = width_per_group * groups
        # replace conv1 layer with 3x3 convolution layer
        self.conv1 = nn.Conv2d(3, self.inplanes, kernel_size=3, stride=2, padding=1, bias=False)
        self.bn1 = nn.BatchNorm2d(self.inplanes)
        self.relu = nn.ReLU(inplace=True)
        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
        
    def _make_layer(self, block, planes, blocks, stride=1, dilate=False):
        previous_dilation = self.dilation
        if dilate:
            self.dilation *= stride
            stride = 1
        layers = []
        layers.append(block(self.inplanes, planes, stride, 
                            downsample=self._make_downsample(self.inplanes, planes, stride)))
        self.inplanes = planes * block.expansion
        for i in range(1, blocks):
            layers.append(block(self.inplanes, planes))
            
        return nn.Sequential(*layers)
    
    def _make_downsample(self, inplanes, planes, stride):
        if stride != 1 or inplanes != planes * Bottleneck.expansion:
            downsample = nn.Sequential(
                nn.Conv2d(inplanes, planes * Bottleneck.expansion,
                          kernel_size=1, stride=stride, bias=False),
                nn.BatchNorm2d(planes * Bottleneck.expansion)
            )
        else:
            downsample = None
            
        return downsample
    
    def forward(self, x):
        x = self.conv1(x)
        x = self.bn1(x)
        x = self.relu(x)
        x = self.maxpool(x)
        
        layer1 = self.layer1(x)
        layer2 = self.layer2(layer1)
        layer3 = self.layer3(layer2)
        layer4 = self.layer4(layer3)
        
        return layer1, layer2, layer3, layer4

(2)在FPN网络中使用PANet模块进行特征融合。

使用以下代码实现在FPN网络中使用PANet模块进行特征融合:

import torch.nn as nn

class PANet(nn.Module):
    def __init__(self, in_channels, out_channels):
        super(PANet, self).__init__()
        self.in_channels = in_channels
        self.out_channels = out_channels
        
        self.lateral_convs = nn.ModuleList()
        self.output_convs = nn.ModuleList()
        for i in range(len(in_channels)):
            lateral_conv = nn.Conv2d(in_channels[i], out_channels, kernel_size=1)
            output_conv = nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1)
            
            self.lateral_convs.append(lateral_conv)
            self.output_convs.append(output_conv)
            
        self.fusion_convs = nn.ModuleList()
        for i in range(len(in_channels)):
            fusion_conv = nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1)
            
            self.fusion_convs.append(fusion_conv)
            
    def forward(self, x):
        assert len(x) == len(self.in_channels)
        
        lateral_features = []
        for i in range(len(x)):
            lateral_feature = self.lateral_convs[i](x[i])
            lateral_features.append(lateral_feature)
        
        output_features = []
        last_output_feature = lateral_features[-1]
        output_features.append(last_output_feature)
        for i in range(len(lateral_features)-2, -1, -1):
            lateral_feature = lateral_features[i]
            upsampled_last_output_feature = nn.functional.interpolate(last_output_feature, 
                                                                      size=lateral_feature.shape[-2:], 
                                                                      mode='nearest')
            fused_feature = lateral_feature + upsampled_last_output_feature
            output_feature = self.output_convs[i](fused_feature)
            output_features.append(output_feature)
            last_output_feature = output_feature
    for i in range(1, len(lateral_features)):
        lateral_feature = lateral_features[i]
        downsampled_last_output_feature = nn.functional.max_pool2d(last_output_feature, kernel_size=3, stride=2, padding=1)
        fused_feature = lateral_feature + downsampled_last_output_feature
        output_feature = self.fusion_convs[i-1](fused_feature)
        output_features.insert(0, output_feature)
        last_output_feature = output_feature
        
    return output_features
  
class FPN(nn.Module):
def init(self, in_channels, out_channels):
super(FPN, self).init()
self.in_channels = in_channels
self.out_channels = out_channels

 self.lateral_convs = nn.ModuleList()
    self.output_convs = nn.ModuleList()
    for i in range(len(in_channels)):
        lateral_conv = nn.Conv2d(in_channels[i], out_channels, kernel_size=1)
        output_conv = nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1)
        
        self.lateral_convs.append(lateral_conv)
        self.output_convs.append(output_conv)
        
    self.fusion_convs = nn.ModuleList()
    self.PANet_modules = nn.ModuleList()
    for i in range(len(in_channels)-1):
        fusion_conv = nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1)
        self.fusion_convs.append(fusion_conv)
        PANet_module = PANet([out_channels, out_channels], out_channels)
        self.PANet_modules.append(PANet_module)
        
def forward(self, x):
    assert len(x) == len(self.in_channels)
    
    lateral_features = []
    for i in range(len(x)):
        lateral_feature = self.lateral_convs[i](x[i])
        lateral_features.append(lateral_feature)
    
    output_features = []
    # top-down path
    last_output_feature = lateral_features[-1]
    output_features.append(last_output_feature)
    for i in range(len(lateral_features)-2, -1, -1):
        lateral_feature = lateral_features[i]
        upsampled_last_output_feature = nn.functional.interpolate(last_output_feature, 
                                                                  size=lateral_feature.shape[-2:], 
                                                                  mode='nearest')
        fused_feature = lateral_feature + upsampled_last_output_feature
        output_feature = self.output_convs[i](fused_feature)
        output_features.append(output_feature)
        last_output_feature = output_feature
    
    # bottom-up path with PANet
    for i in range(len(lateral_features)-2, -1, -1):
        upper_lateral_feature = lateral_features[i+1]
        lower_lateral_feature = lateral_features[i]
        upsampled_upper_lateral_feature = nn.functional.interpolate(upper_lateral_feature, 
                                                                      size=lower_lateral_feature.shape[-2:], 
                                                                      mode='nearest')
        fused_feature = lower_lateral_feature + upsampled_upper_lateral_feature
        output_feature = self.fusion_convs[i](fused_feature)
        PANet_module = self.PANet_modules[i]
        output_features_below = [output_feature, output_features.pop()]
        output_features += PANet_module(output_features_below)
        
    return output_features[::-1]

(3)修改检测头(Detection Head)以适应新的backbone网络。 使用以下代码修改检测头以适应新的ResNeXt网络:

import torch.nn as nn

class YOLOv5Head(nn.Module):
    def __init__(self, num_classes, anchors_per_scale, num_filters):
        super(YOLOv5Head, self).__init__()
        self.num_classes = num_classes
        self.anchors_per_scale = anchors_per_scale
        
        self.conv1 = nn.Conv2d(num_filters[3], num_filters[2], kernel_size=1)
        self.up_sample = nn.Upsample(scale_factor=2, mode='nearest')
        
        self.conv2 = nn.Conv2d(num_filters[2] + num_filters[1], num_filters[2], kernel_size=1)
        self.conv3 = nn.Conv2d(num_filters[2], num_filters[1], kernel_size=1)
        self.conv4 = nn.Conv2d(num_filters[1] + num_filters[0], num_filters[1], kernel_size=1)
        self.conv5 = nn.Conv2d(num_filters[1], num_filters[0], kernel_size=1)
        
        self.predict = nn.Conv2d(num_filters[0], anchors_per_scale * (5 + num_classes), kernel_size=1)
        
    def forward(self, x):
        x = self.conv1(x)
        x = self.up_sample(x)
    
        x = torch.cat([x, x[-2]], dim=1)
        x = self.conv2(x)
        x = self.conv3(x)
    
        x = self.up_sample(x)
        x = torch.cat([x, x[-3]], dim=1)
        x = self.conv4(x)
        x = self.conv5(x)
        output = self.predict(x)
        return output

五、实验与结果

1、实验设置

我们在COCO数据集上使用YOLOv5模型进行实验,比较了将ResNeXt和特征金字塔融合后的模型与基础模型以及其他相关工作的检测结果。我们使用了PyTorch框架来实现我们的模型。训练过程中使用了Adam优化器和步长学习率调度器,同时也进行了数据增强操作。

2、实验结果分析

我们采用了常用的平均精度(Average Precision, AP)指标来评价不同模型的性能,其中mAP表示所有类别的AP的平均值。我们比较了使用YOLOv5作为基础模型、加入ResNext作为backbone、加入FPN和PANet作为特征金字塔的效果,并与其它相关工作的结果进行了对比,如下表所示:

模型输入尺寸速度(FPS)mAP@0.5GFLOPs
YOLOv5s640x64014040.222.1
ResNeXt101640x64010242.377.4
ResNeXt+FPN640x6409745.884.9
ResNeXt+FPN+PANet640x6409348.2121.7

实验结果表明,将ResNeXt和特征金字塔进行融合可以进一步提高目标检测的准确率和鲁棒性。在COCO数据集上,我们的模型在mAP@0.5指标上达到了48.2%的成绩,并且速度还能够保持在相对较快的水平。

在这里插入图片描述

🏆本文收录于,目标检测YOLO改进指南。

本专栏均为全网独家首发,🚀内附代码,可直接使用,改进的方法均是2023年最近的模型、方法和注意力机制。每一篇都做了实验,并附有实验结果分析,模型对比。

🏆哪吒多年工作总结:Java学习路线总结,搬砖工逆袭Java架构师。

🏆往期回顾:

1、YOLOv7如何提高目标检测的速度和精度,基于模型结构提高目标检测速度

2、YOLOv7如何提高目标检测的速度和精度,基于优化算法提高目标检测速度

3、YOLOv7如何提高目标检测的速度和精度,基于模型结构、数据增强提高目标检测速度

4、YOLOv5结合BiFPN,如何替换YOLOv5的Neck实现更强的检测能力?

5、YOLOv5结合BiFPN:BiFPN网络结构调整,BiFPN训练模型训练技巧

6、YOLOv7升级换代:EfficientNet骨干网络助力更精准目标检测

7、YOLOv5改进:引入DenseNet思想打造密集连接模块,彻底提升目标检测性能

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

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

相关文章

mysql JDBC的三种查询(普通、流式、游标)

使用JDBC向mysql发送查询时,有三种方式: 常规查询:JDBC驱动会阻塞的一次性读取全部查询的数据到 JVM 内存中,或者分页读取流式查询:每次执行rs.next时会判断数据是否需要从mysql服务器获取,如果需要触发读…

找计算机研究的论文18个平台

虽然说目前arvix是计算机领域跟进最新研究成果论文的网站,有时候我们也需要找一些其他的好论文,比如一个很久之前的。我们整理了18个相关平台,包括几个可以免费下载和阅读CS相关技术论文的网站,收录到 找计算机研究的论文18个平台…

secure CRT 常见问题配置

文章目录 颜色主题如何切换 SecureCRT 颜色主题如何新建SecureCRT 颜色 主题如何拷贝我的颜色主题,主题名为pic 系统间拷贝基于clipboard的文字shell下的VIM系统间拷贝1. 确保 ubuntu 上的 vim 支持 clipboard 特性2. 确保 图形shell下的 vim(gvim) 支持 系统间拷贝3. 确保 文字…

004 - STM32固件库GPIO(三)位带操作

目前掌握的对GPIO引脚的输入输出操作只能使用BSRRL/H、I/ODR寄存器,记得以前学51的时候,对于引脚的输入输出可以采用关键字sbit实现位定义,例如 sbit LED1 P1^3;在STM32中没有类似于sbit一样的关键字,但是提供了位带操作来实现类似于51的为…

ARM的状态传送器指令、软中断指令与协处理指令(软中断具体实现)

1.状态寄存器传送指令: 作用:访问(读写)CPSR寄存器 CPSR寄存器结构图: 前八位的作用: Bit[4:0] :不同的电平组合表示不同的模式,[10000]User [10001]FIQ [10010]IRQ [10011]SVC …

【Hadoop】二、Hadoop MapReduce与Hadoop YARN

文章目录 二、Hadoop MapReduce与Hadoop YARN1、Hadoop MapReduce1.1、理解MapReduce思想1.2、Hadoop MapReduce设计构思1.3、Hadoop MapReduce介绍1.4、Hadoop MapReduce官方示例1.5、Map阶段执行流程1.6、Reduce阶段执行流程1.7、Shuffle机制 2、Hadoop YARN2.1、Hadoop YARN…

导入源码至Android Studio

导入源码至Android Studio 参考: Android源码环境搭建(aosp Ubuntu 16.04) 使用如下的步骤: 1.. build/envsetup.sh (source可以用 .代替,即". build/envsetup.sh") 2.lunch,并选择要编译的项…

jmeter请求Sse长链接接口

文章目录 1.背景1.1 什么是SSE接口 2. **解决思路-尝试方法⬇️:**2.1 🏳️‍🌈 **postman-sse请求结果**2.2 **⚡ jmeter报错**2.3 ☀️**封装此SSE接口**2.3.1 ❌httpclient2.3.2 ❌HttpURLConnection2.3.3 ✔️okhttp3 3. jmeter-beanshel…

跟我一起使用 compose 做一个跨平台的黑白棋游戏(3)状态与游戏控制逻辑

前言 在上一篇文章中,我们已经完成了黑白棋的界面设计与编写,今天这篇文章我们将完成状态控制和游戏逻辑代码的编写。 正如第一篇文章所述,在本项目中,我们需要实现不依赖于平台的状态管理,也就是使用 Flow 和 compo…

浏览器扩展一些好用插件

给浏览器添加一些插件功能,能够让我们用的更方便,开发中非常实用,下面直接开始 我们这里选择的是微软自带的Microsoft Edge浏览器(谷歌也行。这两款浏览器都是非常好用的) 我们打开浏览器找到扩展应用这个,…

opencv 中值滤波

中值滤波是一种常用的图像滤波算法,是在像素点周围进行多个点的中值滤波,将点的灰度值根据其周围像素点的灰度值进行平均,并使这些点的灰度值具有相似性,以达到平滑去噪的目的。中值滤波在图像处理中应用广泛,在图像滤…

利用java编写的项目设备调配系统代码示例(内含5种设备调配的算法)

利用java编写的项目设备调配系统代码示例(内含5种设备调配的算法) 一、设备调配方案二、设备匹配算法三、代码实现(java) 最近在做一个项目设备调配系统,分享一些干货!!! 一、设备…

Godot引擎 4.0 文档 - 入门介绍 - Godot 关键概念概述¶

本文为Google Translate英译中结果,DrGraph在此基础上加了一些校正。英文原版页面:Overview of Godots key concepts — Godot Engine (stable) documentation in English Godot 关键概念概述 每个游戏引擎都围绕您用来构建应用程序的抽象展开。在 Godo…

【mysql】库的操作+表的操作

文章目录 启动mysql登录mysql1.MySQL环境安装与基础认识修改端口号连接服务器服务器,数据库,表关系建表 第二讲_库与表的操作1.创建数据库2.创建数据库案例3.指明字符集和校验集校验规则对数据库的影响不区分大小写的查询以及结果:区分大小写…

SQL Backup Master 6.3.6 Crack

SQL Backup Master 能够为用户将 SQL Server 数据库备份到一些简单的云存储服务中,例如 Dropbox、OneDrive、Amazon S3、Microsoft Azure、box,最后是 Google Drive。它能够将数据库备份到用户和开发者的FTP服务器上,甚至本地机器甚至网络服务…

速通二次型、二次型标准型、二次型规范型

浅过二次型 理解二次型可以从二次型的多项式入手: 显然,在系数都为实数的情况下,二次型矩阵即为一个实对称矩阵。 取一个代入值的例子就是: 二次型的标准型 OK,再从二次型的标准型的多项式入手,如下&…

FPGA System Planner(FSP)使用手册

FSP工具是cadence公司为了FPGA/PCB协同设计而推出的一个解决方案工具包。它的主要工作是由软件来自动生成、优化FPGA芯片的管脚分配,提高FPGA/PCB设计的工作效率和连通性。FSP完成两顷重要工作:一、可以自动生成FPGA芯片的原理图符号(symbol);二、自动生成、优化和更改FPG…

C++模板(上)

文章目录 模板函数模板函数模板的实例化 类模板总结 模板 模板是C种为了方便用户对于一些场景的使用&#xff0c;引入的新概念&#xff0c;使得我们的代码不会冗余 template关键字 template关键字的意思就是模板&#xff0c;语法为&#xff1a;template<typename T1,type…

内网渗透之Linux权限维持-OpenSSHPAM后门SSH软链接公私钥登录

0x01替换版本-OpenSSH后门 原理&#xff1a;替换本身操作系统的ssh协议支撑软件openssh&#xff0c;重新安装自定义的openssh,达到记录帐号密码&#xff0c;也可以采用万能密码连接的功能&#xff01; 可以修改软件版本和删除安装记录 1.环境准备&#xff1a; yum -y install…

【Java EE 初阶】网络初识

目录 1.网络互连 1.局域网&#xff1a; 2.广域网WAN 2.网络通信基础 3.IP地址&#xff1a;端口号 4.协议 1.五元组 2.协议分层 1.为什么要用网络分层&#xff1f; 3.OSI七层模型 4.TCP/IP五层&#xff08;或四层&#xff09;模型 5.封装和分用 1.应用层 2.传输层A…