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

【深度学习】C++ Tensorrt Yolov8 目标检测推理

C++ Tensorrt Yolov8 目标检测推理

  • 模型导出
  • 代码
    • yolov8.h
    • yolov8.cpp
    • common.hpp
    • CMakeList
    • main.cpp

C++ tensorrt对yolov8目标检测模型进行推理。
Windows版本下只需要修改common.hpp对文件的判断S_ISREG 和对文件夹的判断S_ISDIR即可,非核心代码,不调用删掉都可以。亲测可行。

模型导出

python 导出onnx

from ultralytics import YOLO# Load the YOLOv8 model
model = YOLO("best.pt")# # Export the model to ONNX format
model.export(format="onnx", dynamic=False, simplify=True, imgsz = (640,640), opset=12, half=False, int8=False)  # creates 'yolov8n.onnx'

tensorRT自带bin下的trtexec导出engine模型


## export trt/
(base) xiaoxin@xiaoxin:/usr/local/TensorRT-8.6.1.6/bin$ sudo ./trtexec --onnx=/home/xiaoxin/Documents/ultralytics-main/best.onnx --saveEngine=/home/xiaoxin/Documents/ultralytics-main/best.engine --workspace=1024 --fp16# Key	Value	Description
# format	'torchscript'	format to export to
# imgsz	640	image size as scalar or (h, w) list, i.e. (640, 480)
# keras	False	use Keras for TF SavedModel export
# optimize	False	TorchScript: optimize for mobile
# half	False	FP16 quantization
# int8	False	INT8 quantization
# dynamic	False	ONNX/TF/TensorRT: dynamic axes
# simplify	False	ONNX: simplify model
# opset	None	ONNX: opset version (optional, defaults to latest)
# workspace	4	TensorRT: workspace size (GB)
# nms	False	CoreML: add NMS

代码

yolov8.h

#ifndef YOLOV8_H
#define YOLOV8_H
#include "NvInferPlugin.h"
#include "common.hpp"
#include "fstream"
using namespace det;#define _PRINT true
// #define BATCHED_NMS
// #define assert(_Expression) ((void)0)class YOLOv8 {
public:explicit YOLOv8(const std::string& engine_file_path);~YOLOv8();void                 makePipe(bool warmup = true);void                 copyFromMat(const cv::Mat& image);void                 copyFromMat(const cv::Mat& image, cv::Size& size);void                 letterBox(const cv::Mat& image, cv::Mat& out, cv::Size& size);void                 infer();void                 postprocess(std::vector<Object>& objs,float                score_thres = 0.25f,float                iou_thres   = 0.65f,int                  topk        = 100,int                  num_labels  = 1);static void          draw_objects(const cv::Mat&                                image,cv::Mat&                                      res,const std::vector<Object>&                    objs,const std::vector<std::string>&               CLASS_NAMES,const std::vector<std::vector<unsigned int>>& COLORS);public:int                  num_bindings;int                  num_inputs  = 0;int                  num_outputs = 0;std::vector<Binding> input_bindings;std::vector<Binding> output_bindings;std::vector<void*>   host_ptrs;std::vector<void*>   device_ptrs;PreParam pparam;Parameter param;private:nvinfer1::ICudaEngine*       engine  = nullptr;nvinfer1::IRuntime*          runtime = nullptr;nvinfer1::IExecutionContext* context = nullptr;cudaStream_t                 stream  = nullptr;Logger                       gLogger{nvinfer1::ILogger::Severity::kERROR};
};
#endif  // YOLOV8_H

yolov8.cpp

