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

带你玩转Jetson之Deepstream简明教程(四)DeepstreamApp如何使用以及用于工程验证。

1.DeepstreamApp是什么?

        如果你安装完毕deepstream整体框架,会在你的系统执行目录内有可执行文件,文件名字是deepstream-app。这是一个可执行脚本文件,通过deepstream框架中的代码在安装的时候编译后install到系统根目录内。

        此脚本文件可以通过终端命令行使用,使用的同时必须使用txt文本文件作为配置文件。此脚本可以通过txt配置一个“相当简单的”deepstream管道,管道中的视频源可以通过txt文本设置为各种输入,包括但不限于本地视频文件,网络上的rtsp推流等等。管道中的堆叠,一级、二级推理、跟踪、OSD等也可以通过txt文本文件进行相当简单快速的配置。

        使用终端输入deepstream-app -h即可查看如何使用此脚本。

        这个deepstream-app程序是安装deepstream的时候就已经编译好安装在系统里,可以在任意位置的命令终端进行调用。App分为deepstream-app和deepstream-test5-app两种。两者功能上的差别就是tset5支持类型设置为6的sink,也就是向kafka服务器收发数据的组件。其余二者大致相同。英伟达也附赠了两个app的源代码,基于C++的源代码的位置位于:(可以学习参考)

opt/nvidia/deepstream/deepstream-5.1/sources/apps/sample_apps/deepstream-app
opt/nvidia/deepstream/deepstream-5.1/sources/apps/sample_apps/deepstream-test5

 2.Deepstream-App存在的意义?

        deepstream-app脚本存在主要有两个意义。

        首先第一个,用于工程快速验证性开发。因为deepstream-app是一个通过文本文件就能配置的管道,因此可以在您视频应用的早期阶段进行深度学习网络性能和设备硬件性能的快速测试。譬如您设计、训练了一个网络,要部署到nx上面,需要实时处理8路视频。此时您对nx的性能没有底,或者是并不知道这个网络在nx上能不能跑八路。这时候总不能现用c++或者python开发个系统再去测试吧。代码的时间是宝贵的,为了快速验证可行性,通常会先把网络设计训练完毕,然后通过deepstream-app脚本装载到简单管道里做一下压力测试。这样可以快速验证项目可行性。

        其次第二个,deepstream-app可以验证网络性能瓶颈和辅助排除Bug。我之前遇到过一个大学的学生设计制作矿井安全监控,他们在3090上面跑了20多路1080p的视频流,开到22个视频流就开始卡顿,无推理结果,他们使用了c++脚本二次开发。因为他们的代码揉合了自己的代码和deepstream官方代码,有很多自定义的方法和类,短时间摸透他们的代码并不容易,且代码风格一团糟。也没有注释,这时候就开始把他们的网络通过deepstream-app配置一个22路视频同时输入的管道,通过配置发现deepstream-app本身工作正常,并没有出现卡顿无推理的情况。所以基本排除了deepstream本身的关键组件出现问题的可能。将问题锁定在了他们自己的代码位置。最后通过排查发现他们是版本控制太乱,有个学生在管道内通过tee组件插了一个支路,这个支路导致了线程崩溃。再者说,如果您的deepstream工程出现了卡顿、性能瓶颈等,完全可以把网络模型单独拿出来用txt写个简单管道,挨个排查deepstream每个单元可能的问题。如果deepstream-app都没问题,就需要自己排查自己写的部分代码。

3.Deepstream-app怎么用?

        Deepstream-app的用法非常简洁。即脚本+配置文件。具体写法如下所示:

deepstream-app -c 您的配置文件.txt

        脚本会自动解析您配置文件里面的内容然后组成管道。所以我们的重点应该放在这个配置文件如何写。下面,我贴出来一份以YoloV5m为范例的配置文件,逐行进行分析。

