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

融媒体服务中PBO进行多重采样抗锯齿(MSAA)

如果不理解pbo 那先去了解概念,在此不再解释,这是我为了做融合服务器viewpointserver做的一部分工作,融合服务器的功能是将三维和流媒体,AI融合在一起,viewpointserver会直接读取三维工程的文件,同时融合rtsp视频流,将视频流作为纹理给材质,最后赋值给三维模型如fbx的表面。由于没有窗口,三维作为服务运行,里面有一项工作就是三维的抗锯齿采集。

PBO(Pixel Buffer Object)进行多重采样抗锯齿(MSAA)的一般步骤

1 初始化 OpenGL 和 MSAA 帧缓冲:

1.1开启 MSAA:

在初始化 OpenGL 时,通过设置相关参数开启多重采样抗锯齿。例如,使用 glEnable(GL_MULTISAMPLE) 函数来启用 OpenGL 的多重采样功能。

1.2 创建帧缓冲:

创建一个帧缓冲对象(FBO),用于存储多重采样后的图像数据。这可以通过 glGenFramebuffers 和 glBindFramebuffer 等函数来完成。

1.3 配置 FBO 的附件:

为 FBO 配置颜色附件和深度附件。对于颜色附件,创建一个纹理,并将其绑定到 FBO 上;对于深度附件,可以创建一个渲染缓冲对象(RBO)并绑定到 FBO。确保纹理和 RBO 的尺寸与渲染窗口的尺寸相匹配。

2 渲染到 MSAA 帧缓冲:

2.1 绑定 MSAA 帧缓冲:

在渲染场景之前,使用 glBindFramebuffer 函数将之前创建的 MSAA FBO 绑定为当前的渲染目标。这样,后续的渲染操作将把图像数据渲染到 MSAA FBO 中。

2.2 进行常规渲染:

按照正常的 OpenGL 渲染流程绘制场景中的物体。由于启用了 MSAA,OpenGL 会在每个像素内进行多个子采样,以实现抗锯齿效果。

3 使用 PBO 读取 MSAA 数据:

创建 PBO:使用 glGenBuffers 函数创建一个 PBO,并使用 glBindBuffer 函数将其绑定到 GL_PIXEL_PACK_BUFFER 目标上。然后,使用 glBufferData 函数为 PBO 分配足够的内存空间,以存储从 MSAA FBO 读取的像素数据。
读取像素数据到 PBO:在渲染完成后,使用 glReadPixels 函数将 MSAA FBO 中的像素数据读取到 PBO 中。由于 PBO 的存在,这个操作可以在后台异步进行,减少对 CPU 的阻塞。

4 处理和解析 PBO 中的数据:

4.1 映射 PBO:

使用 glMapBuffer 函数将 PBO 映射到 CPU 可访问的内存空间,以便读取和处理像素数据。这将返回一个指向 PBO 内存的指针,可以通过该指针访问像素数据。

4.2 解析像素数据:

根据需要,对 PBO 中的像素数据进行处理和解析。例如,可以将像素数据转换为图像格式,以便保存为文件或进行其他操作。在处理像素数据时,需要考虑 MSAA 的子采样信息,通常需要对多个子采样点的颜色值进行合并或平均,以得到最终的抗锯齿效果。

4.3 取消映射 PBO:

完成对 PBO 数据的处理后,使用 glUnmapBuffer 函数取消对 PBO 的映射,释放 CPU 对 PBO 内存的访问。

5 显示或使用抗锯齿后的图像:

5.1 将处理后的像素数据显示在屏幕上:

如果需要在屏幕上显示抗锯齿后的图像,可以使用 glDrawPixels 或其他相关的 OpenGL 函数将处理后的像素数据绘制到默认的帧缓冲中,然后通过交换缓冲区来显示在屏幕上。

5.2 保存为图像文件:

可以将处理后的像素数据保存为图像文件,以便后续使用。这可以通过使用图像库(如 stb_image 库)来实现,将像素数据写入图像文件中。

使用深度缓冲的例子

