当前位置: 首页 > news >正文

使用 TensorFlow SSD 网络进行对象检测

使用 TensorFlow SSD 网络进行对象检测

目录

  • 描述
  • 这个示例是如何工作的?
    • 处理输入图
    • 准备数据
    • sampleUffSSD 插件
    • 验证输出
    • TensorRT API 层和操作
  • 先决条件
  • 运行示例
    • 示例 --help 选项
  • 附加资源
  • 许可证
  • 更改日志
  • 已知问题

描述

该示例 sampleUffSSD 预处理 TensorFlow SSD 网络,使用 TensorRT 进行 SSD 网络的推理,利用 TensorRT 插件加速推理。

该示例基于 SSD:单次多盒检测器 论文。SSD 网络在网络的单次前向传播中执行对象检测和定位任务。

本示例中使用的 SSD 网络基于 TensorFlow 实现的 SSD 网络,与原始论文有所不同,它具有 inception_v2 骨干网络。有关实际模型的更多信息,请下载 ssd_inception_v2_coco。TensorFlow SSD 网络是使用 MSCOCO 数据集 对 InceptionV2 架构进行训练的,该数据集包括 91 个类别(包括背景类)。网络的配置细节可以在此处找到。

这个示例是如何工作的?

SSD 网络通过网络的单次前向传播执行对象检测和定位任务。TensorFlow SSD 网络是使用 MSCOCO 数据集在 InceptionV2 架构上训练的。

该示例使用 TensorRT 插件来运行 SSD 网络。为了使用这些插件,需要预处理 TensorFlow 图,并使用 GraphSurgeon 实用程序进行此操作。

该网络的主要组件包括图像预处理器、特征提取器、盒子预测器、网格锚点生成器和后处理器。

图像预处理器
图像预处理图的步骤负责调整图像的大小。图像被调整为 300x300x3 大小的张量。该步骤还执行图像的归一化,使得所有像素值都在范围 [-1, 1] 内。

特征提取器
图的特征提取器部分在经过预处理的图像上运行 InceptionV2 网络。生成的特征图被用于锚点生成步骤,用于为每个特征图生成默认的边界框。

在此网络中,用于锚点生成的特征图的大小为 [(19x19), (10x10), (5x5), (3x3), (2x2), (1x1)]。

盒子预测器
盒子预测器步骤接受高级别特征图作为输入,并为每个特征图的每个编码盒子生成一个盒子编码(x-y 坐标)列表以及每个编码盒子的类别分数列表。然后将这些信息传递给后处理器。

网格锚点生成器
此步骤的目标是为每个特征图单元格生成一组默认边界框(根据配置中提到的比例和长宽比)。这实现为 TensorRT 中的一个名为 gridAnchorGenerator 插件的层。注册的插件名称是 GridAnchor_TRT

后处理器
后处理器步骤执行生成网络输出的最后步骤。所有特征图的边界框数据和置信度分数都将与预先生成的默认边界框(在 GridAnchorGenerator 命名空间中生成)一起输入到此步骤中。然后执行 NMS(非最大抑制),基于置信度阈值和 IoU(交并比)重叠来删掉大部分边界框,仅保留每类的前 N 个边界框。这实现为 TensorRT 中的名为 NMS 的插件层。注册的插件名称是 NMS_TRT

注意: 本示例还实现了另一个名为 FlattenConcat 的插件,用于将输入扁平化然后连接结果。在输入传递给后处理器之前,会将位置和置信度数据应用于这个插件,因为 NMS 插件需要数据采用这种格式。

关于插件如何实现的详细信息,请参见 tensorrt/samples/sampleUffSSD 目录中的 sampleUffSSD.cpp 文件中的 FlattenConcat 插件和 FlattenConcatPluginCreator 的实现。

具体来说,此示例执行以下步骤:

  • 处理输入图
  • 准备数据
  • sampleUffSSD 插件
  • 验证输出

处理输入图