################################################################################
# Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
################################################################################[application]
enable-perf-measurement=1
perf-measurement-interval-sec=5
#gie-kitti-output-dir=streamscl[tiled-display]
enable=1
rows=1
columns=1
width=1920
height=1080[source0]
enable=1
#Type - 1=CameraV4L2 2=URI 3=MultiURI 4=RTSP
type=3
uri=rtsp://admin:HuaWei123@113.128.197.19:54388/LiveMedia/ch1/Media1
#uri=file:///home/jetson/vedio/1.mp4
num-sources=1
gpu-id=0
# (0): memtype_device   - Memory type Device
# (1): memtype_pinned   - Memory type Host Pinned
# (2): memtype_unified  - Memory type Unified
cudadec-memtype=0[sink0]
enable=1
#Type - 1=FakeSink 2=EglSink 3=File 4=RTSPStreaming 5=Overlay 6=send message to cloud(only enable in test5-app)
type=6
msg-conv-config=./MsgConfig/config.txt
msg-conv-payload-type=0
#(0): PAYLOAD_DEEPSTREAM - Deepstream schema payload
#(1): PAYLOAD_DEEPSTREAM_MINIMAL - Deepstream schema payload minimal
#(256): PAYLOAD_RESERVED - Reserved type
#(257): PAYLOAD_CUSTOM   - Custom schema payload
msg-broker-proto-lib=/opt/nvidia/deepstream/deepstream-5.1/lib/libnvds_kafka_proto.so
#msg-broker-conn-str=127.0.0.1;9092;RawData
msg-broker-conn-str=192.168.1.104;9092;RawData
topic=RawData[sink1]
enable=1
#Type - 1=FakeSink 2=EglSink 3=File 4=RTSPStreaming 5=Overlay
type=4
#1=h264 2=h265
codec=1
#encoder type 0=Hardware 1=Software
enc-type=0
sync=0
bitrate=4000000
#H264 Profile - 0=Baseline 2=Main 4=High
#H265 Profile - 0=Main 1=Main10
profile=0
# set below properties in case of RTSPStreaming
rtsp-port=8554
udp-port=5400[osd]
enable=1
border-width=2
text-size=15
text-color=1;1;1;1;
text-bg-color=0.3;0.3;0.3;1
font=Serif
show-clock=0
clock-x-offset=800
clock-y-offset=820
clock-text-size=12
clock-color=1;0;0;0[streammux]
##Boolean property to inform muxer that sources are live
live-source=0
batch-size=1
##time out in usec, to wait after the first buffer is available
##to push the batch even if the complete batch is not formed
batched-push-timeout=40000
## Set muxer output width and height
width=1920
height=1080
## If set to TRUE, system timestamp will be attached as ntp timestamp
## If set to FALSE, ntp timestamp from rtspsrc, if available, will be attached
# attach-sys-ts-as-ntp=1# config-file property is mandatory for any gie section.
# Other properties are optional and if set will override the properties set in
# the infer config file.[primary-gie]
enable=1
bbox-border-color0=1;0;0;1
bbox-border-color1=0;1;1;1
bbox-border-color2=0;0;1;1
bbox-border-color3=0;1;0;1
gie-unique-id=1
config-file=./Models/config.txt[tracker]
enable=1
# For the case of NvDCF tracker, tracker-width and tracker-height must be a multiple of 32, respectively
tracker-width=640
tracker-height=384
ll-lib-file=/opt/nvidia/deepstream/deepstream-5.1/lib/libnvds_mot_iou.so
#ll-lib-file=/opt/nvidia/deepstream/deepstream-5.1/lib/libnvds_nvdcf.so
#ll-lib-file=/opt/nvidia/deepstream/deepstream-5.1/lib/libnvds_mot_klt.so
#ll-config-file required for DCF/IOU only
#ll-config-file=tracker_config.yml
#ll-config-file=iou_config.txt
gpu-id=0
#enable-batch-process and enable-past-frame applicable to DCF only
enable-batch-process=1
enable-past-frame=0
display-tracking-id=1[tests]
file-loop=0

        让我们逐组件逐行来进行翻译和解释。说在最前面,这份配置文件是通过“#”字符来进行注释的,如果有不需要的设置或者需要更改设置,建议使用“#”来进行无效化,不建议直接删,否则可能会记不住删除了那些东西。

[application]
enable-perf-measurement=1
perf-measurement-interval-sec=5

        首先来看application总体配置。enable-perf-measurement的意思是开启每秒帧数测试。是否开启fps帧率检测,0代表不开启1代表开始,下面的perf-measurement-interval-sec参数是多少帧率计算一次用来做数据平滑。

