【youcans动手学模型】目标检测之 RCNN 模型

news2024/11/26 12:28:57

欢迎关注『youcans动手学模型』系列
本专栏内容和资源同步到 GitHub/youcans


【youcans动手学模型】目标检测之 RCNN 模型

    • 1. R-CNN 目标检测
      • 1.1 论文摘要
      • 1.2 技术背景
      • 1.3 基本方法
      • 1.4 算法实现
      • 1.5 总结
    • 2. 使用 PyTorch 实现 RCNN 目标检测
      • 2.1 训练 AlexNet 模型
      • 2.2 微调 AlexNet 预训练模型
      • 2.3 训练 SVM 分类器
      • 2.4 训练 BBox 回归器
      • 2.5 模型预测


本文介绍 RCNN 目标检测方法,并使用 PyTorch 实现 RCNN 方法。


1. R-CNN 目标检测

R-CNN(Regions with Convolutional Neural Network Features) 是目标检测任务的经典模型,属于两阶段(two-stage)目标检测方法。

论文发表于 2014年 CVPR。

Ross Girshick, Jeff Donahue, Trevor Darrell, Jitendra Malik. Rich feature hierarchies for accurate object detection and semantic segmentation. 2014 CVPR
【下载地址】: https://arxiv.org/abs/1311.2524
【GitHub地址】:
https://github.com/rbgirshick/rcnn
https://github.com/bigbrother33/Deep-Learning

在这里插入图片描述


1.1 论文摘要

近年来基于 PASCAL VOC 标准数据集的目标检测任务的性能比较平稳。性能最好的方法是复杂的集成系统,通常将多个图像特征与上下文相结合。在本文中,我们提出了一种简单且可扩展的检测算法,该算法将平均检测精度(mAP)提高了 30% 以上(VOC 2012 的最佳结果为53.3%)。

本文的方法结合了两个关键技术:

(1)在候选区域(region proposal)自下而上地使用卷积神经网络(CNNs),进行定位和分割对象;

(2)当训练数据不足时,先针对辅助任务进行有监督的预训练,再进行特定任务的微调,可以显著提高性能。

我们将这种候选区域与 CNN 相结合的方法称为 R-CNN: Regions with CNN features 。

我们将 R-CNN 与基于 CNN架构的滑动窗口检测器 OverFeat 进行比较,在 ILSVRC2013检测数据集上 R-CNN的性能大大优于OverFeat。


1.2 技术背景

图像分类、目标检测和图像分割

图像分类、目标检测和图像分割都是计算机视觉领域最基础、最常用、发展最迅速的任务。我们首先看看这几个任务之间的区别。

  • 图像分类:输入图像中通常只有一个物体,目的是判断图像中物体的类别,属于图像级别的任务。
  • 目标检测:输入图像中通常有一个或多个物体,目的是判断每个物体的位置与类别,属于计算机视觉中的核心任务。
  • 图像分割:输入图像中通常有一个或多个物体,目的是判断图像中每一个像素属于哪一个类别,属于像素级的分类。

在这里插入图片描述

图像分类任务针对图像中只有一个目标的情况。分类目标可以有多种类别(例如猫、狗等),但输入图像中通常只有一个类别的实例。但是,大多数图像中可能有多个/多种目标,需要找到目标的位置,并对它们进行分类。这种情况就是目标检测。

在目标检测中,我们不仅对输入图像中的目标感兴趣,还关心目标在输入图像中的位置。目标检测比图像分类问题更复杂,计算时间通常是后者的数百倍。因此,对于目标的位置不重要的问题,应该使用图像分类算法。


现有的目标检测方法

特征很重要。在过去十年中,各类视觉识别任务基本都建立在对 SIFT 和 HOG 特征的使用,但性能的进展比较缓慢。例如,基于 HOG 的可变性部件优化模型(deformable part model,DPM),可以视为 HOG+SVM 的扩展和改进,连续获得了 2007~2009 的目标检测任务冠军 。