TensorFlow SSD 图具有一些目前在 TensorRT 中不受支持的操作。通过对图进行预处理,我们可以将图中的多个操作合并为单个自定义操作,这些操作可以在 TensorRT 中实现为插件层。目前,预处理器提供了将图中的所有节点(在删除断言后没有输出的节点)拼接成单个自定义节点的能力。

要使用预处理器,应该使用 convert-to-uff 实用程序并带有配置文件的 -p 标志来调用它。配置脚本还应包含将嵌入到生成的 .uff 文件中的所有自定义插件的属性。目前用于 SSD 的示例脚本位于 /usr/src/tensorrt/samples/sampleUffSSD/config.py

使用图的预处理器,我们能够删除图中的 Preprocessor 命名空间,将 GridAnchorGenerator 命名空间拼接在一起以创建 GridAnchorGenerator 插件,将 postprocessor 命名空间拼接在一起以获得 NMS 插件,并将 BoxPredictor 中的 concat 操作标记为 FlattenConcat 插件。

TensorFlow 图中有一些操作,如 AssertIdentity,在推理时可以移除。Assert 等操作已被移除,剩下的节点(在删除断言后没有输出的节点)将被递归地删除。

Identity 操作将被删除,并且输入将被转发到所有连接的输出。有关图预处理器的附加文档,可以在TensorRT API中找到。

准备数据

生成的网络具有名为 Input 的输入节点,输出节点的名称由 UFF 转换器命名为 MarkOutput_0

parser->registerInput("Input", DimsCHW(3, 300, 300), UffInputOrder::kNCHW);
parser->registerOutput("MarkOutput_0");

本示例中 SSD 网络的输入是 3 通道 300x300 图像。在示例中,我们对图像进行归一化,使像素值位于范围 [-1,1]。

由于 TensorRT 不依赖于任何计算机视觉库,图像以每个像素的二进制 RGB 值表示。格式是可移植图像映射(Portable PixMap,PPM),这是一种 netpbm 颜色图像格式。在此格式中,每个像素的 RGB 值由整数字节(0-255)表示,并按像素存储在一起。

有一个名为 readPPMFile 的简单 PPM 读取函数。

sampleUffSSD 插件

有关如何创建 TensorRT 插件的详细信息,请参见使用自定义层扩展 TensorRT。

用于 convert-to-uff 命令的 config.py 定义应通过修改 op 字段将自定义层映射到 TensorRT 中的插件名称。插件参数的名称也应与 TensorRT 插件所期望的名称和类型完全匹配。例如,对于 GridAnchor 插件,config.py 应该如下所示:

PriorBox = gs.create_plugin_node(name="GridAnchor",
op="GridAnchor_TRT",
numLayers=6,
minSize=0.2,
maxSize=0.95,
aspectRatios=[1.0, 2.0, 0.5, 3.0, 0.33],
variance=[0.1,0.1,0.2,0.2],
featureMapShapes=[19, 10, 5, 3, 2, 1])

这里,GridAnchor_TRT 与已注册的插件名称匹配,参数的名称和类型与插件所期望的名称相同。

如果 config.py 定义如上,NvUffParser 将能够解析网络并使用正确的参数调用适当的插件。

以下是TensorRT中为SSD实现的一些插件层的详细信息。

GridAnchorGeneration 插件
这个插件层实现了TensorFlow SSD网络中的网格锚点生成步骤。对于每个特征图,我们计算每个网格单元的边界框。在这个网络中,有6个特征图,每个网格单元的边界框数量如下:

  • [19x19] 特征图:3个边界框(19x19x3x4(坐标/边界框))
  • [10x10] 特征图:6个边界框(10x10x6x4)
  • [5x5] 特征图:6个边界框(5x5x6x4)
  • [3x3] 特征图:6个边界框(3x3x6x4)
  • [2x2] 特征图:6个边界框(2x2x6x4)
  • [1x1] 特征图:6个边界框(1x1x6x4)