[source0]
enable=1
#Type - 1=CameraV4L2 2=URI 3=MultiURI 4=RTSP
type=3
uri=rtsp://admin:HuaWei123@113.128.197.19:54388/LiveMedia/ch1/Media1
#uri=file:///home/jetson/vedio/1.mp4
num-sources=1
gpu-id=0
# (0): memtype_device   - Memory type Device
# (1): memtype_pinned   - Memory type Host Pinned
# (2): memtype_unified  - Memory type Unified
cudadec-memtype=0

        然后来看source0,这个是deepstream的输入源,您可以在这个source组件进行视频流输入的配置。如果您有一个视频流就写[source0],如果有多个就[source1],[source2],[source3]依次往下递增序号即可。enable不用说了还是一个使能设置,0则关闭1则开启。type类型是告诉deepstream-app大概是什么类型的输入,1是V4L2也就是linux硬件设备树上面的摄像头,2是网络URI,3是万能设置,比2更好,可以读取本地文件。4是指定的RTSP视频流。我一般直接用3即可。

        然后是Uri链接,如果是网络连接或者是ip摄像头,直接把rtsp地址copy过来即可。就如同上面的:uri=rtsp://admin:HuaWei123@113.128.197.19:54388/LiveMedia/ch1/Media1。如果是本地的视频文件,需要特定的写法。这个我也是论坛查了好久才查到的,具体写法就是uri:///加上文件在系统内的绝对路径加上文件名字。这样写deepstream-app就能直接读取本地视频流进行推理。

[streammux]
##Boolean property to inform muxer that sources are live
live-source=0
batch-size=1
##time out in usec, to wait after the first buffer is available
##to push the batch even if the complete batch is not formed
batched-push-timeout=40000
## Set muxer output width and height
width=1920
height=1080
## If set to TRUE, system timestamp will be attached as ntp timestamp
## If set to FALSE, ntp timestamp from rtspsrc, if available, will be attached
# attach-sys-ts-as-ntp=1

        Streammux插件是deepstream的混流插件,比如你输入是30路视频流,需要通过Streammux插件将视频流混流到一起,组成一个视频流。这里需要注意的是batch-size改成了1,还有输入输出的尺寸需要设计好。

[primary-gie]
enable=1
bbox-border-color0=1;0;0;1
bbox-border-color1=0;1;1;1
bbox-border-color2=0;0;1;1
bbox-border-color3=0;1;0;1
gie-unique-id=1
config-file=./Models/config.txt

        [primary-gie]插件就是我们需要用到的推理插件,这个插件在deepstream-app的txt配置文件中需要写的东西不多,上面的几个参数分别是使能,bbox框颜色,bbox框是否生成唯一id。后面这个config-file目录才是重点。这里文件目录采用的是和终端命令行相似的相对目录,在deepstream-app的txt配置文件的同级目录下的Models的文件夹内的config文件。这个目录和文件名到时候根据您的项目来随意写。网络推理的相关参数都在这个config文本内。接下来我们看一下这个config.txt文本内到底是什么。

################################################################################
# Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
################################################################################# Following properties are mandatory when engine files are not specified:
#   int8-calib-file(Only in INT8), model-file-format
#   Caffemodel mandatory properties: model-file, proto-file, output-blob-names
#   UFF: uff-file, input-dims, uff-input-blob-name, output-blob-names
#   ONNX: onnx-file
#
# Mandatory properties for detectors:
#   num-detected-classes
#
# Optional properties for detectors:
#   cluster-mode(Default=Group Rectangles), interval(Primary mode only, Default=0)
#   custom-lib-path
#   parse-bbox-func-name
#
# Mandatory properties for classifiers:
#   classifier-threshold, is-classifier
#
# Optional properties for classifiers:
#   classifier-async-mode(Secondary mode only, Default=false)
#
# Optional properties in secondary mode:
#   operate-on-gie-id(Default=0), operate-on-class-ids(Defaults to all classes),
#   input-object-min-width, input-object-min-height, input-object-max-width,
#   input-object-max-height
#
# Following properties are always recommended:
#   batch-size(Default=1)
#
# Other optional properties:
#   net-scale-factor(Default=1), network-mode(Default=0 i.e FP32),
#   model-color-format(Default=0 i.e. RGB) model-engine-file, labelfile-path,
#   mean-file, gie-unique-id(Default=0), offsets, process-mode (Default=1 i.e. primary),
#   custom-lib-path, network-mode(Default=0 i.e FP32)
#
# The values in the config file are overridden by values set through GObject
# properties.[property]
gpu-id=0
net-scale-factor=0.0039215697906911373
#0=RGB, 1=BGR
model-color-format=0
custom-network-config=yolov5s
model-file=yolov5s.wts
model-engine-file=yolov5s_fp16.engine
labelfile-path=labels.txt
int8-calib-file=yolov5s.trt.calib.table
## 0=FP32, 1=INT8, 2=FP16 mode
network-mode=2
num-detected-classes=2
gie-unique-id=1
network-type=0
is-classifier=0
## 0=Group Rectangles, 1=DBSCAN, 2=NMS, 3= DBSCAN+NMS Hybrid, 4 = None(No clustering)
cluster-mode=2
maintain-aspect-ratio=1
parse-bbox-func-name=NvDsInferParseCustomYoloV5
custom-lib-path=libnvdsinfer_custom_impl_yolov5.so
engine-create-func-name=NvDsInferYoloCudaEngineGet
#scaling-filter=0
#scaling-compute-hw=0

        首先,前面的大段都是nvidia的版权声明,从poperty这里开始是推理引擎的配置。gpu-id是指定相关gpu,单卡就是0,多卡依次按序号指定。net-scale-factor一般是默认数据。需要注意的是,这里的:

custom-network-config=yolov5s
model-file=yolov5s.wts
model-engine-file=yolov5s_fp16.engine
parse-bbox-func-name=NvDsInferParseCustomYoloV5
custom-lib-path=libnvdsinfer_custom_impl_yolov5.so
engine-create-func-name=NvDsInferYoloCudaEngineGet

几行要合起来看,因为我这里使用的是deepstream的第三方网络也就是yolov5m,deepstream并不能直接加载且解析网络、构建网络的加速引擎、并且对网络推理的后处理bbox进行解析,所以需要你自己编写一个.so来进行上述工作。parse-bbox-func-name就是指出bbox解析的api名称,custom-lib-path是你的.so库名字,engine-create-func-name是你库的解析yolov5模型创建引擎的api名称。需要注意的是,如果你使用的英伟达TAO或者TLT迁移学习,深度学习网络模型是从nvidia官网上下载的resnet19等训练好的etlt模型,可以无缝接入Deepstream不用做这个第三方库。直接就可以简化为:

model-file=resnet19.etlt
model-engine-file=resnet19_fp16.engine

        剩下的关于深度学习网络的配置我就不一一介绍了,基本都是推理相关,我等会会把每一条都是什么的官网查询文档贴出来。

        接着来看跟踪器相关设置。

[tracker]
enable=1
# For the case of NvDCF tracker, tracker-width and tracker-height must be a multiple of 32, respectively
tracker-width=640
tracker-height=384
ll-lib-file=/opt/nvidia/deepstream/deepstream-5.1/lib/libnvds_mot_iou.so
#ll-lib-file=/opt/nvidia/deepstream/deepstream-5.1/lib/libnvds_nvdcf.so
#ll-lib-file=/opt/nvidia/deepstream/deepstream-5.1/lib/libnvds_mot_klt.so
#ll-config-file required for DCF/IOU only
#ll-config-file=tracker_config.yml
#ll-config-file=iou_config.txt
gpu-id=0
#enable-batch-process and enable-past-frame applicable to DCF only
enable-batch-process=1
enable-past-frame=0
display-tracking-id=1

        Tracker组件用于对推理目标进行跟踪,譬如一个摄像头30FPS,但是推理性能不够只有15FPS,需要跳帧推理的时候,中间没有进行推理的帧就通过跟踪器进行追踪,确保不会丢失bbox。或者是针对目标进行单一id化,确保目标识别出来后在画面内始终保持同一个id。在车船人员计数方面还是有一定作用,防止bbox推理丢失后产生多重计数等。

        nvidia这边提供了三种跟踪方式,分别是iou、nvdcf、klt光流。iou最简单算力使用最低,但是效果最差劲,klt光流法最好但是最吃算力。nvdcf是英伟达自己开发的算法,通过概率去预测。是一个比较均衡的。此Tracker组件需要根据选用的算法指定具体.so,追踪宽高基本是默认的。

        需要注意的是上述追踪算法在jetson平台默认自动运行于VIC内,会减少CPU占用。

[osd]
enable=1
border-width=2
text-size=15
text-color=1;1;1;1;
text-bg-color=0.3;0.3;0.3;1
font=Serif
show-clock=0
clock-x-offset=800
clock-y-offset=820
clock-text-size=12
clock-color=1;0;0;0

        OSD插件适用于bbox可视化,基本就是线宽,是否展示id,颜色等等,不做过多赘述。此插件也是在jetson平台用VIC进行硬件加速的,会减少cpu占用。