以下使用qt来做,qt的优点是很多都是封装好的,比较容易实现,不用引入额外的库,当然我们也可以使用glfw来做,后面会给出例子

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QtWidgets/QWidget>
#include <QOpenGLWidget>
#include <QOpenGLFunctions_4_5_Core>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLBuffer>
#include <QOpenGLTexture>
#include <QOpenGLShader>
#include <QOpenGLShaderProgram>
#include "ui_MainWindow.h"QT_BEGIN_NAMESPACE
namespace Ui {class CMainWindow;
}
QT_END_NAMESPACEclass CMainWindow : public QOpenGLWidget, protected QOpenGLFunctions_4_5_Core
{Q_OBJECTpublic:CMainWindow(QWidget *parent = Q_NULLPTR);~CMainWindow();void initFBO();protected:void initializeGL();void paintGL();void resizeGL(int w, int h);private:QImage m_img;GLsizei m_width = 0;GLsizei m_height = 0;GLsizeiptr m_dataSize = 0;GLuint m_VBO = 0;GLuint m_VAO = 0;GLuint m_EBO = 0;GLuint m_texture = 0;GLuint m_frameBuffer = 0;GLuint m_RBO = 0;GLuint m_fVBO = 0;GLuint m_fVAO = 0;GLuint m_textureFBO = 0;QOpenGLShaderProgram *m_programScreen = nullptr;QOpenGLShaderProgram *m_shaderProgram = nullptr;
private:Ui::CMainWindow *ui;
};
#endif //MAINWINDOW_H
#include "MainWindow.h"CMainWindow::CMainWindow(QWidget* parent): QOpenGLWidget(parent), ui(new Ui::CMainWindow)
{ui->setupUi(this);m_img = QImage("2.jpg");//picturem_width = m_img.width();m_height = m_img.height();m_dataSize = m_width * m_height * 3;
}CMainWindow::~CMainWindow()
{delete ui;glDeleteVertexArrays(1, &m_VAO);glDeleteBuffers(1, &m_VBO);glDeleteBuffers(1, &m_EBO);glDeleteVertexArrays(1, &m_fVAO);glDeleteBuffers(1, &m_fVBO);glDeleteBuffers(1, &m_frameBuffer);glDeleteBuffers(1, &m_RBO);
}
void CMainWindow::initFBO()
{glGenFramebuffers(1, &m_frameBuffer);glBindFramebuffer(GL_FRAMEBUFFER, m_frameBuffer);glGenTextures(1, &m_textureFBO);glBindTexture(GL_TEXTURE_2D, m_textureFBO);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_width, m_height, 0, GL_BGRA, GL_UNSIGNED_BYTE, nullptr);//TODOglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glBindTexture(GL_TEXTURE_2D, 0);glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_textureFBO, 0);glGenRenderbuffers(1, &m_RBO);glBindRenderbuffer(GL_RENDERBUFFER, m_RBO);glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, m_width, m_height);glBindRenderbuffer(GL_RENDERBUFFER, 0);glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_RBO);if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)qDebug() << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" ;glBindFramebuffer(GL_FRAMEBUFFER, 0);char vertexShaderSource[] ="#version 450 core\n""layout (location = 0) in vec2 aPos;\n""layout (location = 1) in vec2 aTexCoords;\n""out vec2 TexCoords;\n""void main()\n""{\n""   gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0);\n""TexCoords = aTexCoords;\n""}\n";char fragmentShaderSource[] ="#version 450 core\n""out vec4 FragColor;\n""in vec2 TexCoords;\n""uniform sampler2D screenTexture;\n""void main()\n""{\n""   FragColor = texture(screenTexture, TexCoords);\n""}\n";m_programScreen = new QOpenGLShaderProgram;m_programScreen->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);m_programScreen->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);m_programScreen->link();m_programScreen->bind();m_programScreen->setUniformValue("screenTexture", 1);m_programScreen->release();float fb_Vertices[] = {// positions   // texCoords-1.0f,  1.0f,  0.0f, 1.0f,-1.0f, -1.0f,  0.0f, 0.0f,1.0f, -1.0f,  1.0f, 0.0f,-1.0f,  1.0f,  0.0f, 1.0f,1.0f, -1.0f,  1.0f, 0.0f,1.0f,  1.0f,  1.0f, 1.0f};glGenVertexArrays(1, &m_fVAO);glBindVertexArray(m_fVAO);glGenBuffers(1, &m_fVBO);glBindBuffer(GL_ARRAY_BUFFER, m_fVBO);glBufferData(GL_ARRAY_BUFFER, sizeof(fb_Vertices), fb_Vertices, GL_STATIC_DRAW);glEnableVertexAttribArray(0);glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (void*)0);glEnableVertexAttribArray(1);glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (void*)(2 * sizeof(float)));glBindBuffer(GL_ARRAY_BUFFER, 0);glBindVertexArray(0);}void CMainWindow::initializeGL()
{this->initializeOpenGLFunctions();char vertexShaderSource[] ="#version 450 core\n""layout(location = 0) in vec3 aPos;\n""layout(location = 1) in vec3 aColor;\n""layout(location = 2) in vec2 aTexcood;\n""out vec3 vertexColor;\n""out vec2 m_tex;\n""void main()\n""{\n""   m_tex = aTexcood;\n""   vertexColor = aColor;\n""   gl_Position = vec4(aPos, 1.0);\n""}\n";char fragmentShaderSource[] ="#version 450 core\n""out vec4 FragColor;\n""in vec3 vertexColor;\n""in vec2 m_tex;\n""uniform sampler2D ourTexture;\n""void main()\n""{\n""   FragColor = texture2D(ourTexture, m_tex) * vec4(vertexColor, 1.0f);\n""}\n";m_shaderProgram = new QOpenGLShaderProgram;m_shaderProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);m_shaderProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);m_shaderProgram->link();m_shaderProgram->bind();m_shaderProgram->setUniformValue("ourTexture", 0);m_shaderProgram->release();GLfloat vertices[] = {-1.0f, -1.0f,0.0f, 0.0f,0.0f,1.0f, 0.0f,0.0f,1.0f, -1.0f,0.0f, 0.0f,1.0f,0.0f, 1.0f,0.0f,1.0f,  1.0f,0.0f, 1.0f,0.0f,0.0f, 1.0f,1.0f,-1.0f,  1.0f,0.0f, 0.0f,1.0f,1.0f, 0.0f,1.0f,};GLuint indices[] = {0,1,2,0,2,3};glGenVertexArrays(1, &m_VAO);glBindVertexArray(m_VAO);glGenBuffers(1, &m_VBO);glBindBuffer(GL_ARRAY_BUFFER, m_VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);glGenBuffers(1, &m_EBO);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_EBO);glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)0);glEnableVertexAttribArray(0);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(3 * sizeof(float)));glEnableVertexAttribArray(1);glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(6 * sizeof(float)));glEnableVertexAttribArray(2);glBindVertexArray(0);glBindBuffer(GL_ARRAY_BUFFER, 0);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);glGenTextures(1, &m_texture);glBindTexture(GL_TEXTURE_2D, m_texture);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_width, m_height, 0, GL_BGRA, GL_UNSIGNED_BYTE, m_img.bits());//TODOglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);glGenerateMipmap(GL_TEXTURE_2D);glBindTexture(GL_TEXTURE_2D, 0);//初始化FBOinitFBO();}void CMainWindow::paintGL()
{glBindFramebuffer(GL_FRAMEBUFFER, m_frameBuffer);glEnable(GL_DEPTH_TEST);glClearColor(0.5f, 0.0f, 0.0f, 1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);m_shaderProgram->bind();glBindVertexArray(m_VAO);glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, m_texture);glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL);glBindVertexArray(0);glBindTexture(GL_TEXTURE_2D, 0);m_shaderProgram->release();/********** 关键之处 ***********/GLuint fb = context()->defaultFramebufferObject();glBindFramebuffer(GL_FRAMEBUFFER, fb);glDisable(GL_DEPTH_TEST);glClearColor(1.0f, 1.0f, 1.0f, 1.0f);glClear(GL_COLOR_BUFFER_BIT);glViewport(0, 0, m_width, m_height);m_programScreen->bind();glBindVertexArray(m_fVAO);glActiveTexture(GL_TEXTURE1);glBindTexture(GL_TEXTURE_2D, m_textureFBO);glDrawArrays(GL_TRIANGLES, 0, 6);glBindVertexArray(0);glBindTexture(GL_TEXTURE_2D, 0);m_programScreen->release();}void CMainWindow::resizeGL(int w, int h)
{glViewport(0, 0, w, h);
}