NMS 插件
NMS 插件生成基于BoxPredictor生成的位置和置信度预测的检测输出。此层有三个输入张量,对应于位置数据(locData)、置信度数据(confData)和先前框数据(priorData)。

检测输出插件的输入必须被扁平化并连接在所有特征图上。我们使用样本中实现的FlattenConcat插件来实现这一点。BoxPredictor生成的位置数据的尺寸如下:

19x19x12 -> 重塑 -> 1083x4 -> 扁平化 -> 4332x1
10x10x24 -> 重塑 -> 600x4 -> 扁平化 -> 2400x1

等等,对于其余特征图也是如此。

连接后,locData 输入的维度约为7668x1。

BoxPredictor生成的置信度数据的尺寸如下:

19x19x273 -> 重塑 -> 1083x91 -> 扁平化 -> 98553x1
10x10x546 -> 重塑 -> 600x91 -> 扁平化 -> 54600x1

等等,对于其余特征图也是如此。

连接后,confData 输入的维度为174447x1。

Grid Anchor Generator 插件生成的先前数据有6个输出,它们的维度如下:

输出 1 对应于19x19特征图,维度为2x4332x1
输出 2 对应于10x10特征图,维度为2x2400x1

等等,对于其他特征图也是如此。

注意: 输出中有两个通道,因为一个通道用于存储每个坐标的方差,这在NMS步骤中使用。连接后,priorData 输入的维度约为2x7668x1。

struct DetectionOutputParameters
{
bool shareLocation, varianceEncodedInTarget;
int backgroundLabelId, numClasses, topK, keepTopK;
float confidenceThreshold, nmsThreshold;
CodeTypeSSD codeType;
int inputOrder[3];
bool confSigmoid;
bool isNormalized;
};

shareLocationvarianceEncodedInTarget 用于Caffe SSD网络实现,所以对于TensorFlow网络,它们应该分别设置为 truefalseconfSigmoidisNormalized 参数对于TensorFlow实现是必要的。如果将 confSigmoid 设置为 true,它将计算所有置信度得分的sigmoid值。isNormalized 标志指定数据是否被规范化,对于TensorFlow图,它被设置为 true

验证输出

在创建生成器之后(参见在C++中构建引擎)并序列化引擎之后(参见在C++中序列化模型),我们可以执行推理。关于反序列化和运行推理的步骤在在C++中执行推理中进行了概述。

SSD网络的输出是人类可解释的。最后的NMS等后处理工作在NMS插件中完成。结果被组织为元组,每个元组有7个元素,分别是图像ID,对象标签,置信度分数,边界框左下角的(x,y)坐标,以及边界框的右上角的(x,y)坐标。可以使用writePPMFileWithBBox函数在输出PPM图像上绘制这些信息。visualizeThreshold参数可用于控制图像中对象的可视化。目前它被设置为0.5,所以输出将显示所有置信度为50%及以上的对象。

TensorRT API层和操作

在这个示例中,使用了以下层。有关这些层的更多信息,请参阅TensorRT开发者指南:层文档。

激活层
激活层实现了逐元素激活函数。具体而言,本示例使用了类型为kRELU的激活层。

连接层
连接层沿着通道维度连接多个非通道大小相同的张量。

卷积层
卷积层计算带有或不带有偏差的2D(通道、高度和宽度)卷积。

填充层
填充层在最内部的两个维度上实现了零填充。

插件层
插件层是用户定义的,提供了扩展TensorRT功能的能力。有关更多详细信息,请参阅通过自定义层扩展TensorRT。

池化层
池化层在通道内进行池化。支持的池化类型有maximumaveragemaximum-average blend

尺度层
尺度层实现了每个张量、每个通道或每个元素的仿射变换和/或常数值的幂运算。

Shuffle层
Shuffle层为张量实现了重塑和转置运算符。