#include "yolov8.h"// init engine model
YOLOv8::YOLOv8(const std::string& engine_file_path)
{// 1. make sure this file can be open by binary mode.std::ifstream file(engine_file_path, std::ios::binary);if(!file.good()){if(_PRINT){std::cout << "[ERROR] can not open file, please check up your engine file!" << std::endl;}return;}// 2. move pointer to the end.file.seekg(0, std::ios::end);// 3. get the location of current pointer.auto size = file.tellg();// 4. move pointer to start.file.seekg(0, std::ios::beg);char* trtModelStream = new char[size];assert(trtModelStream);file.read(trtModelStream, size);file.close();// 5. create runtime object deserialization///    important tip   ///// in order to use initLibNvInferPlugins, link to nvinfer_plugin.so or nvinfer_plugin.dll.// if you have some errors in this method, check up your .so or .dll files. you can put them in program directory.initLibNvInferPlugins(&this->gLogger, "");this->runtime = nvinfer1::createInferRuntime(this->gLogger);assert(this->runtime != nullptr);this->engine = this->runtime->deserializeCudaEngine(trtModelStream, size);assert(this->engine != nullptr);delete[] trtModelStream;// 6. create some space to store intermediate activation values.this->context = this->engine->createExecutionContext();assert(this->context != nullptr);cudaStreamCreate(&this->stream);// 7. get number of input tensor and output tensor.this->num_bindings = this->engine->getNbBindings();// 8. get binding dimensions, this process can support different dimensions.for (int i = 0; i < this->num_bindings; ++i) {Binding            binding;nvinfer1::Dims     dims;nvinfer1::DataType dtype = this->engine->getBindingDataType(i);std::string        name  = this->engine->getBindingName(i);binding.name             = name;binding.dsize            = type_to_size(dtype);bool IsInput = engine->bindingIsInput(i);if (IsInput) {this->num_inputs += 1;dims         = this->engine->getProfileDimensions(i, 0, nvinfer1::OptProfileSelector::kMAX);binding.size = get_size_by_dims(dims);binding.dims = dims;this->input_bindings.push_back(binding);// set max opt shapethis->context->setBindingDimensions(i, dims);}else {dims         = this->context->getBindingDimensions(i);binding.size = get_size_by_dims(dims);binding.dims = dims;this->output_bindings.push_back(binding);this->num_outputs += 1;}}
}YOLOv8::~YOLOv8()
{this->context->destroy();this->engine->destroy();this->runtime->destroy();cudaStreamDestroy(this->stream);for (auto& ptr : this->device_ptrs) {CHECK(cudaFree(ptr));}for (auto& ptr : this->host_ptrs) {CHECK(cudaFreeHost(ptr));}
}// warm up.
void YOLOv8::makePipe(bool warmup)
{for (auto& bindings : this->input_bindings) {void* d_ptr;CHECK(cudaMallocAsync(&d_ptr, bindings.size * bindings.dsize, this->stream));this->device_ptrs.push_back(d_ptr);}for (auto& bindings : this->output_bindings) {void * d_ptr, *h_ptr;size_t size = bindings.size * bindings.dsize;CHECK(cudaMallocAsync(&d_ptr, size, this->stream));CHECK(cudaHostAlloc(&h_ptr, size, 0));this->device_ptrs.push_back(d_ptr);this->host_ptrs.push_back(h_ptr);}if (warmup) {for (int i = 0; i < 5; i++) {for (auto& bindings : this->input_bindings) {size_t size  = bindings.size * bindings.dsize;void*  h_ptr = malloc(size);memset(h_ptr, 0, size);CHECK(cudaMemcpyAsync(this->device_ptrs[0], h_ptr, size, cudaMemcpyHostToDevice, this->stream));free(h_ptr);}this->infer();}if(_PRINT){printf("model warmup 5 times\n");}}
}void YOLOv8::letterBox(const cv::Mat& image, cv::Mat& out, cv::Size& size)
{const float inp_h  = size.height;const float inp_w  = size.width;float       height = image.rows;float       width  = image.cols;float r    = std::min(inp_h / height, inp_w / width);int   padw = std::round(width * r);int   padh = std::round(height * r);cv::Mat tmp;if ((int)width != padw || (int)height != padh) {cv::resize(image, tmp, cv::Size(padw, padh));}else {tmp = image.clone();}float dw = inp_w - padw;float dh = inp_h - padh;dw /= 2.0f;dh /= 2.0f;int top    = int(std::round(dh - 0.1f));int bottom = int(std::round(dh + 0.1f));int left   = int(std::round(dw - 0.1f));int right  = int(std::round(dw + 0.1f));cv::copyMakeBorder(tmp, tmp, top, bottom, left, right, cv::BORDER_CONSTANT, {114, 114, 114});cv::dnn::blobFromImage(tmp, out, 1 / 255.f, cv::Size(), cv::Scalar(0, 0, 0), true, false, CV_32F);this->pparam.ratio  = 1 / r;this->pparam.dw     = dw;this->pparam.dh     = dh;this->pparam.height = height;this->pparam.width  = width;
}void YOLOv8::copyFromMat(const cv::Mat& image)
{cv::Mat  nchw;auto&    in_binding = this->input_bindings[0];auto     width      = in_binding.dims.d[3];auto     height     = in_binding.dims.d[2];cv::Size size{width, height};this->letterBox(image, nchw, size);this->context->setBindingDimensions(0, nvinfer1::Dims{4, {1, 3, height, width}});CHECK(cudaMemcpyAsync(this->device_ptrs[0], nchw.ptr<float>(), nchw.total() * nchw.elemSize(), cudaMemcpyHostToDevice, this->stream));
}void YOLOv8::copyFromMat(const cv::Mat& image, cv::Size& size)
{cv::Mat nchw;this->letterBox(image, nchw, size);this->context->setBindingDimensions(0, nvinfer1::Dims{4, {1, 3, size.height, size.width}});CHECK(cudaMemcpyAsync(this->device_ptrs[0], nchw.ptr<float>(), nchw.total() * nchw.elemSize(), cudaMemcpyHostToDevice, this->stream));
}void YOLOv8::infer()
{this->context->enqueueV2(this->device_ptrs.data(), this->stream, nullptr);for (int i = 0; i < this->num_outputs; i++) {size_t osize = this->output_bindings[i].size * this->output_bindings[i].dsize;CHECK(cudaMemcpyAsync(this->host_ptrs[i], this->device_ptrs[i + this->num_inputs], osize, cudaMemcpyDeviceToHost, this->stream));}cudaStreamSynchronize(this->stream);
}void YOLOv8::postprocess(std::vector<Object>& objs, float score_thres, float iou_thres, int topk, int num_labels)
{if(param.setPam){score_thres = param.score_thres;iou_thres = param.iou_thres;topk = param.topk;num_labels = param.num_labels;}objs.clear();auto num_channels = this->output_bindings[0].dims.d[1];auto num_anchors  = this->output_bindings[0].dims.d[2];auto& dw     = this->pparam.dw;auto& dh     = this->pparam.dh;auto& width  = this->pparam.width;auto& height = this->pparam.height;auto& ratio  = this->pparam.ratio;std::vector<cv::Rect> bboxes;std::vector<float>    scores;std::vector<int>      labels;std::vector<int>      indices;cv::Mat output = cv::Mat(num_channels, num_anchors, CV_32F, static_cast<float*>(this->host_ptrs[0]));output         = output.t();for (int i = 0; i < num_anchors; i++) {auto  row_ptr    = output.row(i).ptr<float>();auto  bboxes_ptr = row_ptr;auto  scores_ptr = row_ptr + 4;auto  max_s_ptr  = std::max_element(scores_ptr, scores_ptr + num_labels);float score      = *max_s_ptr;if (score > score_thres) {float x = *bboxes_ptr++ - dw;float y = *bboxes_ptr++ - dh;float w = *bboxes_ptr++;float h = *bboxes_ptr;float x0 = clamp((x - 0.5f * w) * ratio, 0.f, width);float y0 = clamp((y - 0.5f * h) * ratio, 0.f, height);float x1 = clamp((x + 0.5f * w) * ratio, 0.f, width);float y1 = clamp((y + 0.5f * h) * ratio, 0.f, height);int              label = max_s_ptr - scores_ptr;cv::Rect_<float> bbox;bbox.x      = x0;bbox.y      = y0;bbox.width  = x1 - x0;bbox.height = y1 - y0;bboxes.push_back(bbox);labels.push_back(label);scores.push_back(score);}}#ifdef BATCHED_NMScv::dnn::NMSBoxesBatched(bboxes, scores, labels, score_thres, iou_thres, indices);
#elsecv::dnn::NMSBoxes(bboxes, scores, score_thres, iou_thres, indices);
#endifint cnt = 0;for (auto& i : indices) {if (cnt >= topk) {break;}Object obj;obj.rect  = bboxes[i];obj.prob  = scores[i];obj.label = labels[i];objs.push_back(obj);cnt += 1;}
}void YOLOv8::draw_objects(const cv::Mat&                                image,cv::Mat&                                      res,const std::vector<Object>&                    objs,const std::vector<std::string>&               CLASS_NAMES,const std::vector<std::vector<unsigned int>>& COLORS)
{res = image.clone();for (auto& obj : objs) {cv::Scalar color = cv::Scalar(COLORS[obj.label][0], COLORS[obj.label][1], COLORS[obj.label][2]);cv::rectangle(res, obj.rect, color, 2);char text[256];sprintf(text, "%s %.1f%%", CLASS_NAMES[obj.label].c_str(), obj.prob * 100);int      baseLine   = 0;int x = (int)obj.rect.x;int y = (int)obj.rect.y + 1;y > res.rows ? res.rows : y;/ you can choose whether you need a background for text. // cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.4, 1, &baseLine);// cv::rectangle(res, cv::Rect(x, y, label_size.width, label_size.height + baseLine), {0, 0, 255}, -1);cv::putText(res, text, cv::Point(x, y), cv::FONT_HERSHEY_SIMPLEX, 0.4, {0, 0, 255}, 1);}
}

common.hpp

#ifndef COMMON_HPP
#define COMMON_HPP
#include "NvInfer.h"
#include "opencv2/opencv.hpp"
#include <sys/stat.h>
#include <unistd.h>#define CHECK(call)                                                                                                    \do {                                                                                                               \const cudaError_t error_code = call;                                                                           \if (error_code != cudaSuccess) {                                                                               \printf("CUDA Error:\n");                                                                                   \printf("    File:       %s\n", __FILE__);                                                                  \printf("    Line:       %d\n", __LINE__);                                                                  \printf("    Error code: %d\n", error_code);                                                                \printf("    Error text: %s\n", cudaGetErrorString(error_code));                                            \exit(1);                                                                                                   \}                                                                                                              \} while (0)class Logger: public nvinfer1::ILogger 
{
public:nvinfer1::ILogger::Severity reportableSeverity;explicit Logger(nvinfer1::ILogger::Severity severity = nvinfer1::ILogger::Severity::kINFO):reportableSeverity(severity){}void log(nvinfer1::ILogger::Severity severity, const char* msg) noexcept override{if (severity > reportableSeverity) {return;}switch (severity) {case nvinfer1::ILogger::Severity::kINTERNAL_ERROR:std::cerr << "INTERNAL_ERROR: ";break;case nvinfer1::ILogger::Severity::kERROR:std::cerr << "ERROR: ";break;case nvinfer1::ILogger::Severity::kWARNING:std::cerr << "WARNING: ";break;case nvinfer1::ILogger::Severity::kINFO:std::cerr << "INFO: ";break;default:std::cerr << "VERBOSE: ";break;}std::cerr << msg << std::endl;}
};inline int get_size_by_dims(const nvinfer1::Dims& dims)
{int size = 1;for (int i = 0; i < dims.nbDims; i++) {size *= dims.d[i];}return size;
}inline int type_to_size(const nvinfer1::DataType& dataType)
{switch (dataType) {case nvinfer1::DataType::kFLOAT:return 4;case nvinfer1::DataType::kHALF:return 2;case nvinfer1::DataType::kINT32:return 4;case nvinfer1::DataType::kINT8:return 1;case nvinfer1::DataType::kBOOL:return 1;default:return 4;}
}inline static float clamp(float val, float min, float max)
{return val > min ? (val < max ? val : max) : min;
}inline bool IsPathExist(const std::string& path)
{if (access(path.c_str(), 0) == F_OK) {return true;}return false;
}inline bool IsFile(const std::string& path)
{if (!IsPathExist(path)) {printf("%s:%d %s not exist\n", __FILE__, __LINE__, path.c_str());return false;}struct stat buffer;return (stat(path.c_str(), &buffer) == 0 && S_ISREG(buffer.st_mode));
}inline bool IsFolder(const std::string& path)
{if (!IsPathExist(path)) {return false;}struct stat buffer;return (stat(path.c_str(), &buffer) == 0 && S_ISDIR(buffer.st_mode));
}namespace det 
{struct Binding {size_t         size  = 1;size_t         dsize = 1;nvinfer1::Dims dims;std::string    name;};struct Object {cv::Rect_<float> rect;int              label = 0;float            prob  = 0.0;};struct PreParam {float ratio  = 1.0f;float dw     = 0.0f;float dh     = 0.0f;float height = 0;float width  = 0;};struct Parameter{bool setPam = false;float score_thres = 0.25f;float iou_thres = 0.65f;int topk = 100;int num_labels = 1;};
}  // namespace det
#endif  // COMMON_HPP

CMakeList

cmake_minimum_required(VERSION 3.1)set(CMAKE_CUDA_ARCHITECTURES 60 61 62 70 72 75 86 89 90)
set(CMAKE_CUDA_COMPILER /usr/local/cuda/bin/nvcc)project(yolov8 LANGUAGES CXX CUDA)set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -O3")
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_BUILD_TYPE Release)
option(CUDA_USE_STATIC_CUDA_RUNTIME OFF)# CUDA
find_package(CUDA REQUIRED)
message(STATUS "CUDA Libs: \n${CUDA_LIBRARIES}\n")
get_filename_component(CUDA_LIB_DIR ${CUDA_LIBRARIES} DIRECTORY)
message(STATUS "CUDA Headers: \n${CUDA_INCLUDE_DIRS}\n")# OpenCV
find_package(OpenCV REQUIRED)
message(STATUS "OpenCV Libs: \n${OpenCV_LIBS}\n")
message(STATUS "OpenCV Libraries: \n${OpenCV_LIBRARIES}\n")
message(STATUS "OpenCV Headers: \n${OpenCV_INCLUDE_DIRS}\n")# TensorRT
set(TensorRT_INCLUDE_DIRS /usr/include/x86_64-linux-gnu)
set(TensorRT_LIBRARIES /usr/lib/x86_64-linux-gnu)message(STATUS "TensorRT Libs: \n${TensorRT_LIBRARIES}\n")
message(STATUS "TensorRT Headers: \n${TensorRT_INCLUDE_DIRS}\n")list(APPEND INCLUDE_DIRS${CUDA_INCLUDE_DIRS}${OpenCV_INCLUDE_DIRS}${TensorRT_INCLUDE_DIRS}include)list(APPEND ALL_LIBS${CUDA_LIBRARIES}${CUDA_LIB_DIR}${OpenCV_LIBRARIES}${TensorRT_LIBRARIES})include_directories(${INCLUDE_DIRS})add_executable(${PROJECT_NAME}main.cppyolov8.cppcommon.hpp)target_link_directories(${PROJECT_NAME} PUBLIC ${ALL_LIBS})
target_link_libraries(${PROJECT_NAME} PRIVATE nvinfer nvinfer_plugin cudart ${OpenCV_LIBS})if (${OpenCV_VERSION} VERSION_GREATER_EQUAL 4.7.0)message(STATUS "Build with -DBATCHED_NMS")add_definitions(-DBATCHED_NMS)
endif ()