[sink0]
enable=1
#Type - 1=FakeSink 2=EglSink 3=File 4=RTSPStreaming 5=Overlay 6=msgbroker(only enable in test5-app)
type=6
msg-conv-config=./MsgConfig/config.txt
msg-conv-payload-type=0
#(0): PAYLOAD_DEEPSTREAM - Deepstream schema payload
#(1): PAYLOAD_DEEPSTREAM_MINIMAL - Deepstream schema payload minimal
#(256): PAYLOAD_RESERVED - Reserved type
#(257): PAYLOAD_CUSTOM   - Custom schema payload
msg-broker-proto-lib=/opt/nvidia/deepstream/deepstream-5.1/lib/libnvds_kafka_proto.so
#msg-broker-conn-str=127.0.0.1;9092;RawData
msg-broker-conn-str=192.168.1.104;9092;RawData
topic=RawData

        sink是管道最后的sink接受终端,enable-1代表开启,type种类非常丰富。1就是假的sink,啥也不干。算法纯在后台运行不做任何显示或者处理。2是图像显示,格式是EGL。3是文件sink,在接收到视频流后直接在本地存文件。4是RTSP推流。5是全屏直接显示,6是服务器收发消息组件,仅在deepstream-test5-app有效。此处选择了6。

        msg-conv-config参数是配置摄像头位置信息的,仅仅在360度扭曲变换那个例子有用,这里直接抄过来了怕出错。不过里边的东西没用。msg-conv-payload-type就是每一帧发送什么样的消息,0就是所有的都发,1简短一些,256 257是自定义和预留的参数。msg-broker-proto-lib是选择底层用什么通讯,这里选用了kafka。msg-broker-conn-str参数是服务参数配置,这里nx代表了kafka的producer,需要给一个broker发送消息。Kafka的broker就相当于是个托管服务器,消费者和生产者的消息都要过这个broker中间人。第一个是broker服务的地址,第二个是端口,第三个是Topic。下面的Topic参数和上面的写一致即可。

        上面这个主要是为了给kafka服务器发送数据,如果只是做本地显示,改成如下即可。

[sink0]
enable=1
#Type - 1=FakeSink 2=EglSink 3=File 4=RTSPStreaming 5=Overlay 6=msgbroker(only enable in test5-app)
type=2

        如果你想通过deepstream-app推流,也可以如下设置sink组件来达到推流效果:

[sink1]
enable=1
#Type - 1=FakeSink 2=EglSink 3=File 4=RTSPStreaming 5=Overlay
type=4
#1=h264 2=h265
codec=1
#encoder type 0=Hardware 1=Software
enc-type=0
sync=0
bitrate=4000000
#H264 Profile - 0=Baseline 2=Main 4=High
#H265 Profile - 0=Main 1=Main10
profile=0
# set below properties in case of RTSPStreaming
rtsp-port=8554
udp-port=5400

        sink1是rtsp的推流sink,可以接受管道数据然后在局域网转推出来。Codec是选择编码格式,默认h264。Enc-type是编码器选择,这里肯定选硬件编码器。Sync是同步选择,就是视频源头推送一帧我这个sink就推送一帧,是同步且实时的,但是有点不好的就是读取带有延迟的网络视频流,经过网络的传输实时延迟已经很大了,就会造成sync报错视频卡顿,所以sync还是不开了,给关掉了。Bitrate是编码比特率,默认参数。Profile暂时没搞懂,默认的参数。Rtsp port和udp port都是网络端口信息。这俩都是默认即可,可以根据网络环境更改。最后管道在运行的时候就可以得到一个实时推流地址。

4.实机演示

        验证平台:Jetson NX 8 GB 、yolov5m 、deeepstream 5.1

        运行效果如上图所示。 如果你还增加了rtsp推流,将结果推出,脚本会输出rtsp地址以供查看。

5.概括Deepstream-app脚本优缺点

        优点1.快速搭建用于验证的管道模型。

        优点2.通过控制关键组件enable的0、1来排查bug或者性能瓶颈。

        缺点:基本就是个直肠子,只能组建source-mux混流-gie推理-(gie二级推理)-tracker-osd-sink这样的简单管道,至于您要想搞什么tee插件分流,搞什么opencv挂探针取图,基本不可能,只能靠二次开发。如果您的管道设计非常简单,甚至不用二次开发用deepstream-app脚本挂管道就行了。但是如果您的设计较为复杂,此脚本远远无法满足。还是得搞开发环境二次开发。

6.相关资料

        上述配置文件中各种眼花缭乱的配置有些很重要有些是次要的,好多都没写,我只写了主要的。但是要查这些组件的配置去哪里查呢?英伟达doc文档中心有deepstream的设置参数手册,里边罗列了非常详细的参数列表和建议参数还有参数含义。在这里将地址挂出来您自行查询。

         地址在这里:

https://docs.nvidia.com/metropolis/deepstream/dev-guide/text/DS_ref_app_deepstream.html

        感谢您的阅读!

相关文章:

带你玩转Jetson之Deepstream简明教程(四)DeepstreamApp如何使用以及用于工程验证。