先决条件

  1. 安装 UFF 工具包和图形外科医生;根据您的 TensorRT 安装方法,选择您所使用的方法以安装工具包和图形外科医生,可以参考 TensorRT 安装指南:安装 TensorRT 获取详细说明。

  2. 下载 ssd_inception_v2_coco TensorFlow 训练模型。

  3. 使用 UFF 转换器对 TensorFlow 模型进行预处理。

    1. 从之前步骤下载的目录中将 TensorFlow 协议缓冲文件(frozen_inference_graph.pb)复制到工作目录中(例如 /usr/src/tensorrt/samples/sampleUffSSD/)。

    2. 运行以下命令进行转换。

    convert-to-uff frozen_inference_graph.pb -O NMS -p config.py
    
     这将保存转换后的 `.uff` 文件到与输入相同的目录,并命名为 `frozen_inference_graph.pb.uff`。`config.py` 脚本指定了 SSD TensorFlow 图所需的预处理操作。`config.py` 脚本中使用的插件节点和插件参数应与 TensorRT 中的注册插件匹配。
    
    1. 将转换后的 .uff 文件复制到数据目录,并将其重命名为 sample_ssd_relu6.uff <TensorRT 安装目录>/data/ssd/sample_ssd_relu6.uff
  4. 该示例还需要一个包含用于训练模型的所有标签的 labels.txt 文件。该网络的标签文件是 <TensorRT 安装目录>/data/ssd/ssd_coco_labels.txt

运行示例

  1. <TensorRT 根目录>/samples/sampleUffSSD 目录中运行 make 来编译该示例。该二进制文件将被创建在 <TensorRT 根目录>/bin 目录中。

    cd <TensorRT 根目录>/samples/sampleUffSSD
    make
    

    其中 <TensorRT 根目录> 是您安装 TensorRT 的位置。

  2. 运行示例以执行对象检测和定位。

    要在 FP32 模式下运行示例:

    ./sample_uff_ssd
    

    要在 INT8 模式下运行示例:

    ./sample_uff_ssd --int8
    

    注意: 要在 INT8 模式下运行网络,请参考 BatchStreamPPM.h,了解如何执行校准。目前,我们需要一个名为 list.txt 的文件,其中列出了位于 <TensorRT 安装目录>/data/ssd/ 文件夹中用于校准的所有 PPM 图像。用于校准的 PPM 图像也可以位于同一文件夹中。

  3. 验证示例是否成功运行。如果示例成功运行,您应该会看到类似以下的输出:

    &&&& RUNNING TensorRT.sample_uff_ssd # ./build/x86_64-linux/sample_uff_ssd
    [I] ../data/samples/ssd/sample_ssd_relu6.uff
    [I] 开始解析模型...
    [I] 完成解析模型...
    [I] 开始构建引擎...
    I] 批处理数量 1
    [I] 数据大小 270000
    [I] *** 反序列化
    [I] 推断所用时间为 4.24733 毫秒。
    [I] 保留数量 100
    [I] 在图像 0(../../data/samples/ssd/dog.ppm)中检测到狗,置信度为 89.001,坐标为 (81.7568, 23.1155),(295.041, 298.62)。
    [I] 结果保存在 dog-0.890010.ppm 中。
    [I] 在图像 0(../../data/samples/ssd/dog.ppm)中检测到狗,置信度为 88.0681,坐标为 (1.39267, 0),(118.431, 237.262)。
    [I] 结果保存在 dog-0.880681.ppm 中。
    &&&& PASSED TensorRT.sample_uff_ssd # ./build/x86_64-linux/sample_uff_ssd
    

    这个输出表明示例成功运行;“PASSED”。

示例 --help 选项

要查看可用选项的完整列表及其说明,请使用 -h--help 命令行选项。

附加资源

以下资源提供了有关 TensorFlow SSD 网络结构的更深入理解:

模型

  • TensorFlow 检测模型库

网络

  • ssd_inception_v2_coco_2017_11_17

数据集

  • MSCOCO 数据集

文档

  • NVIDIA TensorRT 示例简介
  • 使用 C++ API 使用 TensorRT
  • NVIDIA TensorRT 文档库

许可协议