qt中采集场景如图
在这里插入图片描述

下面给出glfw的例子

glfw

首先初始化 OpenGL、GLFW 和 GLEW,也可以用glad,并创建了 MSAA FBO、颜色纹理、深度 RBO 和 PBO。然后,在渲染循环中,先将场景渲染到 MSAA FBO 中,再将 FBO 中的像素数据读取到 PBO 中,并对 PBO 中的像素数据进行处理。最后,清理资源并退出程序。当然实际应用中确实需要根据具体需求进行更多的错误处理和优化。

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <cstdlib>// 窗口尺寸
const int WIDTH = 800;
const int HEIGHT = 600;// 创建 PBO
GLuint pbo;
// 创建 MSAA FBO
GLuint fbo;
// 颜色纹理
GLuint colorTexture;
// 深度 RBO
GLuint depthRBO;void init() {// 初始化 GLFWif (!glfwInit()) {std::cerr << "Failed to initialize GLFW" << std::endl;exit(EXIT_FAILURE);}// 创建窗口GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "MSAA with PBO", nullptr, nullptr);if (!window) {std::cerr << "Failed to create GLFW window" << std::endl;glfwTerminate();exit(EXIT_FAILURE);}// 将窗口设置为当前上下文glfwMakeContextCurrent(window);// 初始化 GLEWglewExperimental = GL_TRUE;if (glewInit()!= GLEW_OK) {std::cerr << "Failed to initialize GLEW" << std::endl;exit(EXIT_FAILURE);}// 开启多重采样抗锯齿glEnable(GL_MULTISAMPLE);// 创建 FBOglGenFramebuffers(1, &fbo);glBindFramebuffer(GL_FRAMEBUFFER, fbo);// 创建颜色纹理glGenTextures(1, &colorTexture);glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, colorTexture);glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, WIDTH, HEIGHT, GL_TRUE);glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, colorTexture, 0);// 创建深度 RBOglGenRenderbuffers(1, &depthRBO);glBindRenderbuffer(GL_RENDERBUFFER, depthRBO);glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, WIDTH, HEIGHT);glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthRBO);// 检查 FBO 是否完整if (glCheckFramebufferStatus(GL_FRAMEBUFFER)!= GL_FRAMEBUFFER_COMPLETE) {std::cerr << "Failed to create FBO" << std::endl;exit(EXIT_FAILURE);}// 创建 PBOglGenBuffers(1, &pbo);glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo);glBufferData(GL_PIXEL_PACK_BUFFER, WIDTH * HEIGHT * 4, nullptr, GL_STREAM_READ);
}void renderScene() {// 绑定 MSAA FBO 并渲染场景glBindFramebuffer(GL_FRAMEBUFFER, fbo);glViewport(0, 0, WIDTH, HEIGHT);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// 在这里进行场景的绘制操作// 解除绑定 FBOglBindFramebuffer(GL_FRAMEBUFFER, 0);
}void processPixels() {// 将 MSAA FBO 中的像素数据读取到 PBOglBindBuffer(GL_PIXEL_PACK_BUFFER, pbo);glReadPixels(0, 0, WIDTH, HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);// 映射 PBO 到 CPU 可访问的内存GLubyte* pixels = (GLubyte*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);if (pixels) {// 在这里处理像素数据,例如保存为图像或进行其他操作// 为了简单起见,这里只是打印一些像素信息for (int i = 0; i < 10; i++) {std::cout << "Pixel " << i << ": ("<< (int)pixels[4 * i] << ", "<< (int)pixels[4 * i + 1] << ", "<< (int)pixels[4 * i + 2] << ", "<< (int)pixels[4 * i + 3] << ")" << std::endl;}// 取消映射 PBOglUnmapBuffer(GL_PIXEL_PACK_BUFFER);}
}int main() {init();// 渲染循环while (!glfwWindowShouldClose(glfwGetCurrentContext())) {renderScene();processPixels();// 交换缓冲区并处理事件glfwSwapBuffers(glfwGetCurrentContext());glfwPollEvents();}// 清理资源glDeleteBuffers(1, &pbo);glDeleteTextures(1, &colorTexture);glDeleteRenderbuffers(1, &depthRBO);glDeleteFramebuffers(1, &fbo);glfwTerminate();return 0;
}