main.cpp

#include "chrono"
#include "opencv2/opencv.hpp"
#include "yolov8.h"
#include <iostream>using namespace std;const std::vector<std::string> CLASS_NAMES = {"blackPoint"};const std::vector<std::vector<unsigned int>> COLORS = {{0, 0, 255}};int main(int argc, char** argv)
{// cuda:0cudaSetDevice(0);const std::string engine_file_path{"/home/xiaoxin/Documents/ultralytics-main/last.engine"};const std::string path{"/home/xiaoxin/Documents/ultralytics-main/datasets/Tray/labelImg"};std::vector<std::string> imagePathList;bool                     isVideo{false};auto yolov8 = new YOLOv8(engine_file_path);yolov8->makePipe(true);if (IsFile(path)){std::string suffix = path.substr(path.find_last_of('.') + 1);if (suffix == "jpg" || suffix == "jpeg" || suffix == "png") {imagePathList.push_back(path);}else if (suffix == "mp4" || suffix == "avi" || suffix == "m4v" || suffix == "mpeg" || suffix == "mov"|| suffix == "mkv") {isVideo = true;}else {printf("suffix %s is wrong !!!\n", suffix.c_str());std::abort();}}else if (IsFolder(path)) {cv::glob(path + "/*.png", imagePathList);}cv::Mat  res, image;cv::Size size        = cv::Size{640, 640};yolov8->param.setPam = true;yolov8->param.num_labels  = 1;yolov8->param.topk        = 100;yolov8->param.score_thres = 0.25f;yolov8->param.iou_thres   = 0.35f; // 0.65fstd::vector<Object> objs;cv::namedWindow("result", cv::WINDOW_AUTOSIZE);if (isVideo) {cv::VideoCapture cap(path);if (!cap.isOpened()) {printf("can not open %s\n", path.c_str());return -1;}while (cap.read(image)) {objs.clear();yolov8->copyFromMat(image, size);auto start = std::chrono::system_clock::now();yolov8->infer();auto end = std::chrono::system_clock::now();yolov8->postprocess(objs);yolov8->draw_objects(image, res, objs, CLASS_NAMES, COLORS);auto tc = (double)std::chrono::duration_cast<std::chrono::microseconds>(end - start).count() / 1000.;printf("cost %2.4lf ms\n", tc);cv::imshow("result", res);if (cv::waitKey(10) == 'q') {break;}}}else {for (auto& path : imagePathList) {objs.clear();image = cv::imread(path);yolov8->copyFromMat(image, size);auto start = std::chrono::system_clock::now();yolov8->infer();yolov8->postprocess(objs);yolov8->draw_objects(image, res, objs, CLASS_NAMES, COLORS);auto end = std::chrono::system_clock::now();auto tc = (double)std::chrono::duration_cast<std::chrono::microseconds>(end - start).count() / 1000.;printf("cost %2.4lf ms\n", tc);resize(res, res, cv::Size(0,0), 3, 3);cv::imshow("result", res);cv::waitKey(0);}}cv::destroyAllWindows();delete yolov8;return 0;
}