有关使用、复制和分发的条款和条件,请参阅TensorRT 软件许可协议文档。

更新日志

2019年3月
重新创建、更新和审阅此 README.md 文件。

已知问题

  • 在 INT8 模式下运行网络时,可能会存在一些精度损失,导致某些对象无法被检测到。一般观察是,>500 张图像是用于校准的良好数量。
  • 在 Windows 上,Python 脚本 convert-to-uff 不可用。您可以在 Linux 机器上生成所需的 .uff 文件,然后复制到 Windows 上以运行此示例。

相关文章:

使用 TensorFlow SSD 网络进行对象检测

使用 TensorFlow SSD 网络进行对象检测 目录 描述这个示例是如何工作的&#xff1f; 处理输入图准备数据sampleUffSSD 插件验证输出TensorRT API 层和操作 先决条件运行示例 示例 --help 选项 附加资源许可证更改日志已知问题 描述 该示例 sampleUffSSD 预处理 TensorFlow …...

(2)STM32单片机上位机

使用VX小程序开发上位机&#xff0c; 样式如何创建&#xff1f; 在你所在页面 开辟空间 使用 view 在view 中 输入class 就是样式&#xff0c;在编辑样式的时候&#xff0c;如何寻找哪一块的样式 就是通过这个class寻找的 按钮使用switch...

从InnoDB索引的数据结构,去理解索引

从InnoDB索引的数据结构&#xff0c;去理解索引 1、InnoDB 中的 BTree1.1、BTree 的组成1.2、BTree中的数据页 2、聚簇索引2.1、聚簇索引的特点2.2、聚簇索引的结构示例2.3、聚簇索引的优缺点 3、非聚簇索引3.1、非聚簇索引结构示例3.2、关于回表3.3、聚簇索引和非聚簇索引的区…...

Nacos:动态服务发现与配置管理的终极解决方案

今天我想和大家分享一下Nacos&#xff0c;这是一个由阿里巴巴开源的动态服务发现、配置和服务管理平台。我将详细介绍Nacos的主要特性&#xff0c;并通过实例来演示如何使用它。同时&#xff0c;我还会指出Nacos的优点&#xff0c;希望这篇文章能够帮助大家更好地理解和使用Nac…...

易思无人值守智能物流系统Sys_ReportFile文件上传漏洞复现

文章目录 易思无人值守智能物流系统Sys_ReportFile文件上传漏洞复现0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06 修复建议 易思无人值守智能物流系统Sys_ReportFile文件上传漏洞复现 0x01 前言 免责声明&#xff1a;请…...

java Map List转化,通过Map保存数据,通过List排序。取前三名

java Map List转化&#xff0c;通过Map保存数据&#xff0c;通过List排序。取前三名 package yo;import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map;public class a {public static void …...

LEECODE 1480一维数组的动态和

class Solution { public:vector<int> runningSum(vector<int>& nums) {vector<int> runningSum;int sum 0;int len nums.size();for(int i 0; i < len; i){sum sum nums[i];runningSum.push_back(sum);}return runningSum;} };...

python文档链接

python与并行计算...

HTTP调试代理工具/Proxyman

Proxyman专为开发人员和网络爱好者设计&#xff0c;它允许用户拦截、查看和修改所有传入和传出的网络请求&#xff0c;并提供详细的分析和调试功能。 Proxyman支持HTTP、HTTPS和WebSocket协议&#xff0c;因此&#xff0c;可以轻松捕获和查看这些协议下的网络流量。用户可以使…...

搭建Qt5.7.1+kylinV10开发环境、运行环境

1.下载Qt源码 Index of / 2.编译Qt 解压缩qt-everywhere-opensource-src-5.7.1.tar.gz 进入到qt-everywhere-opensource-src-5.7.1/qtbase/mkspecs这个目录下&#xff0c; 2.1找到以下目录 复制他&#xff0c;然后改名linux-x86-arrch64&#xff0c;博主这里名字取的有些问…...