卷积神经网络在1990年代提出,2012年 AlexNet 模型在 ImageNet 挑战赛获得冠军,使卷积神经网络受到了广泛关注。但是,HOG-like 特征简单明确、容易理解;而 CNN 所提取的特征,可视化和可解释性很差。

一个核心问题是:在 ImageNet 上训练的 CNN 分类模型,能否及如何应用到物体检测任务上?我们关注两个问题:(1)使用深度卷积网络定位物体,(2)在小规模的数据集上进行网络模型的训练。

目标检测需要在图像中定位物体(可能有多个)。一种方法是将边界框的定位视为回归问题,但其性能并不好;另一种方法是构造滑动窗口检测器,但是由于网络层次很深,输入图片的感受野(195×195)和步长(32×32)很大,使滑动窗口方法充满挑战。


选择性搜索产生候选区域

候选区域是可能的边界框的列表,但它包含检测目标的可能性很小,而且并不检测目标的类别。

通过选择性搜索(Selective Search, SS)基于颜色、纹理、大小和形状的一致性计算相似区域的分层分组,从一张图片上提取若干候选区域(region proposal)。
选择性搜索算法的主要步骤为:
(1)基于颜色、纹理、尺度等特征,计算所有邻近区域之间的相似性;
(2)合并相似度最高的区域;
(3)计算合并区域和临近区域的相似度;
(4)重复以上过程,直到整个图片合并为一个区域。

在每次迭代中,形成更大的区域并将其添加到候选区域集合中。通过这种自下而上的方式,可以创建从小到大的不同尺度和形状的候选区域。

在这里插入图片描述


1.3 基本方法

我们基于区域识别(recognition using regions)处理卷积神经网络的定位问题。

先对每张图片产生约2000个候选区域(region proposal),再对每个区域使用 CNN 生成固定长度的特征向量,最后对每个区域用 SVM 分类器进行分类。这种方法结合了 Region proposals 和 CNN,所以将其称为 R-CNN:Regions with CNN features。

在这里插入图片描述

R-CNN 目标检测主要分为 4个阶段:

(1)候选区域。

R-CNN 并不依赖于特定的候选区域算法,我们使用选择性搜索,以便与先前的研究进行比较。
使用选择性搜索(SS)方法,对每张图片产生约 2000个候选区域(region proposal)。这些候选区域的边界框的位置、尺寸和宽高比各不不同,而且大多数候选区域中并不包含任何目标。

(2)特征提取。

使用卷积神经网络模型,从每个候选区域中提取 4096 维特征向量。
以 AlexNet 网络为例,输入图片为 227*227像素。对于大小和形状不同的候选区域,我们直接将不同尺寸的候选区域通过缩放调整到 227*227像素。

(3)类别判定。

使用 SVM 分类器,判断每个候选区域属于某个类别或背景。以检测 20 个类别物体为例,另有输入图像中没有物体的情况作为背景类,共有 21类。将 2000*4096 维特征向量送入 SVM 分类器,得到 2000*21 维输出矩阵,表示每个候选区域属于某类别的概率。
在 2000个候选区域中,存在大量重叠的候选区域,可以使用非极大值抑制(NMS)方法消除冗余的候选框。

(4)精细定位。

经过 NMS 筛选得到的候选区域,定位精度通常并不高,需要进一步的精细定位。
建立并训练一个边界框回归模型(bbox regressor),可以提高候选区域的定位精度。


1.4 算法实现

使用 PyTorch 建立、训练和使用 RCNN 进行目标检测的基本步骤如下。

(1)训练卷积神经网络。

论文中使用 AlexNet 网络架构,但也可以使用其它网络架构,例如 VGG16 网络。经过测试 AlexNet网络的精度为58.5%,而 VGG16 网络的精度为66%,但 VGG的计算量是 AlexNet 的 7 倍。

(2)微调预训练模型。