1.DeepstreamApp是什么? 如果你安装完毕deepstream整体框架,会在你的系统执行目录内有可执行文件,文件名字是deepstream-app。这是一个可执行脚本文件,通过deepstream框架中的代码在安装的时候编译后install到系统根目录内。 此脚…...

快速搭建个人在线书库,随时随地畅享阅读!

前边我们利用NAS部署了个人的导航页、小说站、云笔记,今天,我们再看看怎么部署一个个人的在线书库。 相信很多朋友都在自己的电脑中收藏了大量的PDF、MOBI等格式的电子书籍,但是一旦换了一台设备,要么是无法翻阅,要么…...

电子纸墨水屏的现实应用场景

电子纸挺好个东西,大家都把注意力集中在商超场景 其实还有更多有趣的场景方案可用,价值也不小,比如: 一、仓库场景 通过亮灯拣选,提高仓库作业效率 二、仓库循环使用标签 做NFC类发卡式应用,替代传统纸…...

常量const、引用、指针的大杂烩

文章目录1 普通引用1.1 对普通值的普通引用1.2 对常量值的普通引用1.3 对普通指针的普通引用1.4 对常量指针的普通引用1.5 对指针常量的普通引用1.6 对指向常量的指针常量的普通引用2 常量引用2.1 对普通值的常量引用2.2 对常量值的常量引用2.3 对普通指针的常量引用2.4 对常量…...

宝塔搭建实战php开源likeadmin通用管理移动端uniapp源码(四)

大家好啊,我是测评君,欢迎来到web测评。 上一期给大家分享了pc端的部署方式,今天来给大家分享uniapp端在本地搭建,与打包发布到宝塔的方法。感兴趣的朋友可以自行下载学习。 技术架构 vscode node16 vue3 uniapp vite types…...

Hive的分区表与分桶表内部表外部表

文章目录1 Hive分区表1.1 Hive分区表的概念?1.1.1 分区表注意事项1.2 分区表物理存储结构1.3 分区表使用场景1.4 静态分区表是什么?1.4.1 静态分区表案例1.4.2 分区表练习一1.4.3 分区操作1.5 动态分区表是什么?1.5.1 动态态分区表案例&#…...

和数集团打造《神念无界:源起山海》,诠释链游领域创新与责任

首先,根据网上资料显示,一部《传奇》,二十年热血依旧。 《传奇》所缔造的成绩,承载的是多少人的青春回忆,《传奇》无疑已经在游戏史上写下了浓墨重彩的一笔。 相比《传奇》及背后的研发运营公司娱美德名声大噪&#x…...

小白入门模拟IC设计,如何快速学习?

众所周知,模拟电路很难学。以最普遍的晶体管来说,我们分析它的时候必须首先分析直流偏置,其次在分析交流输出电压。可以说,确定工作点就是一项相当麻烦的工作(实际中来说),晶体管的参数多、参数…...

51单片机——中断系统之外部中断实验,小白讲解,相互学习

中断介绍 中断是为使单片机具有对外部或内部随机发生的事件实时处理而设置的,中断功能的存在,很大程度上提高了单片机处理外部或内部事件的能力。它也是单片机最重要的功能之一,是我们学些单片机必须要掌握的。 为了更容易的理解中断概念&…...

如何设计一个秒杀系统

秒杀系统要如何设计? 前言 高并发下如何设计秒杀系统?这是一个高频面试题。这个问题看似简单,但是里面的水很深,它考查的是高并发场景下,从前端到后端多方面的知识。 秒杀一般出现在商城的促销活动中,指定…...

厄瓜多尔公司注册方案

简介: 经济概况与商机 厄瓜多尔是世界上第74大国家,是南美西部国家,与哥伦比亚,秘鲁和太平洋接壤。厄瓜多尔地处世界中心,地理位置优越,地理位置优越-赤道线零纬度,使其成为通往太平洋的理想枢…...

安全渗透环境准备(工具下载)

数据来源 01 一些VM虚拟机的安装 攻击机kali: kali官网 渗透测试工具Kali Linux安装与使用 kali汉化 虚拟机网络建议设置成NAT模式,桥接有时不稳定。 靶机OWASP_Broken_Web_Apps: 迅雷下载 网盘下载 安装教程 开机之后需要登录&am…...

118.(leaflet篇)leaflet空间判断-点与geojson面图层的空间关系(turf实现)

听老人家说:多看美女会长寿 地图之家总目录(订阅之前建议先查看该博客) 文章末尾处提供保证可运行完整代码包,运行如有问题,可“私信”博主。 效果如下所示: 下面献上完整代码,代码重要位置会做相应解释 <!DOCTYPE html> <html>...