存文件测试

static void saveImage(GLuint& pbo, const std::string& filename, int width, int height) {glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo);// 将帧缓冲区内容读取到 PBOglReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);// 映射 PBO 获取数据指针GLubyte* pixels = (GLubyte*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);if (pixels){stbi_write_png(filename.c_str(), width, height, 4, pixels, width * 4);glUnmapBuffer(GL_PIXEL_PACK_BUFFER);}else{std::cerr << "Failed to map." << std::endl;}glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
}

如下图所示,存的图像是倒立镜像的,实际上是正立的三角形,还没有将视频附上去,工作量有些大,等到下一个文章再写。
在这里插入图片描述

相关文章:

融媒体服务中PBO进行多重采样抗锯齿(MSAA)

如果不理解pbo 那先去了解概念&#xff0c;在此不再解释&#xff0c;这是我为了做融合服务器viewpointserver做的一部分工作&#xff0c;融合服务器的功能是将三维和流媒体&#xff0c;AI融合在一起&#xff0c;viewpointserver会直接读取三维工程的文件&#xff0c;同时融合rt…...

说说BPMN概念及应用

BPMN&#xff08;Business Process Modeling and Notation&#xff09;即业务流程建模与标注&#xff0c;是一种由OMG&#xff08;Object Management Group&#xff0c;对象管理组织&#xff09;制定的业务流程建模语言。以下是对BPMN标准的详细解释&#xff1a; 一、BPMN的起…...