Ceph:关于Ceph 中创建和管理自定义 CRUSH Map

写在前面 准备考试&#xff0c;整理 Ceph 相关笔记博文内容涉及&#xff0c;管理和定制CRUSH Map以及管理OSD Map理解不足小伙伴帮忙指正 对每个人而言&#xff0c;真正的职责只有一个&#xff1a;找到自我。然后在心中坚守其一生&#xff0c;全心全意&#xff0c;永不停息。所…...

【Linux】开发工具——vim多模式编辑器的入土设置sudoers白名单

个人主页点击直达&#xff1a;小白不是程序媛 Linux系列专栏&#xff1a;Linux被操作记 目录 前言&#xff1a; 基本概念 vim基本操作 [正常模式]切换至[插入模式] [插入模式]切换至[正常模式] [正常模式]切换至[末行模式] 三种模式的切换关系图 vim命令模式命令集 进…...

Linux基础环境开发工具的使用(yum,vim,gcc,g++)

Linux基础环境开发工具的使用[yum,vim,gcc,g] 一.yum1.yum的快速入门1.yum安装软件2.yum卸载软件 2.yum的生态环境1.操作系统的分化2.四个问题1.服务器是谁提供的呢?2.服务器上的软件是谁提供的呢?3.为什么要提供呢?4.yum是如何得知目标服务器的地址和下载链接呢?5.软件源 …...

加速软件开发和交付的革命性方法-DevOps

“ 随着信息技术的快速发展&#xff0c;现代软件开发和交付已经经历了巨大的变革。DevOps&#xff08;Development和Operations的结合&#xff09;已经成为这一变革的关键推动力&#xff0c;让开发团队和运维团队之间的界限变得模糊&#xff0c;以加速软件的开发、测试和部署过…...

Ha-NeRF源码解读 train_mask_grid_sample

目录 背景&#xff1a; &#xff08;1&#xff09;Ha_NeRF论文解读 &#xff08;2&#xff09;Ha_NeRF源码复现 &#xff08;3&#xff09;train_mask_grid_sample.py 运行 train_mask_grid_sample.py解读 1 NeRFSystem 模块 2 forward()详解 3 模型训练tranining_st…...

大数据毕业设计选题推荐-系统运行情况监控系统-Hadoop-Spark-Hive

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…...

SpringBoot----自定义Start(自定义依赖)

一&#xff0c;为什么要定义Start 向阿里云OSS如果我们要引入的话很麻烦&#xff0c;所以我们可以自定义一些组件&#xff0c; 然后我们只需要在pom文件中引入对应的坐标就可以 二&#xff0c;怎么定义&#xff08;以阿里云OSS为例&#xff09; 1&#xff0c; 定义两个组件模块…...

通过条件竞争实现内核提权

条件竞争漏洞&#xff08;Race Condition Vulnerability&#xff09;是一种在多线程或多进程并发执行时可能导致不正确行为或数据损坏的安全问题。这种漏洞通常发生在多个线程或进程试图访问和修改共享资源&#xff08;如内存、文件、网络连接等&#xff09;时&#xff0c;由于…...

vue实现换肤功能

1、使用scss定义几种需要进行换肤的颜色&#xff0c;例如&#xff1a; .font-color-theme{[color-theme"black"] & {color: #000}[color-theme"white"] & {color: #fff} }2、使用以下代码控制变化&#xff1b; let colorType localStorage.getIt…...

嵌入式软件工程师面试题——2025校招社招通用(八)

说明&#xff1a; 面试题来源于网络书籍&#xff0c;公司题目以及博主原创或修改&#xff08;题目大部分来源于各种公司&#xff09;&#xff1b;文中很多题目&#xff0c;或许大家直接编译器写完&#xff0c;1分钟就出结果了。但在这里博主希望每一个题目&#xff0c;大家都要…...

背包笔记

