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

利用 Open3D 保存并载入相机视角的简单示例

1. 前言

在使用 Open3D 进行三维可视化和点云处理时,有时需要将当前的视角(Camera Viewpoint)保存下来,以便下次再次打开时能够还原到同样的视角。本文将演示如何在最新的 Open3D GUI 界面(o3d.visualization.gui / o3d.visualization.O3DVisualizer)中实现这一功能,并展示完整示例代码及运行效果。

2. 环境准备

  • Python 版本:3.x
  • Open3D 版本:0.15+ 或 0.16+(支持新的 GUI)
  • 其他依赖:Numpy

如果你使用的是 pip 安装,确保安装最新的 Open3D:

pip install --upgrade open3d

3. 实现思路

在 Open3D 中,相机视角主要由**内参(Intrinsic)外参(Extrinsic)**两个部分组成。

  • 内参(Intrinsic):描述相机的焦距(fx, fy)和主点坐标(cx, cy)。
  • 外参(Extrinsic):描述世界坐标系到相机坐标系的变换关系,包含旋转和平移。

由于 Open3D 内部在新的 GUI 中使用了 OpenGL 风格的坐标系,因此需要进行一次坐标变换。文中使用了一个 ToGLCamera 矩阵与其逆矩阵来做坐标系之间的转换。

当我们在 O3DVisualizer 中查看点云并进行旋转、平移等操作时,可以通过 vis.scene.camera.get_model_matrix() 获取到对应的模型矩阵(model matrix),然后再转换为外参矩阵(extrinsic)。最后,我们把这些参数序列化(用 pickle)存储起来,之后就可以再读取并还原相机的视角。

4. 关键函数解析

4.1 model_matrix_to_extrinsic_matrix(model_matrix)

def model_matrix_to_extrinsic_matrix(model_matrix):return np.linalg.inv(model_matrix @ FromGLGamera)
  • 这里 model_matrix 来自 vis.scene.camera.get_model_matrix()
  • 由于 Open3D GUI 中的相机使用了与传统坐标系不同的变换,需要先右乘一个 FromGLGameraToGLCamera 的逆)矩阵,然后对结果取逆,才能得到最终的外参矩阵。

4.2 create_camera_intrinsic_from_size(width, height, hfov, vfov)

def create_camera_intrinsic_from_size(width=1024, height=768, hfov=60.0, vfov=60.0):fx = (width / 2.0) / np.tan(np.radians(hfov)/2)fy = (height / 2.0) / np.tan(np.radians(vfov)/2)return np.array([[fx, 0, width / 2.0],[0, fy, height / 2.0],[0, 0,  1]])
  • 该函数根据窗口的宽度 width、高度 height 以及水平和垂直视角(hfov, vfov)来计算焦距。
  • 其中 (width / 2) / tan(hfov / 2) 的含义是根据给定视场角和图像尺寸来估计相机焦距。
  • 最终返回一个 3×3 的内参矩阵。

4.3 save_view(vis, fname='saved_view.pkl')

def save_view(vis, fname='saved_view.pkl'):try:model_matrix = np.asarray(vis.scene.camera.get_model_matrix())extrinsic = model_matrix_to_extrinsic_matrix(model_matrix)width, height = vis.size.width, vis.size.heightintrinsic = create_camera_intrinsic_from_size(width, height)saved_view = dict(extrinsic=extrinsic, intrinsic=intrinsic, width=width, height=height)with open(fname, 'wb') as pickle_file:dump(saved_view, pickle_file)except Exception as e:print(e)
  • 获取当前相机的模型矩阵并转换成外参矩阵 extrinsic
  • 读取当前窗口大小,计算内参矩阵 intrinsic
  • 将外参、内参、窗口大小一起打包到一个字典 saved_view 里并用 pickle 序列化保存到文件。

4.4 load_view(vis, fname="saved_view.pkl")