相关文章:

【深度学习】C++ Tensorrt Yolov8 目标检测推理

C Tensorrt Yolov8 目标检测推理 模型导出代码yolov8.hyolov8.cppcommon.hppCMakeListmain.cpp C tensorrt对yolov8目标检测模型进行推理。 Windows版本下只需要修改common.hpp对文件的判断S_ISREG 和对文件夹的判断S_ISDIR即可&#xff0c;非核心代码&#xff0c;不调用删掉都…...

【项目日记(二)】搜索引擎-索引制作

❣博主主页: 33的博客❣ ▶️文章专栏分类:项目日记◀️ &#x1f69a;我的代码仓库: 33的代码仓库&#x1f69a; &#x1faf5;&#x1faf5;&#x1faf5;关注我带你了解更多项目内容 目录 1.前言2.索引结构2.1创捷索引2.2根据索引查询2.3新增文档2.4内存索引保存到磁盘2.5把…...

K 近邻、K-NN 算法图文详解

1. 为什么学习KNN算法 KNN是监督学习分类算法&#xff0c;主要解决现实生活中分类问题。根据目标的不同将监督学习任务分为了分类学习及回归预测问题。 KNN&#xff08;K-Nearest Neihbor&#xff0c;KNN&#xff09;K近邻是机器学习算法中理论最简单&#xff0c;最好理解的算法…...