01背包 朴素版01背包 cin >> n >> m; f[0][0] 0; for(int i 1; i < n; i ) {for(int j 0; j < m; j ){f[i][j] f[i - 1][j];//第i个物品不选if(j - v[i] > 0){f[i][j] max(f[i][j], f[i - 1][j - v[i]] w[i]);//选第i个物品}} }cout << f[n…...

【Redis 速通】Redis 在 Linux 上的单机服务快速搭建与部署(附完整流程步骤及命令代码)

Redis 单机版安装与部署 Written By: Xinyao Tian 概述 本文档主要描述了 Redis 的生产环境安装及配置方法。 主要步骤 编译及安装 进入 root 用户并上传 Redis 源码安装包 查看 Redis 源码安装包的上传情况: [rootcentos-host redis]# pwd /opt/redis [root centos-ho…...

前端JavaScript

文章目录 一、JavaScript概述JS简介1.ECMAScript和JavaScript的关系2.ECMAScript的历史3.什么是javas&#xff1f;4.JavaScript的作用&#xff1f; 三者之间的作用JS基础1.注释语法2.引入js的多种方式3.结束符号 变量与常量变量1.JavaScript声明2.var与let的区别常量 基本数据类…...

C语言程序设计(第五版)谭浩强 第三章课后题答案

第三章 1、假如我国国民生产总值的年增长率为7%&#xff0c; 计算10年后我国国民生产总值与现在相比增长多少百分比。计算公式为 ,其中r为年增长率&#xff0c;n为年数&#xff0c;p为与现在相比的倍数。 #include<stdio.h> #include<math.h>int main(){float r,…...

uni-app 解决钉钉小程序日期组件uni-datetime-picker不兼容ios问题

最近在使用uni-app开发 钉钉小程序 &#xff0c;遇到一个ios的兼容性问题 uni-datetime-picker 组件在模拟器上可以使用&#xff0c;在真机上不生效问题 文章目录 1. 不兼容的写法&#xff0c;uni-datetime-picker 不兼容IOS2. 兼容的写法&#xff0c;使用 dd.datePicker 实现。…...

【C++入门 三】学习C++缺省参数 | 函数重载 | 引用

C入门 三 1.缺省参数1.1 缺省参数概念1.2 缺省参数分类 2. 函数重载2.1 函数重载概念2.2 C支持函数重载的原理--名字修饰(name Mangling) 3.引用3.1引用概念3.2引用特性3.3 常引用3.4 使用场景1. 做参数2. 做返回值 3.5 传值、传引用效率比较3.6引用和指针的区别 4.引用和指针的…...

视频增强修复软件Topaz Video AI mac中文版支持功能

Topaz Video AI mac是一款使用人工智能技术对视频进行增强和修复的软件。它可以自动降噪、去除锐化、减少压缩失真、提高清晰度等等。Topaz Video AI可以处理各种类型的视频&#xff0c;包括低分辨率视频、老旧影片、手机录制的视频等等。 使用Topaz Video AI非常简单&#xff…...

C# 使用Thread类建线程

C# 使用Thread类建线程 目录 C# 使用Thread类建线程引言Thread类启动线程优先级后台运行线程状态线程名称线程ID最后 引言 线程(thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。线程是我们程序常用的并行运行控制手段&#xff0c;…...

asyncio协程框架

asyncio 基本用法 asyncio 包含以下几个主要的组件&#xff1a;协程 asyncio 支持使用 async/await 语法定义协程&#xff08;coroutine&#xff09;。协程是可以暂停和恢复执行的函数&#xff0c;可以实现非阻塞式的异步编程。 import asyncioasync def coroutine():print(H…...

TSINGSEE智慧安防:AI人员入侵检测算法的工作原理及应用场景概述

人员入侵检测算法基于视频分析技术&#xff0c;自动对视频画面进行分析识别&#xff0c;可以对危险区的人员闯入、靠近等行为进行实时进行检测并预警&#xff0c;无需人工干预&#xff0c;协助管理者对场所的安全问题进行监管&#xff0c;可以广泛运用在学校、园区、工地、车站…...