def load_view(vis, fname="saved_view.pkl"):try:with open(fname, 'rb') as pickle_file:saved_view = load(pickle_file)vis.setup_camera(saved_view['intrinsic'], saved_view['extrinsic'],saved_view['width'], saved_view['height'])except Exception as e:print("Can't find file", e)
  • 反序列化读取之前保存的 intrinsicextrinsic 和窗口大小信息。
  • 调用 vis.setup_camera(...) 还原相机视角。
    点击Action按钮,即可导出或载入视角

5. 完整示例代码

下面贴出完整的示例代码,供参考(假设文件名为 demo_save_load_view.py)。代码中已经包含了上述四个关键函数,并演示了如何加载点云、如何在 GUI 中添加菜单项来保存/加载视角,以及如何在程序启动后自动加载之前保存的视角并截图保存。

import numpy as np
import open3d as o3d
import open3d.visualization.gui as gui
from pickle import load, dumpToGLCamera = np.array([[1,  0,  0,  0],[0, -1,  0,  0],[0,  0, -1,  0],[0,  0,  0,  1]
])
FromGLGamera = np.linalg.inv(ToGLCamera)def model_matrix_to_extrinsic_matrix(model_matrix):return np.linalg.inv(model_matrix @ FromGLGamera)def create_camera_intrinsic_from_size(width=1024, height=768, hfov=60.0, vfov=60.0):fx = (width / 2.0) / np.tan(np.radians(hfov)/2)fy = (height / 2.0) / np.tan(np.radians(vfov)/2)return np.array([[fx, 0, width / 2.0],[0, fy, height / 2.0],[0, 0,  1]])def save_view(vis, fname='saved_view.pkl'):try:model_matrix = np.asarray(vis.scene.camera.get_model_matrix())extrinsic = model_matrix_to_extrinsic_matrix(model_matrix)width, height = vis.size.width, vis.size.heightintrinsic = create_camera_intrinsic_from_size(width, height)saved_view = dict(extrinsic=extrinsic, intrinsic=intrinsic, width=width, height=height)with open(fname, 'wb') as pickle_file:dump(saved_view, pickle_file)print(f"View saved to {fname}")except Exception as e:print(e)def load_view(vis, fname="saved_view.pkl"):try:with open(fname, 'rb') as pickle_file:saved_view = load(pickle_file)vis.setup_camera(saved_view['intrinsic'], saved_view['extrinsic'],saved_view['width'], saved_view['height'])print(f"View loaded from {fname}")except Exception as e:print("Can't find file", e)def main():gui.Application.instance.initialize()vis = o3d.visualization.O3DVisualizer("Demo to Load a Camera Viewpoint for O3DVisualizer", 1920, 1080)# 添加窗口gui.Application.instance.add_window(vis)# 设置一些可视化参数vis.point_size = 8vis.show_axes = True# 在菜单中添加保存和加载相机视角的选项vis.add_action("Save Camera View", save_view)vis.add_action("Load Camera View", load_view)# 调整一些可视化效果vis.point_size = 4          vis.show_axes = False       vis.show_skybox(False)# 读取并添加点云到可视化pcd = o3d.io.read_point_cloud('/10.pcd')vis.add_geometry("Random Point Cloud", pcd)# 延迟加载视角def load_view_delayed():load_view(vis, 'saved_view.pkl')gui.Application.instance.post_to_main_thread(vis, load_view_delayed)# 延迟一秒后截图def take_screenshot():import timetime.sleep(1)  vis.export_current_image("screenshot.png")print("Screenshot saved to screenshot.png")gui.Application.instance.post_to_main_thread(vis, take_screenshot)gui.Application.instance.run()if __name__ == "__main__":main()