很多预训练模型是在 ImageNet 数据集进行训练,有 1000 个分类,模型比较庞大。
为了让预训练模型适应新的任务和新的领域,我们使用缩放后的候选窗口作为输入,对预训练模型参数进行微调。我们把预训练模型中的 1000类的分类器,用一个 21类的分类层替代(VOC数据集的20类别+背景类别),而将模型中的卷积层的结构和参数固定不变。

(3)训练 SVM 分类器。

思考一下检测汽车的二分类器。很显然,一个图像区域紧紧包裹着一辆汽车应该就是正例。同样的,没有汽车的就是背景区域,也就是负例。较为不明确的是怎样标注哪些只和汽车部分重叠的区域。我们使用IoU重叠阈值来解决这个问题,低于这个阈值的就是负例。这个阈值我们选择了0.3,是在验证集上基于{0, 0.1, … 0.5}通过网格搜索得到的。

(4)训练 BBox 回归器。

我们使用一种简单的回归方法减小定位误差。受到 DPM 中的约束框回归训练的启发,我们训练了一个线性回归模型在给定一个选择区域的 pool5 特征时,预测一个新的检测窗口。
BBox 回归方法简单,修复了大量的检测错位,使检测性能提升了 3-4 个百分点。

(5)使用非最大值抑制方法(NMS)对结果进行筛选,消除冗余的边界框 。

(6)模型预测。


1.5 总结

R-CNN 将卷积神经网络引入目标检测领域,与传统方法相比检测性能显著提高。其后的系列文章 Fast RCNN, Faster RCNN 在此基础上不断改进,开拓和引领了目标检测领域新的研究方向。

R-CNN 的不足在于:
(1)训练阶段多,步骤繁琐。先要预训练 CNN,然后微调 CNN,再训练 SVM,训练回归器,还要用 NMS 筛选。
(2)训练耗时,占用磁盘空间大。
(3)处理速度慢,需要对 2000 个候选区域分别提取特征,有很多重复的计算。
(4)对候选区域的高宽进行不同比例的缩放,容易引起物体变形。

在这里插入图片描述


2. 使用 PyTorch 实现 RCNN 目标检测

为了简单起见,选择 17flowers 的小型数据集,而不是 PASCAL VOC 2012。17flowers 数据集可以从官网下载:http://www.robots.ox.ac.uk/~vgg/data/flowers/17/


2.1 训练 AlexNet 模型

使用 17flowers 数据集训练 Alexnet 网络,得到分类任务的预训练模型。

$ python train_step1.py

train_step1.py 例程如下。

from __future__ import division
from data.dataset_factory import DatasetFactory
from models.model_factory import ModelsFactory
from options.train_options import TrainOptions



class Train_step1:
    def __init__(self):
        self._opt = TrainOptions().parse()

        self._dataset_train = DatasetFactory.get_by_name("AlexnetDataset", self._opt)
        self._dataset_train_size = len(self._dataset_train)
        print('#train images = %d' % self._dataset_train_size)

        self._model = ModelsFactory.get_by_name("AlexModel", self._opt, is_train=True)

        self._train()

    def _train(self):
        self._steps_per_epoch = int (self._dataset_train_size / self._opt.batch_size)
        
        for i_epoch in range(self._opt.load_alex_epoch + 1, self._opt.total_epoch + 1):
            # train epoch
            self._train_epoch(i_epoch)

            # save model
            if i_epoch % 20 == 0:
                print('saving the model at the end of epoch %d' % i_epoch)
                self._model.save(i_epoch)

    def _train_epoch(self, i_epoch):

        for step in range(1, self._steps_per_epoch+1):
            input, labels = self._dataset_train.get_batch()

            # train model
            self._model.set_input(input, labels)
            self._model.optimize_parameters()

            # display terminal
            self._display_terminal_train(i_epoch, step)

    def _display_terminal_train(self, i_epoch, i_train_batch):
        errors = self._model.get_current_errors()
        message = '(epoch: %d, it: %d/%d) ' % (i_epoch, i_train_batch, self._steps_per_epoch)
        for k, v in errors.items():
            message += '%s:%.3f ' % (k, v)

        print(message)