Eclipse + GDB + J-Link 的单片机程序调试实践

Eclipse GDB J-Link 的调试实践 本文介绍如何创建Eclipse的调试配置&#xff0c;如何控制调试过程&#xff0c;如何查看修改各种变量。 对 Eclipse 的要求 所用 Eclipse 应当安装了 Eclipse Embedded CDT 插件。从 https://www.eclipse.org/downloads/packages/ 下载 Ecli…...

前端代码生成辅助工具

1&#xff0c;Axure Axure设计的界面如何生成HTML文件 https://blog.csdn.net/qq_43279782/article/details/112387511 Axure 生成HTML 文件&#xff0c;并用Chrome打开 https://blog.csdn.net/qq_30718137/article/details/80621025 2&#xff0c;OpenUI [开源] OpenUI …...

静态库与动态库总结

一、库文件和头文件 所谓库文件&#xff0c;可以将其理解为压缩包文件&#xff0c;该文件内部通常包含不止一个目标文件&#xff08;也就是二进制文件&#xff09;。 值得一提的是&#xff0c;库文件中每个目标文件存储的代码&#xff0c;并非完整的程序&#xff0c;而是一个…...

深入解析tcpdump:网络数据包捕获与分析的利器

引言 在网络技术日新月异的今天&#xff0c;网络数据包的捕获与分析成为了网络管理员、安全专家以及开发人员不可或缺的技能。其中&#xff0c;tcpdump作为一款强大的网络数据包捕获分析工具&#xff0c;广泛应用于Linux系统中。本文将从技术人的角度&#xff0c;详细分析tcpdu…...