【微服务】初识(day1)

基础概念 集群 集群是将一个系统完整的部署到多个服务器&#xff0c;每个服务器提供系统的所有服务&#xff0c;多个服务器可以通过负载均衡完成任务&#xff0c;每个服务器都可以称为集群的节点。 分布式 分布式是将一个系统拆分为多个子系统&#xff0c;多个子系统部署在…...

15分钟学 Python 第40天:Python 爬虫入门(六)第一篇

Day40 &#xff1a;Python 爬取豆瓣网前一百的电影信息 1. 项目背景 在这个项目中&#xff0c;我们将学习如何利用 Python 爬虫技术从豆瓣网抓取前一百部电影的信息。通过这一练习&#xff0c;您将掌握网页抓取的基本流程&#xff0c;包括发送请求、解析HTML、存储数据等核心…...

分层解耦-05.IOCDI-DI详解

一.依赖注入的注解 在我们的项目中&#xff0c;EmpService的实现类有两个&#xff0c;分别是EmpServiceA和EmpServiceB。这两个实现类都加上Service注解。我们运行程序&#xff0c;就会报错。 这是因为我们依赖注入的注解Autowired默认是按照类型来寻找bean对象的进行依赖注入…...

HCIP-HarmonyOS Application Developer 习题(六)

&#xff08;多选&#xff09;1、Harmonyos多窗口交互能力提供了以下哪几种交互方式? A. 平行视界 B.全局消息通知 C.分屏 D.悬浮窗 答案&#xff1a;ACD 分析&#xff1a;系统提供了悬浮窗、分屏、平行视界三种多窗口交互&#xff0c;为用户在大屏幕设备上的多任务并行、便捷…...

【电路基础 · 3】实际电压源 实际电流源;两种电源的等效情况;戴维南模型 诺顿模型(自用)

总览 1.实际电源的两种模型和它们的等效变换 2.两种电源的等效情况 3.戴维南模型 && 诺顿模型 一、实际电源的两种模型和它们的等效变换 1.实际电压源 实际电压源不允许短路。因为它的内阻太小&#xff0c;如果短路&#xff0c;电流很大&#xff0c;可能会烧毁电源…...

案例-猜数字游戏

文章目录 效果展示初始画面演示视频 代码区 效果展示 初始画面 演示视频 猜数字游戏 代码区 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width,…...

POI数据的处理与分析

POI概念 POI&#xff08;Point of Interest&#xff0c;兴趣点&#xff09;数据指的是地理空间数据中的一类&#xff0c;表示某一具体地点或位置的信息。通常&#xff0c;这些数据包含位置坐标&#xff08;经纬度&#xff09;、名称、地址、类别和其他相关信息。POI 数据广泛应…...