if __name__ == "__main__":
    Train_step1()

2.2 微调 AlexNet 预训练模型

使用 2flowers 数据集对 Alexnet 预训练网络进行微调,得到微调模型。

$ python train_step2.py --batch_size 128 --load_alex_epoch 100 --options_dir finetune

train_step2.py 例程如下。

from __future__ import division
from data.dataset_factory import DatasetFactory
from models.model_factory import ModelsFactory
from options.train_options import TrainOptions


class Train_step2:
    def __init__(self):
        self._opt = TrainOptions().parse()

        self._dataset_train = DatasetFactory.get_by_name("FinetuneDataset", self._opt)
        self._dataset_train_size = len(self._dataset_train)
        print('#train images = %d' % self._dataset_train_size)

        self._model = ModelsFactory.get_by_name("FineModel", self._opt, is_train=True)
        self._train()

    def _train(self):
        self._steps_per_epoch = int (self._dataset_train_size / self._opt.batch_size)
        
        for i_epoch in range(self._opt.load_finetune_epoch + 1, self._opt.total_epoch + 1):
            # train epoch
            self._train_epoch(i_epoch)

            # save model
            if i_epoch % 20 == 0:
                print('saving the model at the end of epoch %d' % i_epoch)
                self._model.save(i_epoch)

    def _train_epoch(self, i_epoch):

        for step in range(1, self._steps_per_epoch+1):
            input, labels = self._dataset_train.get_batch()

            # train model
            self._model.set_input(input, labels)
            self._model.optimize_parameters()

            # display terminal
            self._display_terminal_train(i_epoch, step)

    def _display_terminal_train(self, i_epoch, i_train_batch):
        errors = self._model.get_current_errors()
        message = '(epoch: %d, it: %d/%d) ' % (i_epoch, i_train_batch, self._steps_per_epoch)
        for k, v in errors.items():
            message += '%s:%.3f ' % (k, v)

        print(message)

if __name__ == "__main__":
    Train_step2()

2.3 训练 SVM 分类器

使用从微调模型中提取的特征来训练 SVM,得到分类任务模型。

$ python train_step3.py --load_finetune_epoch 100 --options_dir svm

train_step3.py 例程如下。

from __future__ import division
from data.dataset_factory import DatasetFactory
from models.model_factory import ModelsFactory
from options.train_options import TrainOptions
import numpy as np

class Train_step3:
    def __init__(self):
        self._opt = TrainOptions().parse()

        self._dataset_train = DatasetFactory.get_by_name("SVMDataset", self._opt)
        self._dataset_train_size = len(self._dataset_train)
        print('#train images = %d' % self._dataset_train_size)

        self.classA_features, self.classA_labels, self.classB_features, self.classB_labels = self._dataset_train.get_datas()

        self._modelA = ModelsFactory.get_by_name("SvmModel", self._opt, is_train=True)
        self._modelB = ModelsFactory.get_by_name("SvmModel", self._opt, is_train=True)

        self._train(self._modelA, self.classA_features, self.classA_labels, "A")
        self._train(self._modelB, self.classB_features, self.classB_labels, "B")

    def _train(self, model, features, labels, name):
        model.train(features, labels)
        model.save(name)
        pred = model.predict(features)

        print (labels)
        print (pred)
        
        

if __name__ == "__main__":
    Train_step3()  

2.4 训练 BBox 回归器

训练一个回归网络,用于边界框的精细定位。

$ python train_step4.py --decay_rate 0.5 --options_dir regression --batch_size 512

train_step4.py 例程如下。

from __future__ import division
from data.dataset_factory import DatasetFactory
from models.model_factory import ModelsFactory
from options.train_options import TrainOptions