【漏洞复现】科立讯通信有限公司指挥调度管理平台uploadgps.php存在SQL注入

0x01 产品简介 科立讯通信指挥调度管理平台是一个专门针对通信行业的管理平台。该产品旨在提供高效的指挥调度和管理解决方案&#xff0c;以帮助通信运营商或相关机构实现更好的运营效率和服务质量。该平台提供强大的指挥调度功能&#xff0c;可以实时监控和管理通信网络设备、…...

什么是自然语言处理(NLP)?详细解读文本分类、情感分析和机器翻译的核心技术

什么是自然语言处理&#xff1f; 自然语言处理&#xff08;Natural Language Processing&#xff0c;简称NLP&#xff09;是人工智能的一个重要分支&#xff0c;旨在让计算机理解、解释和生成人类的自然语言。打个比方&#xff0c;你和Siri对话&#xff0c;或使用谷歌翻译翻译一…...

【linux】gcc快速入门教程

目录 一.gcc简介 二.gcc常用命令 一.gcc简介 gcc 是GNU Compiler Collection&#xff08;GNU编译器套件&#xff09;。就是一个编译器。编译一个源文件的时候可以直接使用&#xff0c;但是源文件数量太多时&#xff0c;就很不方便&#xff0c;于是就出现了make 工具 二.gcc…...

【多维动态规划】Leetcode 97. 交错字符串【中等】

交错字符串 给定三个字符串 s1、s2、s3&#xff0c;请你帮忙验证 s3 是否是由 s1 和 s2 交错 组成的。 两个字符串 s 和 t 交错 的定义与过程如下&#xff0c;其中每个字符串都会被分割成若干 非空 子字符串 子字符串 是字符串中连续的 非空 字符序列。 s s1 s2 … snt…...

【JavaScript脚本宇宙】精通前端开发:六大热门CSS框架详解

前端开发的利器&#xff1a;深入了解六大CSS框架 前言 在现代Web开发中&#xff0c;选择适合的前端框架和工具包是构建高效、响应式和美观的网站或应用程序的关键。本文将详细介绍六个广受欢迎的CSS框架&#xff1a;Bootstrap、Bulma、Tailwind CSS、Foundation、Materialize…...

开发技术-Java集合(List)删除元素的几种方式

文章目录 1. 错误的删除2. 正确的方法2.1 倒叙删除2.2 迭代器删除2.3 removeAll() 删除2.4 removeIf() 最简单的删除 3. 总结 1. 错误的删除 在写代码时&#xff0c;想将其中的一个元素删除&#xff0c;就遍历了 list &#xff0c;使用了 remove()&#xff0c;发现效果并不是想…...

c++ 递归

