two-stage目标检测算法

news2025/1/19 11:18:49

R-CNN

现在,将目光穿越回2012年,hinton刚刚提出alexnet的时代。

此时,该如何审视目标检测任务?

当时的目标检测采用的是滑动窗口+手动特征+分类器的思路。

该方法的弱点包括

  • 速度慢

  • 精度差

精度差的问题是由手工特征造成的,因此可以通过CNN解决

速度慢的问题是由滑动窗口造成的,结合图像金字塔,速度会非常的慢。

如何解决速度慢的问题?

区域选择算法

如果采用金字塔+滑动窗口,同时加上不同窗口比例,目标框可能会数百万计。

对每个目标框的区域都进行图像分类,会造成极大的计算压力。

然而,绝大部分的框都是背景,只有少部分的框是目标。

一种直观的解决思路就是,从图像中筛选出可能存在目标的区域,然后再对这些目标进行仔细辨认

这种思路也是符合人类视觉习惯,例如,人们首先会定位出人的位置,再辨识出是谁。

2014年提出的RCNN就是用到这种思路。

如何筛选出可能存在目标的区域?

从视觉上讲,我们要先找出物体,再判断物体类别。

那么什么是一个物体?就是表达同一个语义的像素区域。

例如,一个雪原场景中,一些黑色的色块,就是同一个物体。

这里就涉及到一个基本假设:表达同一个语义信息的像素,在数值上存在连续性或者相关性

在RCNN中,采用了一种基于传统方法的图像分割算法(Felzenszwalb and Huttenlocher algorithm),按照像素值将图像分割成小的子块,再进行合并后得到的图像分割结果。

关于图像分割算法的样例代码如下所示,具体原理细节在图像分割部分讲授。

In [11]:

# Felzenszwalb and Huttenlocher
import matplotlib.pyplot as plt
import numpy as np

from skimage.data import astronaut
from skimage.color import rgb2gray
from skimage.filters import sobel
from skimage.segmentation import felzenszwalb, slic, quickshift, watershed
from skimage.segmentation import mark_boundaries
from skimage.util import img_as_float

img = img_as_float(astronaut()[::2, ::2])

segments_fz = felzenszwalb(img, scale=100, sigma=0.5, min_size=50)

print(f"Felzenszwalb number of segments: {len(np.unique(segments_fz))}")

fig, ax = plt.subplots(1, 2, figsize=(10, 10), sharex=True, sharey=True)

ax[0].imshow(img)
ax[0].set_title("original")
ax[1].imshow(mark_boundaries(img, segments_fz))
ax[1].set_title("Felzenszwalbs's method")

for a in ax.ravel():
    a.set_axis_off()

plt.tight_layout()
plt.show()
Felzenszwalb number of segments: 194

再回顾一下我们的目标,希望生成多个包含物体的候选框。

那么如何通过分割结果得到候选框?

具体步骤如下:

  1. 计算所有邻域之间的相似性(像素相似性、纹理相似性、大小相似性和形状相似性)
  2. 两个最相似的区域被组合到一起
  3. 计算合并区域和相邻区域的相似度
  4. 重复2、3,直到整个图像变为一个区域

算法截图: 

具体解释:

  1. 先计算各个区域间的相关性
  2. 找出相关性最大对应的两个区域,进行合并。
  3. 合并后,将合并的区域加入集合R,并将原先两个区域的相关性删除,加入新区域的相关性
  4. 重复上述步骤2和3,直到全部的相关性从S中删除。
  5. 最后根据4得到的全部区域集合,得到对应区域的全部候选框。

以上步骤被称为selective search。

计算相似度

计算相似度有四种方法:

  • 颜色
  • 纹理
  • 大小
  • 形状

颜色相似度

如何度量颜色? 直方图

对每个通道量化成25个直方图,三个通道就有75维直方图

根据直方图的重叠区域来定义颜色的相似度

纹理相似度

定义纹理也采用直方图的方式进行。

纹理直方图如何定义?统计每个像素的特征方向。

定义出这些直方图之后,通过直方图的重叠区域定义纹理相似度。