class Train_step4:
    def __init__(self):
        self._opt = TrainOptions().parse()

        self._dataset_train = DatasetFactory.get_by_name("RegDataset", self._opt)
        self._dataset_train_size = len(self._dataset_train)
        print('#train images = %d' % self._dataset_train_size)

        self._model = ModelsFactory.get_by_name("RegModel", self._opt, is_train=True)

        self._train()

    def _train(self):
        self._steps_per_epoch = int (self._dataset_train_size / self._opt.batch_size)
        
        for i_epoch in range(self._opt.load_reg_epoch + 1, self._opt.total_epoch + 1):
            # train epoch
            self._train_epoch(i_epoch)

            # save model
            if i_epoch % 20 == 0:
                print('saving the model at the end of epoch %d' % i_epoch)
                self._model.save(i_epoch)

    def _train_epoch(self, i_epoch):

        for step in range(1, self._steps_per_epoch+1):
            input, labels = self._dataset_train.get_batch()

            # train model
            self._model.set_input(input, labels)
            self._model.optimize_parameters()

            # display terminal
            self._display_terminal_train(i_epoch, step)

    def _display_terminal_train(self, i_epoch, i_train_batch):
        errors = self._model.get_current_errors()
        message = '(epoch: %d, it: %d/%d) ' % (i_epoch, i_train_batch, self._steps_per_epoch)
        for k, v in errors.items():
            message += '%s:%.3f ' % (k, v)

        print(message)

if __name__ == "__main__":
    Train_step4()        

2.5 模型预测

使用在 17flowers 数据集上训练的 RCNN 模型,输入图像进行目标检测。

$ python evaluate.py --load_finetune_epoch 100 --load_reg_epoch 40 --img_path ./sample_dataset/2flowers/jpg/1/image_1281.jpg

evaluate.py 例程如下。

from __future__ import division
from models.model_factory import ModelsFactory
from options.test_options import TestOptions
from utils.util import image_proposal
from utils.util import show_rect
import torch
import numpy as np

class Test:
    def __init__(self):
        self._opt = TestOptions().parse()
        self._img_path = self._opt.img_path
        self._img_size = self._opt.image_size

        self.fine_model = ModelsFactory.get_by_name('FineModel', self._opt, is_train=False)
        self.svm_model_A = ModelsFactory.get_by_name('SvmModel', self._opt, is_train=False)
        self.svm_model_A.load('A')
        self.svm_model_B = ModelsFactory.get_by_name('SvmModel', self._opt, is_train=False)
        self.svm_model_B.load('B')
        self.svms = [self.svm_model_A, self.svm_model_B]
        self.reg_model = ModelsFactory.get_by_name('RegModel', self._opt, is_train=False)

        self.test()

    def test(self):
        imgs, _, rects = image_proposal(self._img_path, self._img_size)

        show_rect(self._img_path, rects, ' ')

        input_data=torch.Tensor(imgs).permute(0,3,1,2)
        features, _ = self.fine_model._forward_test(input_data)
        features = features.data.cpu().numpy()

        results = []
        results_old = []
        results_label = []
        count = 0

        flower = {1:'pancy', 2:'Tulip'}

        for f in features:
            for svm in self.svms:
                pred = svm.predict([f.tolist()])
                # not background
                if pred[0] != 0:
                    results_old.append(rects[count])
                    input_data=torch.Tensor(f)
                    box = self.reg_model._forward_test(input_data)
                    box = box.data.cpu().numpy()
                    if box[0] > 0.3:
                        px, py, pw, ph = rects[count][0], rects[count][1], rects[count][2], rects[count][3]
                        old_center_x, old_center_y = px + pw / 2.0, py + ph / 2.0
                        x_ping, y_ping, w_suo, h_suo = box[1], box[2], box[3], box[4],
                        new__center_x = x_ping * pw + old_center_x
                        new__center_y = y_ping * ph + old_center_y
                        new_w = pw * np.exp(w_suo)
                        new_h = ph * np.exp(h_suo)
                        new_verts = [new__center_x, new__center_y, new_w, new_h]
                        results.append(new_verts)
                        results_label.append(pred[0])
            count += 1

        average_center_x, average_center_y, average_w,average_h = 0, 0, 0, 0
        #use average values to represent the final result
        for vert in results:
            average_center_x += vert[0]
            average_center_y += vert[1]
            average_w += vert[2]
            average_h += vert[3]
        average_center_x = average_center_x / len(results)
        average_center_y = average_center_y / len(results)
        average_w = average_w / len(results)
        average_h = average_h / len(results)
        average_result = [[average_center_x, average_center_y, average_w, average_h]]
        result_label = max(results_label, key=results_label.count)
        show_rect(self._img_path, results_old, ' ')
        show_rect(self._img_path, average_result, flower[result_label])
      