ansible部分模块学习

ansible模块学习 copy模块 copy模块srcsource 源⽂件destdestination ⽬标backupbackupyes 则会在覆盖前进⾏备份mode修改权限owner修改为指定所有者group修改为指定⽤户组 案例1&#xff1a;传输/root/work/scripts/net-tools-install.sh⽂件到/opt/net-tools-install.sh …...

数据库(MySQL):使用命令从零开始在Navicat创建一个数据库及其数据表(二).设置主键自增等特点

前言 在上一节中&#xff0c;主要介绍了 Navicat Premium 17 的使用以及创建一个基础的表格。当时只设置了给数据表补充字段&#xff0c;没有设置给数据表删除字段。现在补充一下。 ALTER TABLE student ADD test int(4); 给名为 student 的数据表添加 test 列&#xf…...

SQL第13课——创建高级联结

本课讲另外一些联结&#xff08;含义和使用方法&#xff09;&#xff0c;如何使用表别名&#xff0c;如何对被联结的表使用聚集函数。 13.1 使用表别名 第7课中使用别名引用被检索的表列&#xff0c;给列起别名的语法如下&#xff1a; SQL除了可以对列名和计算字段使用别名&a…...

订阅ROS2中相机的相关话题并保存RGB、深度和点云图

系统&#xff1a;Ubuntu22.04 ROS2版本&#xff1a;ROS2 humble 1.订阅ROS2中相机的相关话题并保存RGB图、深度图和点云图 ros2 topic list/stellar_1/rgb/image_raw /camera/depth/image_raw /stellar_1/points2CMakeLists.txt cmake_minimum_required(VERSION 3.15) projec…...

Open WebUI | 自托管的类 ChatGPT 网站

Open WebUI 是一个扩展性强、功能丰富且用户友好的自托管 WebUI&#xff0c;旨在完全离线操作。它支持各种 LLM 服务&#xff0c;包括 Ollama 和 OpenAI 兼容的 API。该项目在 GitHub 上已有 38k 星&#xff0c;非常受欢迎。 功能介绍 废话不多说&#xff0c;上图&#xff01;…...

【Python】Python知识总结浅析

Python是一种高级编程语言&#xff0c;由Guido van Rossum于1991年首次发布。它以简洁的语法和强大的功能著称&#xff0c;适用于多种应用场景&#xff0c;包括Web开发、数据分析、人工智能、自动化脚本等。 易于学习和使用&#xff1a;Python的语法简洁明了&#xff0c;适合初…...

c#代码介绍23种设计模式_20策略者模式

目录 1、策略模式的定义 2、策略模式的结构 3、涉及到三个角色: 4、策略者模式在.NET中应用 5、策略者模式的适用场景 6、策略者模式的优缺点 7、实现思路 在现实生活中,策略模式的例子也非常常见,例如,中国的所得税,分为企业所得税、外商投资企业或外商企业所得税…...

FPGA-UART串口接收模块的理解

UART串口接收模块 背景 在之前就有写过关于串口模块的文章——《串口RS232的学习》。工作后很多项目都会用到串口模块&#xff0c;又来重新理解一下FPGA串口接收的代码思路。 关于串口相关的参数&#xff0c;以及在文章《串口RS232的学习》中已有详细的描述&#xff0c;这里就…...

复习HTML(基础)

目录 HTML含义 HTML作用 HTML的常用元素 元素的特点 元素的分类 1 是否嵌套关系 2 是否独占一行 块元素&#xff1a;独占一行 行内元素&#xff1a;共享一行 行内元素与块级元素的转换 3是否有结束标签 常用标签 1 标题标签&#xff1a;有六级 我们用h1 ~h6 表…...

Linux聊天集群开发之环境准备

一.windows下远程操作Linux 第一步&#xff1a;在Linux终端下配置openssh&#xff0c;输入netstate -tanp,查看ssh服务是否启动&#xff0c;默认端口22.。 注&#xff1a;如果openssh服务&#xff0c;则需下载。输入命令ps -e|grep ssh, 查看如否配有&#xff0c; ssh-agent …...

can 总线入门———can简介硬件电路