6. 使用方法

  1. 确保安装好 Open3D(最好是最新版本),并将上面的代码保存为 demo_save_load_view.py
  2. 修改点云文件路径:将 pcd = o3d.io.read_point_cloud('/path/to/your.pcd') 替换为你自己的点云文件路径。
  3. 运行脚本:
    python demo_save_load_view.py
    
  4. 首次运行时,如果本地没有 saved_view.pkl 文件,会提示找不到文件;你可以手动在菜单里选择 Actions -> Save Camera View 来保存当前视角。
  5. 下次再运行脚本时,程序会自动执行 load_view_delayed(),从上次保存的 saved_view.pkl 中加载相机视角,并在 1 秒后截图。

7. 总结

通过本文示例,我们可以看到,在新的 Open3D GUI(O3DVisualizer)中,保存并还原相机视角的核心思路就是:

  1. 获取当前相机的 model_matrix
  2. 结合一个与 OpenGL 坐标系相关的转换矩阵,计算出外参;
  3. 根据窗口大小和视场角,生成内参;
  4. 将这些数据保存到文件,日后可以轻松加载还原相机视角。

这样就能方便地在多次打开程序或者不同机器上还原同一个观察视角。希望这篇文章能给你在使用 Open3D 的项目中带来帮助。

相关文章:

利用 Open3D 保存并载入相机视角的简单示例