if __name__ == "__main__":
    Test()

测试结果如下:

在这里插入图片描述


本节参考以下资料:
https://github.com/cassiePython/RCNN/
https://github.com/bigbrother33/Deep-Learning

【本节完】


版权声明:
欢迎关注『youcans动手学模型』系列
转发请注明原文链接:
【youcans动手学模型】目标检测之 RCNN 模型
Copyright 2023 youcans, XUPT
Crated:2023-07-21


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

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

相关文章

《个人理财》——第六章 理财规划计算工具与方法

考点1: 货币时间价值概述 货币时间价值 也叫资金的时间价值 • 货币在无风险条件下, 经历一定时间投资和再投资发生的增值 • 同等数量货币或现金流的未来价值更低 • 不同时间单位的货币不具有可比性 产生的原因• 现有货币用于投资, 可获得…

IDEA+SpringBoot +ssm+ Mybatis+easyui+Mysql求职招聘管理系统网站

IDEASpringBoot ssm MybatiseasyuiMysql求职招聘管理系统网站 一、系统介绍1.环境配置 二、系统展示1. 登录2.注册3.首页4.公司5.关于我们6.我的简历7.我投递的简历8.修改密码9. 管理员登录10.我的信息11.用户信息12.职位类别13. 职位列表14. 公司列表15. 日志列表 三、部分代码…

听GPT 讲K8s源代码--pkg(八)

k8s项目中 pkg/kubelet/envvars,pkg/kubelet/events,pkg/kubelet/eviction,pkg/kubelet/images,pkg/kubelet/kubeletconfig这些目录都是 kubelet 组件的不同功能模块所在的代码目录。 pkg/kubelet/envvars 目录中包含了与容器运行…

深度学习入门教学——神经网络

深度学习就是训练神经网络。 1、什么是神经网络? 举个最简单的例子,以下是一个使用线性回归来预测房屋价格的函数。这样一个用于预测房屋价格的函数被称作是一单个神经元。大一点的神经网络,就是将这些单个神经元叠加起来。例如&#xff1a…

Java基础之stream流最新版,stream流的基本操作

您好,我是码农飞哥(wei158556),感谢您阅读本文,欢迎一键三连哦。 💪🏻 1. Python基础专栏,基础知识一网打尽,9.9元买不了吃亏,买不了上当。 Python从入门到精…

java 应用 cpu 过高故障排查

文章目录 一、前言二、测试代码 Test.java三、Linux 编译运行 Test.java 程序四、top 命令查看 cpu 使用情况五、查看进程下的线程详情 top -H -p 11748六、将线程 12240 的 pid 转为 16 进制 printf "0x%x\n" 12240七、jstack 查看进程的快照遗留 一、前言 前两天…

二十六章:Pyramid Vision Transformer ——金字塔视觉Transformer:一种无卷积的用于密集预测的多功能主干网络

0.摘要 虽然卷积神经网络(CNN)在计算机视觉领域取得了巨大成功,但本研究探讨了一种更简单、无卷积的骨干网络,适用于许多密集预测任务。与最近提出的专门用于图像分类的Vision Transformer(ViT)不同&#x…

无人机自主探索FUEL:代码阅读1--边界簇检测更新与视点生成