大小相似度

大小相似度并不是对同样大小的区域合并,而是希望优先合并小的区域。

形状相似度

形状相似度也不是为了将相同形状的区域合并,而是衡量两个区域是否更加吻合。(像拼图一样,如果合并后的区域更加符合矩形框,则优先级更高)

综上所述,总体相似度为

最终,selective search算法生成了大量的候选框,从上至下挑选一千至两千个框,称为region proposal.

相比于传统的框来说,region proposal的方式效率极高,避免对每个像素进行遍历。

小结:selective search的步骤为

  1. 用分割算法获取若干个区域

  2. 计算两两区域之间的相似度,原则:给小的区域与吻合的区域赋予较大的相似度

  3. 挑选出相似度最大的区域,进行合并;

  4. 合并后的区域送入备选区域集合,并删除掉合并前的相似度

  5. 利用步骤2计算出新区域与邻居区域的相似度,加入相似度集合

  6. 重复3、4、5步骤,直到相似度集合中没有可以合并的值。

从候选区域集合中获取1-2千个区域,用于后续检测。

特征提取与分类

区域选择代替了滑动窗口,下一步就需要对候选区域进行特征提取。

考虑到选择的区域存在不同的尺度和比例,此处第一步就需要对齐所有区域。

step1. resize region: 将所有的区域resize成同样大小的尺寸(经过cnn后映射到fc的参数一样)

step2. extract feature with CNN:将所有的区域送入CNN中提取特征。

还记得什么是CNN提取的特征吗?

把softmax去掉后的feature map就是特征。

采用的模型为alexnet或者vgg16

那么如何训练这个CNN?

  • step1. 用imagenet训练分类网络

  • step2. 针对检测目标进行训练。

    • 数据集采用pascal voc,每张图像用selective search得到候选框,用候选框作为CNN的输入
    • 定义标签:当候选框与目标检测框的重叠度超过0.5,则认为是一个正样本;否则是一个负样本
    • 此处为多分类器分类,每个分类器是一个二分类,判断是不是这个目标

位置优化

图像分割获得的结果,并不一定准确。

直接将图像分割结果用作最后的检测结果,边界框可能存在较大的误差。

对此,RCNN将位置优化定义为一个线性回归问题

定义某类分类的正例结果,在原图上的位置为x,y,w,ℎ

而ground truth上的位置为 x′,y′,w′,ℎ′.

那么我们说这两个框的差距可以用两个操作完成:平移和缩放

对此,定义四个量如下

 将其定义一个优化问题如下

 本质上,对于确定了目标的框,需要通过上述求得的参数α∗进行位置优化

对位置进行进一步的精修

非极大值抑制

为了避免多个高度重叠的候选框,需要使用NMS来抑制那些与已有框的重叠度高于一定阈值的候选框。

 

NMS的原理

  1. 判断两两框之间是否重合,以及重合的IoU是多少;
  2. 当IoU大于一定阈值,保留较大的分的框,删除较小的分的框。

 慢速的nms

import cv2
import numpy as np

def nms(bounding_boxes, confidence_score, threshold):
    if len(bounding_boxes) == 0:
        return [], []
    bboxes = np.array(bounding_boxes)
    score = np.array(confidence_score)

    # 计算 n 个候选框的面积大小
    x1 = bboxes[:, 0]
    y1 = bboxes[:, 1]
    x2 = bboxes[:, 2]
    y2 = bboxes[:, 3]
    areas =(x2 - x1 + 1) * (y2 - y1 + 1)

    # 对置信度进行排序, 获取排序后的下标序号, argsort 默认从小到大排序
    order = np.argsort(score)

    picked_boxes = [] # 返回值
    picked_score = [] # 返回值
    while order.size > 0:
        # 将当前置信度最大的框加入返回值列表中
        index = order[-1]
        picked_boxes.append(bounding_boxes[index])
        picked_score.append(confidence_score[index])

        # 获取当前置信度最大的候选框与其他任意候选框的相交面积
        x11 = np.maximum(x1[index], x1[order[:-1]])
        y11 = np.maximum(y1[index], y1[order[:-1]])
        x22 = np.minimum(x2[index], x2[order[:-1]])
        y22 = np.minimum(y2[index], y2[order[:-1]])
        w = np.maximum(0.0, x22 - x11 + 1)
        h = np.maximum(0.0, y22 - y11 + 1)
        intersection = w * h

        # 利用相交的面积和两个框自身的面积计算框的交并比, 将交并比大于阈值的框删除
        ratio = intersection / (areas[index] + areas[order[:-1]] - intersection)
        left = np.where(ratio < threshold)
        order = order[left]

    return picked_boxes, picked_score