递归函数是指在函数定义中调用自身的函数。C语言也支持递归函数。 下面是一个使用递归函数计算阶乘的例子&#xff1a; #include <iostream> using namespace std;int factorial(int n) {// 基本情况&#xff0c;当 n 等于 0 或 1 时&#xff0c;阶乘为 1if (n 0 || n…...

RedHat9 | podman容器

1、容器技术介绍 传统问题 应用程序和依赖需要一起安装在物理主机或虚拟机上的操作系统应用程序版本比当前操作系统安装的版本更低或更新两个应用程序可能需要某一软件的不同版本&#xff0c;彼此版本之间不兼容 解决方式 将应用程序打包并部署为容器容器是与系统的其他部分…...

边缘计算项目有哪些

边缘计算项目在多个领域得到了广泛的应用&#xff0c;以下是一些典型的边缘计算项目案例&#xff1a; 1. **智能交通系统**&#xff1a;通过在交通信号灯、监控摄像头等设备上部署边缘计算&#xff0c;可以实时分析交通流量&#xff0c;优化交通信号控制&#xff0c;减少拥堵&…...

计算fibonacci数列每一项时所需的递归调用次数

斐波那契数列是一个经典的数列&#xff0c;其中每一项是前两项的和&#xff0c;定义为&#xff1a; [ F(n) F(n-1) F(n-2) ] 其中&#xff0c;( F(0) 0 ) 和 ( F(1) 1 )。 对于计算斐波那契数列的第 ( n ) 项&#xff0c;如果使用简单的递归方法&#xff0c;其时间复杂度是…...

【教学类65-05】20240627秘密花园涂色书(中四班练习)

【教学类65-03】20240622秘密花园涂色书03&#xff08;通义万相&#xff09;&#xff08;A4横版1张&#xff0c;一大 68张纸136份&#xff09;-CSDN博客 背景需求: 打印以下几款秘密花园样式&#xff08;每款10份&#xff09;给中四班孩子玩一下&#xff0c;看看效果 【教学类…...

Python 学习之基础语法(一)

Python的语法基础主要包括以下几个方面&#xff0c;下面将逐一进行分点表示和归纳&#xff1a; 一、基本语法 1. 注释 a. 单行注释&#xff1a;使用#开头&#xff0c;例如# 这是一个单行注释。 b. 多行注释&#xff1a;使用三引号&#xff08;可以是三个单引号或三个双引号&…...

日志分析-windows系统日志分析

日志分析-windows系统日志分析 使用事件查看器分析Windows系统日志 cmd命令 eventvwr 筛选 清除日志、注销并重新登陆&#xff0c;查看日志情况 Windows7和Windowserver2008R2的主机日志保存在C:\Windows\System32\winevt\Logs文件夹下&#xff0c;Security.evtx即为W…...

【ARM】MDK工程切换高版本的编译器后出现error A1137E报错

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 解决工程从Compiler 5切换到Compiler 6进行编译时出现一些非语法问题上的报错。 2、 问题场景 对于一些使用Compiler 5进行编译的工程&#xff0c;要切换到Compiler 6进行编译的时候&#xff0c;原本无任何报错警告…...

深入 SSH:解锁本地转发、远程转发和动态转发的潜力

文章目录 前言一、解锁内部服务&#xff1a;SSH 本地转发1.1 什么是 SSH 本地转发1.2 本地转发应用场景 二、打开外部访问大门&#xff1a;SSH 远程转发2.1 什么是 SSH 远程转发2.2 远程转发应用场景 三、动态转发&#xff1a;SSH 让你拥有自己的 VPN3.1 什么是 SSH 动态转发3.…...

python如何把一个函数的返回值,当成这个函数的参数值

python如何把一个函数的返回值&#xff0c;当成这个函数的参数值 1. 递归调用 递归是一种函数自己调用自己的方法。在递归调用中&#xff0c;你可以将前一次调用的返回值作为下一次调用的参数。 def recursive_function(x):# 函数逻辑if 条件满足:return 结果else:return rec…...

【融合ChatGPT等AI模型】Python-GEE遥感云大数据分析、管理与可视化及多领域案例应用

随着航空、航天、近地空间遥感平台的持续发展&#xff0c;遥感技术近年来取得显著进步。遥感数据的空间、时间、光谱分辨率及数据量均大幅提升&#xff0c;呈现出大数据特征。这为相关研究带来了新机遇&#xff0c;但同时也带来巨大挑战。传统的工作站和服务器已无法满足大区域…...

SpringBoot: Eureka入门

1. IP列表 公司发展到一定的规模之后&#xff0c;应用拆分是无可避免的。假设我们有2个服务(服务A、服务B)&#xff0c;如果服务A要调用服务B&#xff0c;我们能怎么做呢&#xff1f;最简单的方法是让服务A配置服务B的所有节点的IP&#xff0c;在服务A内部做负载均衡调用服务B…...