目标检测与目标跟踪算法技术汇总

现如今chatgpt的爆火&#xff0c;我也使用了一段时间&#xff0c;问了许多关于人工智能技术的问题&#xff0c;基本是它能够回答了大部分的原理的&#xff0c;至于其人工智能涉及到的算法以及网络&#xff0c;考虑到也没有图&#xff0c;可能在给出这类回答上&#xff0c;是不太…...

Linux 系统启动过程

过去几十年&#xff0c;公用事业行业发生了重大变化。能源需求的转变导致企业利润率的波动&#xff0c;但不是运营成本的波动。 许多公用事业公司通过后勤部门流程自动化来削减成本&#xff0c;比如招采流程自动化。 在招采活动中&#xff0c;人工招采会产生盲点。由于公共事业…...

【每日一题Day118】LC1124表现良好的最长时间段 | 前缀和+单调栈/哈希表

表现良好的最长时间段【LC1124】 给你一份工作时间表 hours&#xff0c;上面记录着某一位员工每天的工作小时数。 我们认为当员工一天中的工作小时数大于 8 小时的时候&#xff0c;那么这一天就是「劳累的一天」。 所谓「表现良好的时间段」&#xff0c;意味在这段时间内&#…...

vue使用nprogress(进度条)

目录 1.安装 2.引入 3.配置 4.使用 5.使用场景 6.改变颜色 1.安装 npm install --save nprogress2.引入 import NProgress from nprogress import nprogress/nprogress.css3.配置 NProgress.configure({easing: ease, // 动画方式&#xff0c;和css动画属性一样&#…...

@NotNull 、@NotBlank、@NotEmpty区别和使用

引言 今天在使用validation校验的时候&#xff0c;发现了使用校验不起作用&#xff0c;一时间有点摸不到头绪&#xff0c;就看了一下同事提交的代码&#xff0c;发现了问题在用NotNull用法&#xff0c;用的有些错误&#xff0c;所以在这里讲一下NotNull、NotBlank、NotEmpty区…...

Nacos——Nacos简介以及Nacos Server安装

资料来源&#xff1a;02-Nacos配置管理-什么是配置中心_哔哩哔哩_bilibili nacos记得下载2.x版本的&#xff0c;负责以后新建配置的时候会出现“发布错误&#xff0c;请检查参数是否正确”错误&#xff01;&#xff01;&#xff01;&#xff01; 目录 一、Nacos简介 1.1 四…...

Presto 文档和笔记

1. Presto Presto 官网 Presto 文档 2. 配置 3.1 node 配置 cat etc/node.properties # Generated by Apache Ambari. Fri Feb 10 14:52:10 2023node.data-dir/mnt/bmr/presto/data node.environmentproduction node.idbmr-master-4b7cbaa3.2 jvm 配置 cat etc/jvm.confi…...

大尺度衰落与小尺度衰落

一. 大尺度衰落 无线电磁波信号在收发天线长距离&#xff08;远大于传输波长&#xff09;或长时间范围发生的功率变化&#xff0c;称为大尺度衰落&#xff0c;一般可以用路径损耗模型来描述&#xff0c;路径损耗是由发射功率在空间中的辐射扩散造成的&#xff0c;根据功率传输…...

完美解决:重新安装VMware Tools灰色。以及共享文件夹的创建(centos8)

解决&#xff1a;重新安装VMware Tools灰色问题&#xff1a;重新安装VMware Tools灰色解决方案-挂载VMware中的linux.iso1. vmtools的linux.iso挂载及安装2. 共享文件夹的创建及配置问题&#xff1a;重新安装VMware Tools灰色 发现一个小问题&#xff0c;我的vm虚拟机安装后发…...

达梦数据库作业管理

一、基本功能 作业系统大致包含作业&#xff0c;警报&#xff0c;操作员三部分。 作业可运行DMPL/SQL脚本&#xff0c;定期备份数据库&#xff0c;检查等。可定时执行&#xff0c;也可通过警报触发执行&#xff0c;可产生警报通知用户状态。一个作业由多个步骤组成&#xff0c…...

数据结构-考研难点代码突破(C++实现树型查找-二叉搜索树(二叉排序树))

文章目录1.二叉搜索树基本操作二叉搜索树的效率分析2. C实现1.二叉搜索树基本操作 二叉排序树是具有下列特性的二叉树&#xff1a; 若左子树非空&#xff0c;则左子树上所有结点的值均小于根结点的值。若右子树非空&#xff0c;则右子树上所有结点的值均大于根结点的值。左、…...

emqx异常处理

启动异常 通过解压tar压缩包安装后通过 ./bin/emqx start 启动报错 WARNING: Default (insecure) Erlang cookie is in use. WARNING: Configure node.cookie in /opt/emqx/etc/emqx.conf or override from environment variable EMQX_NODE__COOKIE NOTE: Use the same config…...

Web前端:开始学习ReactJS需要知道什么?

毫无疑问&#xff0c;ReactJS是前端开发者中最著名的库之一&#xff0c;它的受欢迎程度与日俱增。用ReactJS构建的网站看起来非常棒&#xff0c;大多数开发新手都被它吸引住了。然而&#xff0c;许多新人和有经验的开发人员在没有首先了解先决条件的情况下&#xff0c;就直接用…...

卡诺图化简

1.相关概念 最小项&#xff1a;函数的某个乘积项包含了函数的全部变量&#xff08;原变量或反变量的形式&#xff09;&#xff0c;且每个变量仅出现一次&#xff0c;则这个乘积项为该函数的一个标准积项。 最小项中的原变量记为1&#xff0c;反变量记为0&#xff0c;当变量顺序…...

带你了解软件测试是做什么的

软件测试是互联网技术中一门重要的学科&#xff0c;它是软件生命周期中不可或缺的一个环节&#xff0c;担负着把控、监督软件的质量的重任。 人才稀缺&#xff0c;对于求职者来说就意味着机会。但是很多想学习软件测试的人对这个学科并不了解&#xff0c;也不知道该如何学习&a…...

企业电子招投标采购系统源码之功能模块功能描述

​ 功能模块&#xff1a; 待办消息&#xff0c;招标公告&#xff0c;中标公告&#xff0c;信息发布 描述&#xff1a; 全过程数字化采购管理&#xff0c;打造从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。通供应商门户具备内外协同的能力&#xff0c;为外…...

职场中的高手,是如何高质量解决问题?

职场总会遇见很多新问题&#xff0c;高手会从容应对&#xff0c;因为他们学习了一套通 用理论&#xff0c;可以处理工作当中的大部分内容&#xff0c;剩下的一部分能够用快速 提问的方式找到思路。 记得几年前有个同事 A&#xff0c;下午四点多项目突然丢过来一个活&#xff0c…...

wordpress主题 时光/少儿培训

取出每个数的各个数位分别与2进行比较即可 public class Main {public static void main(String[] args) {int count 0;for (int i 1; i < 2021; i){int temp i;while(temp ! 0){if(temp % 10 2){count;}temp / 10;}}System.out.println(count); //624} }...

重点培育学科建设网站/北京seo优化

前言:在慕课网上学习剑指Java面试-Offer直通车时所做的笔记,供本人复习之用,比较难,我也没大懂,只记录大概意思以后有接触了再改,想要详细解说的不建议看这篇博客. 目录 第一章 对象在内存中的布局 第二章 Monitor 2.1 Monitor在字节码中的表示 第三章 锁的优化 3.1 自旋…...

wordpress伪静态别名/网站的优化从哪里进行

业务数据 下面的示例绘制折线图显示从1970年开始学校在不同年份开通数量。 给定的数据如下&#xff1a; 年份 学校数量 1970 15 1980 30 1990 60 2000 120 2013 240 2014 300 基于AWT的应用 以下是对从上述给定的信息创建线型图的代码。此代码可以帮助在AWT的应用程序嵌入一个折…...

c 转网站开发/2022年今天新闻联播

作者 | 丁彦军责编 | 仲培艺近日&#xff0c;有位粉丝向我请教&#xff0c;在爬取某网站时&#xff0c;网页的源代码出现了中文乱码问题&#xff0c;本文就将与大家一起总结下关于网络爬虫的乱码处理。注意&#xff0c;这里不仅是中文乱码&#xff0c;还包括一些如日文、韩文 、…...

怎么联网访问自己做的网站/qq空间秒赞秒评网站推广

原理很简单&#xff0c;根据你的给定的字段和之前设定的reduce值来分区 比如说 我先设置成 set mapreduce.job.reduces3; 然后将id 分成三个区&#xff0c;然后按成绩排序 select * from score distribute by s_id sort by s_score; 注&#xff1a;可能打印出来不是很明显&a…...

山西省政府网站集约化建设工作/seo网站搭建是什么

重新运行 遇到这种Failed to create/delete directory xxxxx 如果是create重新运行&#xff0c;如果是delete则找到这个文件手动删除...