~/src/catkin_fuel_refactored/fuel_refactored/fuel_planner/bagbag中包含三个.sh文件,为rosbag指令,给出了录包指令以及有用话题信息 FIS 1、增量边界检测与聚类 路径:~/fuel_planner/active_perception/src/frontier_finder.cpp 主要函…

五、模型训练

目录 1. 线性模型1.1 Lasso 回归1.2 Ridge 回归 2. 树模型2.1 随机森林(Random Forest,RF)2.2 梯度提升树(GBDT)2.3 XGBoost2.4 LightGBM2.5 CatBoost2.6 模型深入对比 3. 神经网络3.1 多层感知机3.2 卷积神经网络3.3 …

Linux 下 nc 发送接收 udp、tcp数据

nc,全名叫 netcat,它可以用来完成很多的网络功能,譬如端口扫描、建立TCP/UDP连接,数据传输、网络调试等等,因此,它也常被称为网络工具的 瑞士军刀 。 一、只服务端使用nc 备注:这种方式只能发…

【Hive】Centos7安装单机版Hive

Hive依赖MySQL存储元数据信息,安装Hive前需要先安装MySQL 一、安装MySQL 下载mysql安装包 wget http://repo.mysql.com/mysql57-community-release-el7-10.noarch.rpm2. 如果不是root用户需要先切换到root用户,安装第1步下载的rpm包 yum -y install …

MYSQL练习一答案

练习1答案 构建数据库 数据库 数据表 answer开头表为对应题号答案形成的数据表 表结构 表数据 答案: 1、查询商品库存等于50的所有商品,显示商品编号,商 品名称,商品售价,商品库存。 SQL语句 select good_no,good…

数据结构07:查找[C++][B树Btree]

图源:文心一言 考研对于B树的要求重点在推理手算的部分,只参考王道论坛咸鱼老师的视频就可以了;若时间非常充裕的小伙伴,也可以往下滑了解一下代码~🥝🥝 备注: 这次的代码是从这里复制的&…

nodejs+vue+elementui汽车销售网站

前端技术:nodejsvueelementui,视图层其实质就是vue页面,通过编写vue页面从而展示在浏览器中,编写完成的vue页面要能够和控制器类进行交互,从而使得用户在点击网页进行操作时能够正常。 可以设置中间件来响应 HTTP 请求。 Express …

关于坏点问题的调试总结

1、问题背景: 前段时间调试一个项目,有发现在低照度场景下图上有很多明显的白点,如下图所示。以以往的调试经验来看这就是坏点,可以通过 ISP 中去坏点模块去将其抹掉,但这么多的明显坏点,通过去坏点模块去…

5.1.tensorRT基础(2)-正确导出onnx的介绍,使得onnx问题尽量少

目录 前言1. 正确导出ONNX总结 前言 杜老师推出的 tensorRT从零起步高性能部署 课程,之前有看过一遍,但是没有做笔记,很多东西也忘了。这次重新撸一遍,顺便记记笔记。 本次课程学习 tensorRT 基础-正确导出 onnx 的介绍&#xff0…

【网络安全】DVWA靶场实战BurpSuite内网渗透

BurpSuite 内网渗透 一、 攻击模式介绍1.1 Sniper(狙击手)1.2 Battering ram(攻城锤)1.3 Pitchfork(草叉)1.4 Cluster bomb(榴霰弹) 二、 DVWA靶场搭建2.1 下载DVWA工程2.2 添加网站…

19 QListWidget控件

Tips: 对于列表式数据可以使用QStringList进行左移一块输入。 代码: //listWidget使用 // QListWidgetItem * item new QListWidgetItem("锄禾日当午"); // QListWidgetItem * item2 new QListWidgetItem("汗滴禾下土"); // ui->…

vue前端打包优化

建议,使用pnpn代替原生的npm 具体操作如下: pnpm安装,如果是linux,需要把npm和pnpm设置为环境变量## 安装pnpm npm install -g pnpm5.15.0 --registryhttps://registry.npm.taobao.org ## 设置淘宝镜像pnpm config set registry…