Typescript 【实用教程】(2024最新版)含类型声明,类型断言,函数,接口,泛型等

简介 TypeScript 是 JavaScript 的超集&#xff0c;是 JavaScript&#xff08;弱类型语言&#xff09; 的强类型版本。 拥有类型机制文件后缀 .tsTypescript type ES6TypeScript 和 JavaScript 的关系类似 less 和 css 的关系TypeScript对 JavaScript 添加了一些扩展&#x…...

智慧校园-实训管理系统总体概述

智慧校园实训管理系统&#xff0c;专为满足高等教育与职业教育的特定需求而设计&#xff0c;它代表了实训课程管理领域的一次数字化飞跃。此系统旨在通过革新实训的组织结构、执行流程及评估标准&#xff0c;来增强学生的实践操作技能和教师的授课效率&#xff0c;为社会输送具…...

如何用GPT开发一个基于 GPT 的应用?

原文发自博客&#xff1a;GPT应用开发小记 如何开发一个基于 GPT 的应用&#xff1f;答案就在问题里&#xff0c;那就是用 GPT 来开发基于 GPT 的应用。本文以笔者的一个开源项目 myGPTReader 为例&#xff0c;分享我是如何基于 GPT 去开发这个系统的&#xff0c;这个系统的功能…...

大数据生态体系中各组件的区别面试题(更新)

一、MapReduce与Spark有什么区别&#xff1f; 1、处理方式: MapReduce基于磁盘处理数据&#xff0c;将中间结果保存到磁盘中,减少了内存占用&#xff0c;计算速度慢。 基于内存处理数据&#xff0c;将计算的中间结果保存到内存中&#xff0c;计算速度快。2、资源申请方式&…...

数字信号处理实验一(离散信号及离散系统的MATLAB编程实现)

实验要求&#xff1a; 离散信号及离散系统的MATLAB编程实现&#xff08;2学时&#xff09; 要求&#xff1a; 编写一程序&#xff0c;输出一定长度&#xff08;点数&#xff09;&#xff0c;具有一定幅度、&#xff08;角&#xff09;频率和初始相位的实&#xff08;或复&…...

ipv6域名解析 做网站/列表网推广收费标准

某天晚上凌晨突然收到一封国外boss的需求文件过来&#xff0c;附件夹带着一个excel文件&#xff0c;没来得及看密密麻麻的英文邮件内容&#xff0c;怀着忐忑不安的心情打开附件&#xff0c;以为又是一个难搞的复杂需求&#xff0c;结果内容只有一条。关掉附件&#xff0c;常出了…...

企业网站推广营销/快速seo优化

构造器的作用&#xff1a; 1.创建对象。 设计类时&#xff0c;若不显示的声明类的构造器的话&#xff0c;程序会默认提供一个空参的构造器。 一旦显示的定义了构造器&#xff0c;就不再默认提供。 声明类的构造器&#xff1a;权限修饰符 与类同名&#xff08;形参&#xff09;{…...

金泉网站建设开发/seo搜索引擎优化报价

一问题&#xff1a;一辆校车能装下多少个高尔夫球&#xff1f; 答&#xff1a;读题关键词“校车”“装下”“高尔夫球”&#xff0c;问题“多少个”。校车是什么用途&#xff0c;专用来载学校里面学生教育工作者的。高尔夫球是什么。一种运动器材。或者一种商品&#xff08;还没…...

成都网站建设 urkeji/今日新闻最新

*2019互联网岳麓峰会现场 在“2019互联网岳麓峰会”上&#xff0c;智能驾驶依旧是各方热议话题。在百度李彦宏、腾讯苏奎锋和滴滴贾兆寅眼里&#xff0c;2019智能汽车将会如何发展&#xff1f;自动驾驶到智慧城市又该如何走&#xff1f; 百度创始人、董事长兼CEO李彦宏&#…...

网站设计定位/怎么做网站免费的

组件 如图所示&#xff1a; 下载地址&#xff1a;TAB组件 在此基础修改&#xff1a;vue高仿立体卡片效果&#xff08;第一版&#xff09; 更新记录&#xff1a; 1.0 修复中间分割线ios端异常&#xff0c;放弃border-image采用after伪元素实现...

甘肃省环保建设申报网站/app推广注册招代理

最近做一个视频系统&#xff0c;需要实现从网页上传大文件给服务器。一般情况下都是采用Ajax异步方式&#xff0c;创建一个iframe&#xff0c;在iframe里面把数据以form方式提交给后端的服务器脚本&#xff0c;由服务器脚本(比如PHP)来负责接收上传的数据。这种方式存在性能和效…...