总结

RCNN是真正使用深度学习进行目标检测的开山之作,为后续的faster rcnn系列提供了巨人的肩膀。

总体示意图如下图所示

优势:

- rcnn打破了传统思路滑动窗口的模式,提供了更加快速的检测
- 大幅提升了传统方法的性能,在voc2007上从35%提升到了53%

劣势:

- 速度依然很慢。gpu上的速度大概每张图像13秒

rcnn的局限性

RCNN的首要问题在于:

* 目标产生了形变
* 目标框要一一识别


  • 目标框一一识别

2000个目标框,每个都需要调用CNN进行识别。这是算力上的严重浪费。(速度慢的原因之一)

如果能对整张图像进行特征提取,然后再对其对应的特征进一步的分类,就可以解决上述问题。

  • 目标产生形变

从selective search中产生的目标框,想要从其中获取特征,需要先把他resize成相同大小的图像。

这样就会造成较大的误差,严重降低了识别精度。

为什么要变成相同大小的内容?

因为CNN需要变成相同大小的内容。

为什么CNN需要输入相同大小的内容?

因为CNN的卷积层到fc层限定了feature map的尺寸。

问题:如何能够令cnn接收不同尺寸的输入与输出?

问题的关键就在于令卷积层能够对不同尺寸的图像,输出相同大小的feature map(通过SPP

即然无法改变参数,就只能改变非参数的层,即池化层adaptivemaxpooling

SPP Net

金字塔池化层

自适应窗口的池化层

根据输入的feature map大小,将feature map划分为固定数量的块。

每块采用最大池化,将不同尺寸的feature map池化为固定尺寸的池化。

金字塔池化

分别用不同的尺度进行池化,最终得到不同尺寸的feature map池化结果。

将不同尺寸的feature拉平后 concate起来,得到最终的结果。

具体参数

  1. 输入任意大小的,N1通道的feature map

  2. 第一尺度的池化,将feature map池化为4*4

  3. 第二尺度的池化,将feature map池化为2*2

  4. 第三尺度的池化,将feature map池化为1*1

上述特征按通道flatten,分别得到16*N1, 4*N1, 1*N1的特征,连接起来,就可以得到一个21*N1的feature map

统一提取特征

通过selective search得到的目标框,坐标可以映射到feature map中。

这些feature map经过空间金字塔池化的处理,得到相同大小的faeture map

这些feature map会被进一步的送入fc层进行特征提取,最终得到目标框的特征

SPP net的总体流程

  1. selective search找到若干候选框

  2. 整张图像进入cnn提取特征

  3. 根据候选框从feature map中提取对应的特征,送入SPP层

  4. SPP层的内容经过FC提取,得到特征,最终存入硬盘

  5. 硬盘中读取特征,进入SVM进行预测和训练;

  6. 硬盘中读取特征,进入回归中进行预测和训练。

训练过程

  1. 先训练ConvNet,在imagenet的基础上fine tuning(用提取到的特征微调fc)
  2. 完成了conv的训练后,将提取到的特征用于svm训练
  3. 训练回归(L2损失)

SPPNET的实验结果

  1. 精度略低于RCNN(降低了不到3个点):原因:训练的时候不能微调conv(效率低下)在训练fc时无法优化conv:因为SPP到fc特征是拼接得到的,因此无法求导回传梯度
  2. 速度远快于RCNN(38倍预测速度,3.4倍训练速度) 原因:大图像进行了一次conv,rcnn需要运行2000次

SPPNET存在什么问题?

SPPnet较好的解决了不同尺度的图像送入cnn的问题,但是在svm和回归的分类器,使得模型的训练非常的繁琐。

具体上,我们要先把图像提取的fc特征存储到硬盘上。

然后从硬盘读取出来(比从内存读慢得多),再进行分类和回归。

时间慢、占用磁盘高。

Fast RCNN--现代目标检测的雏形

fast rcnn提出了rcnn的三个不足:

  • 测试效率低

  • 多阶段训练模型

  • 训练计算量大

对此,fast rcnn做了以下三点改进:

  1. roi(region of interest感兴趣的区域) pooling(spp 的一种特例)

  2. 先对全图进行特征提取,然后从feature map中提取出对应区域(spp已经解决)

  3. 将分类和回归合并到了一起

fast rcnn如何训练?

对于一个分类cnn网络,需要做三件事情:

  1. 将最后一层pool换成roi pooling

  2. 将模型的fc分别输送给并行的两个内容:softmax分类和回归

  3. 将模型的输入改变为两个:图像和proposal region

这样就把一个imagenet训练的模型载入了fast rcnn中(conv)。

之后,用voc数据集对参数进行训练。

不同于sppnet,fast rcnn这里是使用了分层的思想进行训练。

sppnet是从一个batch中均匀的采样出若干个roi框,也就是说他的batch size中必须有足够多的图像才能进行

然而,fastrcnn中,是从一张图像中提取出若干个框来训练。

这样,sppnet中会占用更多的显存。

fast rcnn的损失函数

  • 第一项是:分类(softmax)[损失,u为ground truth,p是预测结果 −log⁡pu
  • 第二项是:回归损失,采用了smooth L1损失进行

关于smooth l1损失,是为了解决l2损失的不足(当x很大时,求导接近正无穷,会造成梯度爆炸)

当x>=1时,梯度=1,解决了梯度爆炸的问题

SVD优化算法

fc层的快速优化算法:通过svd奇异值分解。

已知fc层参数W可分解为:

1层fc==>2层fc(w1=∑V^T; w2=U)提高了速度

就可以分解成两个不同的全联接层。

fast-rcnn代码可看

Faster RCNN

从RCNN网络开始,用region proposal代替了滑动窗口式的遍历检测

之后的SPP Net,开启了统一提取特征并在feature map上的特征提取

而后,Fast RCNN则是将回归与分类结合起来,形成了多任务训练模型

下面该如何改进?

Motivation

虽然Fast RCNN很优雅,但是其存在一个源生性缺陷:selective search

selective search固然是代替滑动窗口来实现目标检测的里程碑式工作,但目前已经严重阻碍了目标检测的发展。

主要的阻碍分为两个方面:

  1. 速度慢:selective search步骤占据了fast RCNN中的大多数运算时间

  2. 精度差:无论如何,selective search是一个基于手工特征的方法,本身依然存在泛化性不足的问题(迷彩服)

这样一来,如何改进selective search,则变成了实现现代目标检测算法中的最关键的一个步骤。

为了改进selective search(手工特征),一个直接的想法就是利用神经网络

那么一个什么样的神经网络可以满足要求呢?

这样的神经网络又该如何训练呢?

基本思路:RPN网络

Region Proposal Network, 其目的是接受图像的输入,并输出可能存在目标的框。那么如何实现?

  1. 要找出粗略的目标的话,首先要对模型进行特征提取。如何做?

用imagenet模型参数作为初始参数,提取自然图像中的高纬特征。

将得到的高维特征作为输入,我们希望新的网络从中预测出潜在的框的位置。

  1. 如何找到潜在框的位置?

本质上就是针对特征层面的selective search。

这也是faster rcnn中最关键的内容。

目标区域推荐

假设我们已经训练好了一个网络,这个网络能对输入的大尺寸的feature map中得到若干个不同尺寸的框。

那么这个流程,应当可以借鉴传统的目标检测方法,即滑动窗口的方式。

用一个固定大小的窗口对feature map中的元素进行遍历,每个窗口对应了原图像中的一个区域。

把这个窗口截取的feature map进行后续的分类和回归,来判断这个窗口是否存在目标,以及应该框在哪里。

注意 这里的目标依然是固定尺寸的。针对目标可能存在比例、尺度的不同,这里对每个feature进行不同尺寸窗口的截取。

具体上,窗口中存在3种比例3种尺度(128,256,512)。分别是

一张featuremap中可以提取多个不同尺度的proposal

对每个proposal进行预测,(判断这里的框是/否是目标,而不是是哪一类),即可得到正例样本。

同时不要忘记进行nms,最终可以输出推荐出来的,可能存在区域的样本。

问题:如何训练这样的网络?

  • imagenet的模型载入base net
  • 输入一张图像,得到feature map
  • 根据输入图像的目标框位置,得到若干正样本(包含目标)以及对应数量的负样本(不包含目标的框)
选择正负样本应当遵循一下原则:

1. Anchor boxes与ground truth框的IoU大于0.7的每个anchor box标记为正样本。因为IoU较大表示anchor box与ground truth框有较好的匹配。
2. Anchor boxes与所有的ground truth框的IoU都小于0.3的每个anchor box标记为负样本。因为IoU较小表明anchor box可能是背景或误检。
3. Anchor boxes与某个ground truth框的IoU在0.3到0.7之间的不参与训练。因为这些anchor box难以清晰判断是正样本还是负样本。
4. 每个ground truth框最多只能匹配一个anchor box。如果多个anchor box与同一ground truth框IoU都大于0.7,则选择IoU最大的那一个作为正样本,其余不参与训练。
5. 每个ground truth框至少要匹配一个anchor box作为正样本。如果没有任何anchor box可以匹配,则选择与该ground truth框IoU最接近0.7的anchor box作为正样本。(想一下为什么?当目标物体大于最大的候选框时会出现这种情况)
6. 对于未匹配到任何ground truth框的anchor boxes,标记为负样本。
7. 保证正负样本数量比例为1:1或1:3,过度不平衡会影响模型的收敛。
  • 最后,将选择到的正负样本送入网络进行训练,让模型充分认识到哪些区域可能会存在特征

(负样本的选择尽量与目标有小的重叠,这样网络可以学习到“较难”的特征)

  • 根据联合损失(分类+回归)得到目标框的位置

根据以上内容,我们可以大致画出rpn模型的草图如下

那么根据这个网络,我们就可以彻底甩掉selective search,用上述网络实现目标区域的粗筛选。

(为什么是粗筛选?因为不知道具体属于什么类别,只知道是否是目标

Faster RCNN的进一步优化

在得到RPN网络后,一个直接的感受就是

  • 图像先进入RPN进行区域推荐(RPN将坐标(anchor的中心点)输入给roi)
  • 图像进入fast rcnn进行训练,只不过selective search的部分,由rpn得到

显然,这样做是一种极大的浪费,因为图像会被提取两次basenet,极大地降低了效率。

为何不将这两个网络进行合并

也就是说他们的basenet应当公用。

这样的话,就可以一次提取特征,用于rpn和后续检测。

最终,faster rcnn的框图如下图所示

训练

那么这样的一个网络该如何训练?

  1. imagenet的模型载入basenet,然后训练RPN模块(basenet部分不更新)

  2. 带入RPN模块,三部分进行统一训练(四个loss:RPN坐标和位置,svm和Bbox回归)

损失函数

关于损失函数部分,rpn会得到cls_rpn和reg_rpn;rcnn那部分会得到cls_rcnn和reg_rcnn,

将上述两部分特征加起来,就是最终的损失。

 

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

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

相关文章

【VS安装记录】Visual Studio 2022安装教程(超详细)

大家好&#xff0c;我是雷工&#xff01; 由于更换了电脑&#xff0c;很多软件需要重新安装&#xff0c;为了方便学习C#&#xff0c;今天有时间安装下Visual Studio 2022&#xff0c;顺便记录安装过程。 1、从官网下载并解压软件压缩包&#xff0c;然后打开文件夹。 2、双击…

切比雪夫不等式,大数定律及极限定理。

一.切比雪夫不等式 1.定理 若随机变量X的期望EX和方差DX存在,则对任意ε > 0,有   P{ |X - EX| > ε } < DX/ε2 或 P{ |X - EX| < ε } > 1 - DX/ε2 2.解析定理 ①该定理对 X 服从什么分布不做要求&#xff0c;仅EX DX存在即可。 ②“| |” 由于X某次…

linux kernel pwn 基础知识

基础知识 内核概述 内核架构 通常来说我们可以把内核架构分为两种&#xff1a;宏内核和微内核&#xff0c;现在还有一种内核是混合了宏内核与微内核的特性&#xff0c;称为混合内核。 宏内核&#xff08;Monolithic kernel&#xff09;&#xff0c;也译为集成式内核、单体…

网络原理——基础概念(端口号、分层、封装和复用)、各层协议(TCP/IP协议)(详细图解)

目录 一、基础概念 1、 IP地址 &#xff08;1&#xff09;点分十进制 2、端口号 3、协议 &#xff08;1&#xff09;协议的 组成部分 &#xff08;2&#xff09; 协议的 作用 4、五元组 5、协议分层 &#xff08;1&#xff09;分层的 好处 &#xff08;2&#xff0…

Overleaf中Latex问题——控制文本分两列显示(分栏布局)

文章目录 需求描述相关介绍实现代码实现效果参考和总结 需求描述 要写论文&#xff0c;需要分两列进行显示文本。但是默认都是单列展示&#xff0c;并且自动换行。 需要实现一下的效果 相关介绍 在$LaTeX 中&#xff0c;你可以使用 中&#xff0c;你可以使用 中&#xff0c…

Tokenview上线BRC-20浏览器,支持Ordinals API数据服务

5月20日&#xff0c;Tokenview团队宣布正式推出BRC-20代币浏览器&#xff0c;同时支持BTC Ordinals API数据服务。作为通用多链区块链浏览器&#xff0c;Tokenview以最快的速度推出了BRC-20浏览器&#xff0c;Ordinals API旨在为所有面向比特币的普通用户和开发者提供数据支持&…

追寻篮球梦想 点燃希望之光 2023年海彼特全国幼儿篮球联赛·总决赛圆满落幕

5月21日&#xff0c;由北京海彼特教育科技院主办的“2023年海彼特全国幼儿篮球联赛总决赛”。在河北体育馆隆重举行&#xff0c;精彩的比赛效果使体育馆顿时成为幼儿篮球界最高端、大气的舞台。 本次盛会联合举办方有&#xff1a; 河北体育馆 亚洲少儿体育协会 北京海彼特文…

组件123456789

前言&#xff1a;相信看到这篇文章的小伙伴都或多或少有一些编程基础&#xff0c;懂得一些linux的基本命令了吧&#xff0c;本篇文章将带领大家服务器如何部署一个使用django框架开发的一个网站进行云服务器端的部署。 文章使用到的的工具 Python&#xff1a;一种编程语言&…

G企孵化-千趣生活项目,10年互联网经验专业策划商业模式

G企孵化-千趣生活项目&#xff0c;10年互联网经验专业策划商业模式 背景&#xff1a;现在许许多多的项目&#xff0c;首先对外呼吁的口号就是“上市”但真正能做到上市的企业&#xff0c;确实没有几个&#xff0c;10年互联网经验的微三云胡佳东&#xff0c;给大家详细聊聊&…

【卡尔曼滤波的学习,以及一些理解】

卡尔曼滤波的一些理解 优秀的博客推荐直观理解卡尔曼滤波核心算法举个例子 最近两个多月在实习&#xff0c;做的是GPS定位相关的一些工作&#xff0c;同时也简单做了一下组合导航。卡尔曼滤波是组合不同传感器比较核心的算法&#xff0c;应用也比较广泛&#xff0c;也有很多文章…

电子数据保全及数据恢复

目录 一.创建虚拟磁盘 系统操作 1.创建虚拟磁盘文件 2.完成低级格式化——分区——高级格式化 3.虚拟磁盘创建完成 用winhex做 2. 镜像&#xff1a; 克隆&#xff1a; 计算分区的hash值&#xff1a; 二.FAT32文件系统 1.认识FAT32文件系统 三.NTFS文件系统 认识NTFS文…

数字信号处理5

好长时间没有更新了&#xff0c;一是这段时间事情比较多&#xff0c;另外一个&#xff0c;我觉得抄书其实意义不大&#xff0c;不如先看书&#xff0c;一个章节看完之后&#xff0c;再写&#xff0c;那样子的话&#xff0c;会效果更好一些&#xff0c;所以我就花了一段时间去把…

chatgpt赋能Python-python_chia

简介&#xff1a;什么是Python Chia&#xff1f; Python Chia是一种加密货币&#xff0c;它的挖矿过程使用Python编程语言。Python Chia是开源的&#xff0c;任何人都可以参与挖矿。 Chia使用绿色挖矿的方式&#xff0c;这意味着Chia的挖矿过程对环境没有任何负面影响。此外&…

typeScript开发

typeScript开发 1.TypeScript简介2.TypeScript 安装3.TypeScript 基础语法3.TypeScript 基础类型4.TypeScript 变量声明5.TypeScript 运算符6.TypeScript 条件语句7.TypeScript 循环8.TypeScript 函数9.TypeScript Number10.TypeScript String&#xff08;字符串&#xff09;11…

使用github CICD 简单部署vue项目

1.首先先创建一个github访问地址&#xff0c;关于Github Pages的域名访问地址&#xff0c;在github上新建一个以域名为名称的仓库即可&#xff0c;一般都是githubname.github.io 2.首先创建vue项目&#xff0c;这里我就使用自己写的前端项目脚手架来创建vue项目 这里顺便把图标…

立创梁山派学习笔记——GPIO输入检测

按键检测 前言按键的硬件电路BOOT选择复位按键唤醒按键GPIO输入框图软件配置寄存器简介1.端口控制寄存器&#xff08;GPIOx_CTL, xA..I&#xff09;2.端口上拉/下拉寄存器&#xff08;GPIOx_PUD, xA..I&#xff09;3.端口输入状态寄存器&#xff08;GPIOx_ISTAT, xA..I&#xf…

cs109-energy+哈佛大学能源探索项目 Part-2.2(Data Wrangling)

博主前期相关的博客见下&#xff1a; cs109-energy哈佛大学能源探索项目 Part-1&#xff08;项目背景&#xff09; cs109-energy哈佛大学能源探索项目 Part-2.1&#xff08;Data Wrangling&#xff09; 这次是将数据整理的部分讲完。 Data Wrangling 数据整理 Weather data 天…

chatgpt赋能Python-python_changeint

Python中changeint函数介绍&#xff1a;将浮点数转换为整数 Python是一种高级编程语言&#xff0c;众所周知&#xff0c;它非常强大且易于学习。在Python中&#xff0c;有一个很有用的函数&#xff0c;名为changeint&#xff0c;它可以将一个浮点数转换为整数。在本文中&#…

进程间通信—进程池设计

进程池设计 文章目录 进程池设计代码目的头文件 对子进程操作建立子进程对象并把子进程对象放进数组里建立子进程需要执行的任务表创建子进程和父进程通信的管道&#xff0c;并且让子进程阻塞读取对父进程操作回收子进程整体代码子进程具有读端未关闭的bug 代码目的 创建一个父…

【libdatachannel】1 :cmake+vs2022 构建

libdatachannel libdatachannel 是基于c++17实现的cmake 链接openssl 可以参考【libcurl 】win32 构建 Release版本 修改cmakelist 链接openssl1.1.*构建 OpenSSL 找不到 Selecting Windows SDK version 10.0.22000.0 to target Windows 10.0.22621. The CXX compiler identifi…