文章目录 0. 前言1. CAN简介2. 主流通讯协议对比3. CAN 硬件电路4. CAN 电平标准5. CAN 收发器 0. 前言 博客内容来自B站上CAN总线入门教程视频讲解&#xff0c;博客中的插图和内容均为视频中的内容。视频链接 CAN总线入门教程 1. CAN简介 先来看看一它名字的意思&#xff0c…...

【重学 MySQL】六十、空间类型

【重学 MySQL】六十、空间类型 空间数据类型的分类空间数据类型的属性空间数据的表示方式空间数据的操作应用场景 在MySQL中&#xff0c;空间类型&#xff08;Spatial Types&#xff09;主要用于支持地理特征的生成、存储和分析。这些地理特征可以表示世界上具有位置的任何东西…...

python实现DES算法

DES算法 一、算法介绍1.1 背景1.2 原理1.3 基本功能函数1.3.1 初始置换函数 I P IP IP1.3.2 f f f 轮函数1.3.3 逆初始置换函数 I P − 1 IP^{-1} IP−1 1.4 子密钥的生成 二、代码实现2.1 子密钥生成实现2.2 DES加解密实现2.3 完整代码 三、演示效果 一、算法介绍 1.1 背景…...

基于LORA的一主多从监测系统_框架搭建

第一节、框架搭建 打开CubeMAX&#xff0c;选择好芯片&#xff0c;进行基础配置 第一步、先配置时钟源 第二步、配置SYS选项 配置debug口以及计数器源&#xff0c;我这里选择TIM1 第三步、选择I2C接口 配置如下即可&#xff0c;默认配置不用改 第四步、串口选择 我们这里使…...

优化理论及应用精解【25】

文章目录 优化学习率调度1. 阶梯衰减&#xff08;Step Decay&#xff09;2. 余弦退火&#xff08;Cosine Annealing&#xff09;3. 多项式衰减&#xff08;Polynomial Decay&#xff09;4. 指数衰减&#xff08;Exponential Decay&#xff09;总结 梯度弥散效应 参考文献 优化 …...

贝锐蒲公英网盘首发,秒建私有云,高速远程访问

虽然公共网盘带来了不少便利&#xff0c;但是大家对隐私泄露和重要数据泄密的担忧也随之增加。如果想要确保数据安全&#xff0c;自建私有云似乎是一条出路&#xff0c;然而面对搭建私有云的复杂步骤&#xff0c;许多人感到力不从心&#xff0c;NAS设备的成本也往往让人望而却步…...

[ 蓝桥 ·算法双周赛 ] 第 19 场 小白入门赛

&#x1f525;博客介绍&#xff1a; EvLast &#x1f3a5;系列专栏&#xff1a; <<数据结构与算法>> << 算法入门>> << C项目>> &#x1f3a5; 当前专栏: << 算法入门>> 专题 : 帮助小白快速入门算法竞赛 &#x1f44d…...

HTML+CSS基础 第二季课堂笔记

一、列表 列表都不是单打独斗的&#xff0c;通常都是一组标签组成 1 无序列表 作用&#xff1a;定义一个没有顺序的列表结构 由两个标签组成&#xff0c;ul&#xff08;容器级标签&#xff09;&#xff0c;li&#xff08;容器级&#xff09; ul&#xff1a;英文ulordered …...

【Easy RL】Easy RL蘑菇书全书学习笔记

【Easy RL】Easy RL蘑菇书全书学习笔记 第一章 强化学习基础1.1 强化学习概述监督学习强化学习与监督学习的不同之处二者的区别总结强化学习的特征强化学习的优越性预演&#xff08;rollout&#xff09;和 轨迹&#xff08;trajectory&#xff09;的概念端到端的概念深度强化学…...

JavaWeb(二)

Servlet开发技术 [外链图片转存中…(img-Cnu8X2V4-1728026684827)] 简述Servlet的创建过程&#xff1f; package servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; …...

【C++】--类和对象(2)

&#x1f44c;个人主页: 起名字真南 &#x1f446;个人专栏:【数据结构初阶】 【C语言】 【C】 目录 1 类的默认成员函数2 构造函数3 析构函数4 拷贝构造5 赋值运算符重载5.1 运算符重载5.2 赋值运算符的重载 1 类的默认成员函数 默认成员函数就是用户没有显示实现&#xff0c;…...