1. 前言 在使用 Open3D 进行三维可视化和点云处理时,有时需要将当前的视角(Camera Viewpoint)保存下来,以便下次再次打开时能够还原到同样的视角。本文将演示如何在最新的 Open3D GUI 界面(o3d.visualization.gui / o…...

kiln微调大模型-使用deepseek R1去训练一个你的具备推理能力的chatGPT 4o

前言 随着deepseek的爆火,对于LLM的各种内容也逐渐步入我的视野,我个人认为,可能未来很长一段时间,AI将持续爆火,进入一段时间的井喷期,AI也会慢慢的走入我们每个家庭之中,为我们的生活提供便利…...

《从Kokoro看开源语音模型的“无限可能”》:此文为AI自动生成

开源语音模型 Kokoro 是一款轻量级、高性能的文本转语音(TTS)模型,以下是关于它的详细介绍: 核心优势 卓越的音质:即使参数规模仅 8200 万,也能生成自然流畅、富有表现力的语音。轻量高效:占用资源少,运行速度快,在 CPU 上即可实现近乎实时的语音生成,在 GPU 端则能…...

Spring 事务和事务传播机制(详解)

1 .事务 1.1.什么是事务? 事务是一组操作的集合,是不可分割的操作 事务作为一个整体,要不同时完成,要不同时失败 1.2什么时候需要事务? 关于金钱的操作基本都会有事务 例如转账操作: 第一步 A账号 - 500元第二步 B账…...

Innodb MVCC实现原理

什么是MVCC? MVCC全称多版本并发控制,是在并发访问数据库时对操作数据做多版本管理,避免因为写数据时要加写锁而阻塞读取数据的请求问题。 Innodb对mvcc的实现 1、事务版本号 每次事务开启前都会从数据库获得一个自增长的事务ID,可以从事…...

【网络编程】网络套接字和使用案例

一、为什么大多数网络编程使用套接字 在网络编程中,套接字 (socket) 是最常用的接口,但并不是所有的底层通信都依赖于套接字。尽管如此,绝大多数网络应用(特别是在操作系统层面)都使用套接字进行通信,因为…...

【Java企业生态系统的演进】从单体J2EE到云原生微服务

Java企业生态系统的演进:从单体J2EE到云原生微服务 目录标题 Java企业生态系统的演进:从单体J2EE到云原生微服务摘要1. 引言2. 整体框架演进:从原始Java到Spring Cloud2.1 原始Java阶段(1995-1999)2.2 J2EE阶段&#x…...

【爬虫基础】第二部分 爬虫基础理论 P1/3

上节内容回顾:【爬虫基础】第一部分 网络通讯 P1/3-CSDN博客 【爬虫基础】第一部分 网络通讯-Socket套接字 P2/3-CSDN博客 【爬虫基础】第一部分 网络通讯-编程 P3/3-CSDN博客 爬虫相关文档,希望互相学习,共同进步 风123456789&#xff…...

第2章_保护您的第一个应用程序

第2章_保护您的第一个应用程序 在本章中,您将学习如何使用 Keycloak 保护您的第一个应用程序。为了让事情更有趣,您将运行的示例应用程序由两部分组成,前端 Web 应用程序和后端 REST API。这将向您展示用户如何向前端进行身份验证&#xff0…...

山东大学软件学院人工智能导论实验之知识库推理

目录 实验目的: 实验代码: 实验内容: 实验结果 实验目的: 输入相应的条件,根据知识库推理得出相应的知识。 实验代码: def find_data(input_process_data_list):for epoch, data_process in enumerat…...

Java 网络协议面试题答案整理,最新面试题

TCP和UDP的主要区别是什么? TCP(传输控制协议)和UDP(用户数据报协议)的主要区别在于TCP是面向连接的协议,而UDP是无连接的协议。这导致了它们在数据传输方式、可靠性、速度和使用场景方面的不同。 1、连接…...

win10把c盘docker虚拟硬盘映射迁移到别的磁盘

c盘空间本身就比较小、如果安装了docker服务后,安装的时候没选择其他硬盘,虚拟磁盘也在c盘会占用很大的空间,像我的就三十多个G,把它迁移到其他磁盘一下子节约几十G 1、先输入下面命令查看 docker 状态 wsl -l -v 2、如果没有停止…...

AOP进阶-02.通知顺序

一.通知顺序 当有多个切面类中的切入点表达式一样时,这些切面类的执行顺序是怎样的呢?如图我们将定义两个切面类,一个MyAspect2,一个MyAspect3,一个MyAspect4。执行后我们发现, 对于目标方法前的通知方法&…...

${sym} 与 String(sym) 的区别

在 JavaScript 中,${sym}(模板字符串插值)和 String(sym)(显式类型转换)虽然都涉及将值转换为字符串,但它们的底层逻辑和行为存在显著差异,尤其是在处理 Symbol 等特殊类型时。以下是具体对比&a…...

sglang框架源码笔记

文章目录 整体架构1. **客户端(Client)**:2. **服务器端(Server)**:3. **调度器与模型工作节点(Scheduler & Model Worker)**: TpModelWorker类ModelRunner类TpModel…...

2025年SCI一区智能优化算法:混沌进化优化算法(Chaotic Evolution Optimization, CEO),提供MATLAB代码

一、混沌进化优化算法 https://github.com/ITyuanshou/MATLABCode 1. 算法简介 混沌进化优化算法(Chaotic Evolution Optimization, CEO)是2025年提出的一种受混沌动力学启发的新型元启发式算法。该算法的主要灵感来源于二维离散忆阻映射的混沌进化过…...

uake 网络安全 reverse网络安全

🍅 点击文末小卡片 ,免费获取网络安全全套资料,资料在手,涨薪更快 本文首发于“合天网安实验室” 首先从PEID的算法分析插件来介绍,要知道不管是在CTF竞赛的REVERSE题目中,还是在实际的商业产品中&#xf…...

C语言实现单链表

单链表是数据结构中最基础的链式结构,它不按照线性的顺序存储数据,而是由若干个同一结构类型的“节点”依次串联而成的,即每一个节点里保存着下一个节点的地址(指针)。 上图中,一个表头变量head是用来存储链表首节点的地址,链表中每个节点有data(数据)部分和n…...

Rk3568驱动开发_点亮led灯代码完善(手动挡)_6

1.实现思路: 应用层打开设备后通过write函数向内核中写值,1代表要打开灯,0代表要关闭灯 Linux配置gpio和控制gpio多了一个虚拟内存映射操作 2.注意事项: 配置和读写操作的时候要谨慎,比如先关掉gpio再注销掉虚拟内存…...

threejs:document.createElement创建标签后css设置失效

vue3threejs,做一个给模型批量CSS2D标签的案例,在导入模型的js文件里,跟着课程写的代码如下: import * as THREE from three; // 引入gltf模型加载库GLTFLoader.js import { GLTFLoader } from three/addons/loaders/GLTFLoader.…...

在 compare-form.vue 中添加 compareDate 隐藏字段,并在提交时自动填入当前时间

在 compare-form.vue 中添加 compareDate 隐藏字段,并在提交时自动填入当前时间。 提交表单时存入的对象是FakeRegistration,这个对象里面有compareDate字段,刚好表格查询的对象也是FakeRegistration,所以表格展示的时间就是刚才…...

使用DeepSeek/ChatGPT等AI工具辅助编写wireshark过滤器

随着deepseek,chatgpt等大模型的能力越来越强大,本文将介绍借助deepseek,chatgpt等大模型工具,通过编写提示词,辅助生成全面的Wireshark显示过滤器的能力。 每一种协议的字段众多,流量分析的需求多种多样,…...

Java 大视界 -- Java 大数据在智能物流路径规划与车辆调度中的创新应用(102)

💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…...

YOLOv12 ——基于卷积神经网络的快速推理速度与注意力机制带来的增强性能结合

概述 实时目标检测对于许多实际应用来说已经变得至关重要,而Ultralytics公司开发的YOLO(You Only Look Once,只看一次)系列一直是最先进的模型系列,在速度和准确性之间提供了稳健的平衡。注意力机制的低效阻碍了它们在…...

一个行为类似标准库find算法的模板

函数需要两个模板类型参数&#xff0c;一个表示函数的迭代器参数&#xff0c;另一个表示值的类型。 代码 #include<iostream> #include<string> #include<vector> #include<list>using namespace std;template <typename IterType,typename T>…...

LLC谐振变换器恒压恒流双竞争闭环simulink仿真

1.模型简介 本仿真模型基于MATLAB/Simulink&#xff08;版本MATLAB 2017Ra&#xff09;软件。建议采用matlab2017 Ra及以上版本打开。&#xff08;若需要其他版本可联系代为转换&#xff09;针对全桥LLC拓扑&#xff0c;利用Matlab软件搭建模型&#xff0c;分别对轻载&#xf…...

Elasticsearch 的分布式架构原理:通俗易懂版

Elasticsearch 的分布式架构原理&#xff1a;通俗易懂版 Lucene 和 Elasticsearch 的前世今生 Lucene 是一个功能强大的搜索库&#xff0c;提供了高效的全文检索能力。然而&#xff0c;直接基于 Lucene 开发非常复杂&#xff0c;即使是简单的功能也需要编写大量的 Java 代码&…...

[深度学习]基于C++和onnxruntime部署yolov12的onnx模型

基于C和ONNX Runtime部署YOLOv12的ONNX模型&#xff0c;可以遵循以下步骤&#xff1a; 准备环境&#xff1a;首先&#xff0c;确保已经下载后指定版本opencv和onnruntime的C库。 模型转换&#xff1a; 安装好yolov12环境并将YOLOv12模型转换为ONNX格式。这通常涉及使用深度学习…...

seacmsv9报错注入

1、seacms的介绍 ​ seacms中文名&#xff1a;海洋影视管理系统。是一个采用了php5mysql架构的影视网站框架&#xff0c;因此&#xff0c;如果该框架有漏洞&#xff0c;那使用了该框架的各个网站都会有相同问题。 2、源码的分析 漏洞的部分源码如下&#xff1a; <?php …...

剑指 Offer II 033. 变位词组

comments: true edit_url: https://github.com/doocs/leetcode/edit/main/lcof2/%E5%89%91%E6%8C%87%20Offer%20II%20033.%20%E5%8F%98%E4%BD%8D%E8%AF%8D%E7%BB%84/README.md 剑指 Offer II 033. 变位词组 题目描述 给定一个字符串数组 strs &#xff0c;将 变位词 组合在一起…...

【2025全网最新最全】前端Vue3框架的搭建及工程目录详解

文章目录 安装软件Node.js搭建Vue工程创建Vue工程精简Vue项目文件 Vue工程目录的解读网页标题的设置设置全局样式路由配置 安装软件Node.js 下载地址&#xff1a;https://nodejs.org/zh-cn/ 安装完成后&#xff0c;打开cmd,查看环境是否准备好 node -v npm -vnpm使用之前一定…...

前缀和专题练习 ——基于罗勇军老师的《蓝桥杯算法入门C/C++》

目录 一、0求和 - 蓝桥云课 算法代码&#xff1a; 代码思路概述 代码详细解释 数组定义 输入读取 前缀和计算部分 结果计算部分 输出结果 程序结束 总结 二、1.可获得的最小取值 - 蓝桥云课 算法代码&#xff1a; 代码思路概述 详细代码逻辑解释 输入初始化 …...

1.测试策略与计划设计指南

1.介绍 1.1项目介绍 完整项目组成&#xff1a;1.基于K8S定制开发的SaaS平台&#xff1b;2.多个团队提供的中台服务(微服务)&#xff1b;3.多个业务团队开发的系统平台。涉及多个项目团队、上百个微服务组件。 测试在所有团队开发测试后&#xff0c;自己搭建测试环境&#xff0c…...

pikachu

暴力破解 基于表单的暴力破解 【2024版】最新BurpSuit的使用教程&#xff08;非常详细&#xff09;零基础入门到精通&#xff0c;看一篇就够了&#xff01;让你挖洞事半功倍&#xff01;_burpsuite使用教程-CSDN博客 登录页面&#xff0c;随意输入抓包&#xff0c;发送到攻击…...

HDFS扩缩容及数据迁移

1.黑白名单机制 在HDFS中可以通过黑名单、白名单机制进行节点管理&#xff0c;决定数据可以复制/不可以复制到哪些节点。 黑名单通常是指在HDFS中被标记为不可用或不可访问的节点列表&#xff0c;这些节点可能由于硬件故障、网络问题或其他原因而暂时或永久性地无法使用。当一…...

设计模式-(状态模式,策略模式,代理模式,责任链模式)

状态模式 概念&#xff1a; 用于管理一个对象在不同状态下的行为变化。它允许对象在内部状态改变时改变其行为&#xff0c;从而让对象看起来像是改变了其类。状态模式的核心思想是将状态封装到独立的类中&#xff0c;每个状态类都定义了在该状态下对象的行为 状态模式主要涉…...

二、IDE集成DeepSeek保姆级教学(使用篇)

各位看官老爷好&#xff0c;如果还没有安装DeepSeek请查阅前一篇 一、IDE集成DeepSeek保姆级教学(安装篇) 一、DeepSeek在CodeGPT中使用教学 1.1、Edit Code 编辑代码 选中代码片段 —> 右键 —> CodeGPT —> Edit Code, 输入自然语言可编辑代码&#xff0c;点击S…...

通义灵码插件安装入门教学 - IDEA(安装篇)

在开发过程中&#xff0c;使用合适的工具和插件可以极大地提高我们的工作效率。今天&#xff0c;我们将详细介绍如何在 IntelliJ IDEA 中安装并配置通义灵码插件&#xff0c;这是一款旨在提升开发者效率的实用工具。无论你是新手还是有经验的开发者&#xff0c;本文都将为你提供…...

每天一个Flutter开发小项目 (4) : 构建收藏地点应用 - 深入Flutter状态管理

引言 欢迎回到 每天一个Flutter开发小项目 系列博客!在前三篇博客中,我们从零开始构建了计数器应用、待办事项列表应用,以及简易天气应用。您不仅掌握了 Flutter 的基础组件和布局,还学习了网络请求、JSON 解析等实用技能,更重要的是,我们一起探讨了高效的 Flutter 学习…...

qt-C++笔记之QtCreator新建项目即Create Project所提供模板的逐个尝试

qt-C笔记之QtCreator新建项目即Create Project所提供模板的逐个尝试 code review! 文章目录 qt-C笔记之QtCreator新建项目即Create Project所提供模板的逐个尝试1.Application(Qt):Qt Widgets Application1.1.qmake版本1.2.cmake版本 2.Application(Qt):Qt Console Applicati…...

【NestJS系列】安装官方nestjs CLI 工具

环境搭建指南:从零开始创建 NestJS 项目 一、工具准备 1. 安装 Node.js 环境 推荐使用 LTS 版本(目前 20.x 以上)验证安装:终端执行 node -v 和 npm -vNode.js 官网下载2. 包管理器选择 这里选用更高效的 pnpm,你也可选择 npm 或 yarn # 安装 pnpm npm install -g pnp…...

【Springboot知识】Logback从1.2.x升级到1.3.x需要注意哪些点?

文章目录 **1. 确认依赖版本**示例依赖配置&#xff08;Maven&#xff09;&#xff1a; **2. 处理 StaticLoggerBinder 的移除**解决方案&#xff1a; **3. 修改日志配置文件**示例 logback.xml 配置&#xff1a; **4. 检查兼容性问题**Spring Boot 2.x 的兼容性解决方案&#…...

【Linux C | 时间】localtime 的介绍、死机、死锁问题以及 localtime_r 函数的时区问题

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…...

每日一题——LRU缓存机制的C语言实现详解

LRU缓存机制的C语言实现详解 参考1. 数据结构设计双向链表节点哈希表节点哈希表LRU缓存结构 2. 初始化哈希表和双向链表哈希函数初始化哈希表初始化双向链表创建LRU缓存 3. 更新双向链表4. 实现Get操作5. 实现Put操作更新节点值删除最久未使用节点插入或更新节点 6. 释放缓存释…...

虚函数表和虚函数表指针

1.虚函数表什么时候生成&#xff1f; 编译器编译的时候生成 2.虚函数表存放在哪里&#xff1f; 讨论两种情况&#xff1a;在磁盘&#xff08;可执行程序&#xff09;、在内存&#xff08;运行状态&#xff09; 3.虚函数表与虚函数表指针的关系 每个类只有一个虚函数&#x…...

计算机毕业设计SpringBoot+Vue.js图书进销存管理系统(源码+文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

3-2 WPS JS宏 工作簿的打开与保存(模板批量另存为工作)学习笔记

************************************************************************************************************** 点击进入 -我要自学网-国内领先的专业视频教程学习网站 *******************************************************************************************…...

大白话Vuex 核心概念(state、mutations、actions)的使用案例与原理

大白话Vuex 核心概念&#xff08;state、mutations、actions&#xff09;的使用案例与原理 Vuex是Vue.js应用程序中专门用来管理状态的工具&#xff0c;就好像是一个大管家&#xff0c;帮你把项目里一些重要的数据和操作管理得井井有条。下面用大白话结合案例来介绍Vuex核心概…...

【学写LibreCAD】1 LibreCAD主程序

一、源码 头文件&#xff1a; #ifndef MAIN_H #define MAIN_H#include<QStringList>#define STR(x) #x #define XSTR(x) STR(x)/*** brief handleArgs* param argc cli argument counter from main()* param argv cli arguments from main()* param argClean a list…...

CentOS7最小化安装中使用curl安装yum和wget

在 CentOS 7 最小化安装中&#xff0c;如果已经有curl工具&#xff0c;可以按照以下步骤使用它来安装yum和wget&#xff1a; 1. 备份原有的 yum 源配置文件 为了避免配置冲突或后续需要恢复&#xff0c;先备份原有的yum源配置文件。 mv /etc/yum.repos.d/CentOS-Base.repo /…...