一文(10图)了解Cornerstone3D核心概念(万字总结附导图)

news2024/11/24 13:05:47

Cornerstone3D介绍

Cornerstone3D是一个专门为处理三维医学影像而设计的JavaScript库。

它是Cornerstone项目的一部分,旨在为医学影像社区提供高性能、可扩展且易于使用的开源Web工具,专注于提供交互式的3D医学图像浏览体验,适用于多种医学影像格式。

特性

  • 健壮的DICOM解析:能够处理和显示各种3D医学影像格式,如CT、MRI和PET扫描等,支持Dicom格式、NifTi格式的影像加载

  • 高性能渲染:使用WebGL进行图像渲染、使用多线程进行图像编码,优化了图像的加载和显示速度,从而提供了流畅的用户体验

  • 模块化设计:设计了灵活的架构,允许开发者扩展自己的工具和定制功能,以适应特定的医学影像应用需求。

版本对比

Cornerstone3D 和 Cornerstone 版本对比,主要在图像处理、渲染性能上进行了提升。2D版本无法更好的支持复杂场景的使用,例如多平面重建、Series融合等等。以下是从不同场景进行的对比:

Cornerstone(2D版本)

  • 图像处理: 专注于处理和展示二维医学影像数据

  • 渲染性能:针对2D图像优化,提供高效的加载和显示性能。

  • 工具和功能:包括基本的图像操作工具,如缩放、平移、旋转、亮度/对比度调节,以及医学影像中常用的注释和测量工具。

Cornerstone3D(3D版本)

  • 图像处理:能够处理和展示三维医学影像数据,如从CT或MRI扫描得到的体积数据集。

  • 渲染性能:使用WebGL等技术进行3D渲染,优化了处理和显示大型体积数据集的能力。

  • 工具和功能:除了包含2D版本的基本功能外,还提供3D特有的功能,如多平面重建(MPR)、体积渲染、图像分割等等。

依赖项

vtk.js

vtk.js是一个开源的javascript库,用于3D计算机图形,图像处理和可视化。Cornerstone3D的渲染引擎被设计为使用vtk.js进行3D渲染

浏览器支持

Cornerstone3D使用HTML5 canvas元素和WebGL 2.0 GPU渲染来渲染所有现代浏览器都支持的图像。但是并不是所有浏览器都支持volume streaming(使用SharedArrayBuffer创建共享内存)等高级功能。

  • Chrome > 68

  • Firefox > 79

  • Edge > 79

SharedArrayBuffer

需要重点关注 SharedArrayBuffer 问题,如果项目是部署在非安全上下文的环境中,SharedArrayBuffer 默认是不支持的,需要设置跨域隔离。

作用范围

原文:https://www.cornerstonejs.org/docs/getting-started/scope

Cornerstone3D是一个Javascript库,它利用纯粹的网络标准实现医学图像的3D渲染。该库在可能的情况下采用WebGL进行GPU加速渲染。Cornerstone3DTools是Cornerstone3D的同级库,包含了多种操控和注释工具,用于与图像进行交互。

Cornerstone3D的范围 并不包括 处理图像/体积的加载和元数据解析,只作用于图像渲染和缓存。应该使用imageLoader.registerImageLoader和volumeLoader.registerVolumeLoader注册到Cornerstone3D来使用图像/体积的请求加载。

在Cornerstone3D中,发布了第一个volumeLoader,streaming-image-volume-loader,它能够逐个流式传输体积图像。

总结回顾

在这里插入图片描述

ImageId及ImageLoader

ImageId

Cornerstone3D中的ImageId是一个用于识别单个图像以供Cornerstone显示的URL。该URL被Cornerstone用来确定调用哪个图像加载器插件来实际加载图像。

值得注意的是,Cornerstone3D将图像的加载工作委托给已注册的图像加载器。

这种策略允许Cornerstone同时显示从不同服务器通过不同协议获取的多个图像。

Image Loader

ImageLoader是一个JavaScript函数,负责接收ImageId并返回一个图像对象。由于加载图像通常需要调用服务器,因此图像加载的API需要是异步的。Cornerstone要求Image Loaders返回一个包含Promise的对象,Cornerstone将使用这个Promise异步接收图像对象,或者在发生错误时接收一个错误信息

支持的Loader类型

  • Cornerstone WADO Image Loader:支持DICOM第10部分图像;支持WADO-URI和WADO-RS;支持多帧DICOM实例;支持从文件对象读取DICOM文件

  • Cornerstone Web Image Loader: 支持 PNG and JPEG 文件

  • Cornerstone-nifti-image-loader:支持 NifTi格式文件

注册一个ImageLoader

使用registerImageLoader注册指定协议的加载器,以下示例表示:wadouri 协议的图像使用 cornerstoneDICOMImageLoader加载器加载

cornerstone.imageLoader.registerImageLoader('wadouri', cornerstoneDICOMImageLoader.wadouri.loadImage);

cornerstoneDICOMImageLoader.wadouri.register(cornerstone);  
cornerstoneDICOMImageLoader.external.cornerstone = cornerstone;
cornerstoneDICOMImageLoader.external.dicomParser = dicomParser;

@cornerstonejs/dicom-image-loader

为Cornerstone3D库提供了一个DICOM图像加载器。这是[cornerstoneDICOMImageLoader]的后继产品,支持在3D库中使用。主要提供了以下新增特性:

  • Typescript支持(及类型定义)

  • 更佳的开发体验(例如,单一仓库、代码规范检查等)

主要特点为:

  • 实现了一个通过HTTP GET请求加载DICOM实例的Cornerstone图像加载器。

    • 可与WADO-URI服务器一起使用

    • 可与Orthanc的文件终端一起使用

    • 可与任何通过HTTP GET返回DICOM P10实例的服务器一起使用

  • 实现了一个用于WADO-RS(DICOMWeb)的Cornerstone图像加载器

  • 支持许多流行的传输语法和光度解释

  • 动态地利用WebAssembly(WASM)构建每个编解码器,显著提高图像解码性能,并使我们能够在需要时动态加载编解码器,从而减少构建时间和复杂性

  • 用于在Web Workers中执行CPU密集型任务的框架

    • 用于图像解码

    • 用于CPU密集型任务(例如,图像处理)

图像加载流程

  1. ImageLoader使用registerImageLoader API在Cornerstone中注册,以加载特定的ImageId URL方案

  2. 应用程序使用loadImage API来加载堆栈中的图像,或者使用createAndCacheVolume API来加载体积数据。

  3. Cornerstone将加载图像的请求委托给已注册相应ImageId URL方案的ImageLoader。

  4. ImageLoader将返回一个包含Promise的图像加载对象,

  5. 一旦获取到像素数据,它将用相应的图像对象解析这个Promise。获取像素数据可能需要通过XMLHttpRequest调用远程服务器,对像素数据进行解压(例如,来自JPEG 2000的数据),并将像素数据转换成Cornerstone能够理解的格式(例如,RGB与YBR颜色)。通过解析Promise返回的图像对象,随后将通过renderingEngine API显示。

在这里插入图片描述

总结回顾

ImageId

在这里插入图片描述

ImageLoader

在这里插入图片描述

Volume及VolumeLoader

Volume

Volume是一个具有空间物理大小和方向的3D数据阵列

它可以通过组合3D成像系列的像素数据元数据来构建,或者可以由应用程序从头定义。一个Volume拥有FrameOfReferenceUID、体素间距(x, y, z)、体素尺寸(x, y, z)、原点和方向向量,这些特征唯一地定义了它相对于患者坐标系统的坐标系统

ImageVolume

在Cornerstone3D中,使用ImageVolume基类来表示3D图像体积。所有的Volume都是从这个类派生的。例如StreamingImageVolume,它被用来表示一个图像被流式传输的Volume。

所以所有的Volume都实现了以下这个接口:

interface IImageVolume {
  /** 【缓存中Volume的唯一标识符】unique identifier of the volume in the cache */
  readonly volumeId: string
  /** volume dimensions */
  dimensions: Point3
  /** volume direction */
  direction: Float32Array
  /** volume metadata */
  metadata: Metadata
  /** volume origin - set to the imagePositionPatient of the last image in the volume */
  origin: Point3
  /** volume scalar data */
  scalarData: any
  /** volume scaling metadata */
  scaling?: {
    PET?: {
      SUVlbmFactor?: number
      SUVbsaFactor?: number
      suvbwToSuvlbm?: number
      suvbwToSuvbsa?: number
    }
  }
  /** volume size in bytes */
  sizeInBytes?: number
  /** volume spacing */
  spacing: Point3
  /** number of voxels in the volume */
  numVoxels: number
  /** volume image data as vtkImageData */
  imageData?: vtkImageData
  /** openGL texture for the volume */
  vtkOpenGLTexture: any
  /** loading status object for the volume containing loaded/loading statuses */
  loadStatus?: Record<string, any>
  /** imageIds of the volume (if it is built of separate imageIds) */
  imageIds?: Array<string>
  /** volume referencedVolumeId (if it is derived from another volume) */
  referencedVolumeId?: string // if volume is derived from another volume
  /** method to convert the volume data in the volume cache, to separate images in the image cache */
  convertToCornerstoneImage?: (
    imageId: string,
    imageIdIndex: number
  ) => IImageLoadObject
}

Volume Loader

与ImageLoader类似,VolumeLoader接收一个Volume ID和加载Volume所需的其他信息,并返回一个解析为体积的Promise。

这个Volume可以由一组2D图像(例如,imageIds)构建,也可以由一个3D数组对象(如NIFTI格式)构建。我们添加了cornerstoneStreamingImageVolumeLoader库来支持将2D图像(imageIds)流式传输成3D体积。

注册一个Volume Loader

使用registerVolumeLoader来定义一个Volume Loader

import {
  cornerstoneStreamingImageVolumeLoader,
  cornerstoneStreamingDynamicImageVolumeLoader,
} from '@cornerstonejs/streaming-image-volume-loader';

 // 注册体积加载器 => 当 CornerstoneJS 需要加载一个类型为 'cornerstoneStreamingImageVolume' 的体积数据时,它将会使用这个加载器。
  volumeLoader.registerVolumeLoader(
  'cornerstoneStreamingImageVolume',
  cornerstoneStreamingImageVolumeLoader,
);

@cornerstonejs/streaming-image-volume-loader

从图片中创建Volume

由于在StreamingImageVolume中3D Volume是由2D图像组成的,它的体积元数据来源于2D图像的元数据,所以这个loader需要在初始时调用来获取图像元数据。这样做不仅可以在内存中预分配和缓存Volume,还可以在加载2D图像时渲染Volume(渐进式加载)

通过预先从所有图像(imageId)中获取元数据,不需要为每个imageId创建Image对象,将图像的pixelData直接插入到正确位置的volume中即可,这样保证了速度和内存效率。

Volume与Image之间的转换

StreamingImageVolume基于一系列获取的图像(2D)加载Volume,Volume可以实现将其3D像素数据转换为2D图像的功能,而无需通过网络重新请求它们。

同样的,如果一组imageid具有Volume的属性(相同的FromOfReference, origin, dimension, direction和pixelSpacing),那么Cornerstone3D可以从一组imageid创建一个Volume。

使用streaming-image-volume-loader

const imageIds = ['wadors:imageId1', 'wadors:imageId2'];

const ctVolumeId = 'cornerstoneStreamingImageVolume:CT_VOLUME';

const ctVolume = await volumeLoader.createAndCacheVolume(ctVolumeId, {
  imageIds: ctImageIds,
});

await ctVolume.load();


自定义加载顺序

由于Volume的创建和缓存(createAndCacheVolume)与图像数据(load)的加载是分离的。所以支持以任何顺序加载图像,以及重新排序图像请求以正确顺序加载图像的能力。

大致的加载流程

  1. 根据一组imageIds,计算Volume的元数据,如间距、原点、方向等。

  2. 实例化一个新的StreamingImageVolume

  3. StreamingImageVolume实现了加载方法(.load)

    1. 通过使用imageLoadPoolManager来实现加载请求

    2. 每个加载的帧(imageId)被放置在3D体积中的正确切片位置

    3. 返回一个体积加载对象,该对象包含一个解析为体积的promise。

总结回顾

Volume

在这里插入图片描述

VolumeLoader

在这里插入图片描述

RenderingEngine

RenderingEngine允许用户创建Viewports,将这些viewport与屏幕上的 HTML 元素关联,并使用WebGL 画布将数据渲染到这些元素上。

值得注意的是,RenderingEngine 能够渲染多个viewport,而无需创建多个引擎。

在Cornerstone3D 中,从零开始构建了 RenderingEngine,并使用 vtk.js 作为渲染的支撑,vtk.js 是一个 3D 渲染库,能够利用 WebGL 进行 GPU 加速渲染。

特性

1. 渲染优化

在 Cornerstone(2D)中,每个viewport都使用 WebGL 画布处理数据。随着viewport数量的增加,尤其在复杂的影像应用场景中(例如,同步视窗),因为会导致屏幕上画布的大量更新,以及随着视窗数量增加而性能下降。

在 Cornerstone3D 中,在屏幕外处理数据。这意味着我们有一个大型的不可见画布(离屏),它内部包含了所有屏幕上的画布。当用户操纵数据时,离屏画布中相应的像素会被更新,在渲染时,将数据从离屏画布复制到每个视窗的屏幕上画布。由于复制过程比重新渲染每个视窗上的操纵更快,因此解决了性能下降的问题。

2. 共享Volume Mapper

vtk.js 提供了用于渲染的标准渲染功能。此外,在 Cornerstone3D 中,引入了共享体积映射器(Shared Volume Mappers),以便在任何可能需要的视窗中重用数据,而无需复制数据。

使用

  • 初始化一个renderingEngine
import { RenderingEngine } from '@cornerstonejs/core';

const renderingEngineId = 'myEngine';
const renderingEngine = new RenderingEngine(renderingEngineId);
  • 创建viewport并绑定视图
const viewportInput = [
  // CT Volume Viewport - Axial
  {
    viewportId: 'ctAxial',
    type: ViewportType.ORTHOGRAPHIC,
    element: htmlElement1,
    defaultOptions: {
      orientation: Enums.OrientationAxis.AXIAL,
    },
  },
  // CT Volume Viewport - Sagittal
  {
    viewportId: 'ctSagittal',
    type: ViewportType.ORTHOGRAPHIC,
    element: htmlElement2,
    defaultOptions: {
      orientation: Enums.OrientationAxis.SAGITTAL,
    },
  },
  // CT Axial Stack Viewport
  {
    viewportId: 'ctStack',
    type: ViewportType.STACK,
    element: htmlElement3,
    defaultOptions: {
      orientation: Enums.OrientationAxis.AXIAL,
    },
  },
];

renderingEngine.setViewports(viewportInput);
  • 渲染视图
renderingEngine.renderViewports(['ctAxial','ctSagittal','ctStack']);

总结概述

在这里插入图片描述

Viewport

在 Cornerstone3D 中,viewport是由 HTML 元素创建的,我们需要提供用于创建viewport的元素。然后进行初始化绑定

分类

viewport主要分为 2D栈视图、Volume体视图、3D视图,根据不同的渲染需求进行选择。无论是哪一种视图类型,都是通过 RenderingEngine API 进行创建

StackViewport

  • 适用于呈现一堆图像,这些图像可能属于也可能不属于同一图像。

  • Stack可以包含各种形状、大小和方向的2D图像

const viewport = renderingEngine.getViewport('stackId');
await viewport.setStack(imageIds);

VolumeViewport

  • 适合于渲染被认为是一个3D图像的体积数据。

  • 使用VolumeViewport可以通过设计实现多平面重组或重建(MPR),可以从不同的方向进行体积可视化,而不会增加性能成本。

  • 用于两个series之间的图像融合

3D Viewport

  • 适用于实际的三维立体数据渲染。

  • 有不同类型的预设,如骨,软组织,肺等。

初始化

所有的Viewport都继承自Viewport类,它提供了一个displayArea字段。该字段可用于以编程方式设置图像的初始缩放/平移。

默认情况下,视口将使dicom图像适合屏幕。displayArea字段支持以下配置内容:

type DisplayArea = {
  imageArea: [number, number], // areaX, areaY
  imageCanvasPoint: {
    imagePoint: [number, number], // imageX, imageY
    canvasPoint: [number, number], // canvasX, canvasY
  },
  storeAsInitialCamera: boolean,
};

设置初始化时的缩放

在初始化时,如果想要设置图像为200%,则设置如下

 imageArea: [0.5, 0.5],

设置初始化时的平移

在初始化时,如果想要左对齐图像,则设置如下

imageCanvasPoint: {
  imagePoint: [0, 0.5], 
  canvasPoint: [0, 0.5], 
};

这意味着画布上的左(0)中间(0.5)点需要与图像上的左(0)中间(0.5)点对齐。数值基于完整图像的%大小。

如何在实际应用中更改

在创建视图时进行初始化

renderingEngine.setViewports([{
    viewportId: 'ctAxial',
    type: ViewportType.ORTHOGRAPHIC,
    element: htmlElement1,
    defaultOptions: {
      orientation: Enums.OrientationAxis.AXIAL,
      displayArea:{
        // 需要更改的配置项
      }
    },
}]);

总结概述

在这里插入图片描述

MetaData

医学影像通常附带大量非像素级的元数据,例如图像的像素间距、患者 ID 或扫描获取日期等等。对于某些文件类型(例如 DICOM),这些信息存储在文件头中,可以被读取、解析并在应用程序中传递。而对于其他类型(例如 JPEG、PNG),这些信息需要独立于实际像素数据提供。

元数据提供器是一个 JavaScript 函数,作为访问 Cornerstone 中与图像相关元数据的接口。用户也可以定义自己的提供器函数,以返回他们希望的每个特定图像的任何元数据。

自定义元数据提供器

提供器需要实现一个get函数,该函数接收一个 type 和 ImageId, 返回当前ImageId中业务需要的数据

function addInstance(imageId, scalingMetaData) {
  const imageURI = csUtils.imageIdToURI(imageId);
  scalingPerImageId[imageURI] = scalingMetaData;
}

function get(type, imageId) {
  if (type === 'scalingModule') {
    const imageURI = csUtils.imageIdToURI(imageId);
    return scalingPerImageId[imageURI];
  }
}

export default { addInstance, get };

在项目中注册使用

通过addProvider函数,在CornerStone中添加提供器

  cornerstone.metaData.addProvider(
    ptScalingMetaDataProvider.get.bind(ptScalingMetaDataProvider),
    10000,
  );

优先级

由于可以注册多个元数据提供器,因此在添加提供器时,可以为其定义一个优先级数字。

当需要请求元数据时,Cornerstone 将按照提供器的优先级顺序请求图像的元数据(如果提供器对于图像 ID 返回未定义,则 Cornerstone 将转向下一个提供器)。例如,如果 provider1 注册时优先级为 10,而 provider2 注册时优先级为 100,则首先向 provider2 请求图像 ID 的元数据。上面的示例中我们定义了一个优先级为10000的provider

总结概述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1405884.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

学习Opencv(蝴蝶书/C++)——4.图形和大型数组类型(下)

文章目录 4.5 通过块访问数组(多行多列等范围访问)4.6 矩阵支持的代数运算(运算符重载)4.7 饱和转换4.8 cv::Mat的其他成员函数7. cv::SparsesMat表示N维稀疏数组7.1 基本介绍7.2 引用或者值访问7.2.1 cv::SparsesMat::ptr()7.2.2 cv::SparsesMat::ref()7.2.3 cv::SparsesM…

人民银行成功实现数字人民币与传统支付的互通

西米支付网&#xff08;45ri.com&#xff09;中国人民银行数字货币研究所10月12日在人民银行网站刊发了题为《扎实开展数字人民币研发试点工作》的文章&#xff0c;截至2022年8月31日&#xff0c;已有15个省市的试点地区共计完成了3.6亿笔的交易&#xff0c;交易金额达到了1000…

大小鼠行为刺激-ZL-034B大小鼠跳台仪/多通道跳台记录仪

小鼠跳台实验是一种常用的学习记忆实验方法&#xff0c;它基于条件反射原理&#xff0c;通过观察小鼠在电栅和平台之间跳跃的行为&#xff0c;来研究药物对学习和记忆过程的影响。它适用于各种增智健脑、提高记忆、抗衰老药物和保健品筛选、开发研制。它是初筛药物的理想工具&a…

ubuntu 20.04 aarch64 平台交叉编译 libffi 库

前言 由于打算交叉编译 python&#xff0c;但是依赖 libffi 库&#xff0c;也就是 libffi 库也需要交叉编译 环境&#xff1a; ubuntu 20.04 交叉编译工具链&#xff1a;这里使用 musl libc 的 gcc 交叉编译工具链&#xff0c;aarch64-linux-musleabi-gcc&#xff0c;gcc 版本…

【心得】java反序列化漏洞利用启蒙个人笔记

目录 前置基础概念 java的反序列化利用概念baby题 例题1 例题2 java反序列化启蒙小结&#xff1a; URLDNS链 一句话总结&#xff1a; 简单分析&#xff1a; 利用点&#xff1a; 示例&#xff1a; 前置基础概念 序列化 类实例->字节流 反序列化 字节流->类实…

大模型+自动驾驶

论文&#xff1a;https://arxiv.org/pdf/2401.08045.pdf 大型基础模型的兴起&#xff0c;它们基于广泛的数据集进行训练&#xff0c;正在彻底改变人工智能领域的面貌。例如SAM、DALL-E2和GPT-4这样的模型通过提取复杂的模式&#xff0c;并在不同任务中有效地执行&#xff0c;从…

1 认识微服务

1.认识微服务 随着互联网行业的发展&#xff0c;对服务的要求也越来越高&#xff0c;服务架构也从单体架构逐渐演变为现在流行的微服务架构。这些架构之间有怎样的差别呢&#xff1f; 1.0.学习目标 了解微服务架构的优缺点 1.1.单体架构 单体架构&#xff1a;将业务的所有…

Checklist系列:MySQL自检五十五问,万字整理,推荐收藏

&#x1f680;最近也打算整理一波已经学过的知识&#xff0c;名字已经想好了就叫《CheckList》系列&#xff0c;以后需要用到的时候也可以拿出来看。问题来源于网上常见的面试题&#xff0c;问题的答案多以官网为主&#xff0c;每个问题我都贴了链接&#xff0c;觉得我写的不清…

Flink中的容错机制

一.容错机制 在Flink中&#xff0c;有一套完整的容错机制来保证故障后的恢复&#xff0c;其中最重要的就是检查点。 1.1 检查点&#xff08;Checkpoint&#xff09; 在流处理中&#xff0c;我们可以用存档读档的思路&#xff0c;将之前某个时间点的所有状态保存下来&#xf…

世微AP2915宽电压无MOS管切换双色灯性价比方案

1&#xff1a;产品描述 AP2915 是一款可以一路灯串切换两路灯串的降压恒流驱动器,高效率、外围简单、内置功率管&#xff0c;适用于 5-100V 输入的高精度降压 LED 恒流驱动芯片。内置功率管输出功率可达 12W&#xff0c;电流 1.2A。AP2915 一路灯亮切换两路灯亮&#xff0c;其…

外包干了一个月,技术退步明显。。。。。

先说一下自己的情况&#xff0c;本科生&#xff0c;19年通过校招进入南京某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…

【GitHub项目推荐--不错的 C++开源项目】【转载】

01 C 那些事 这是一个适合初学者从入门到进阶的仓库&#xff0c;解决了面试者与学习者想要深入 C及如何入坑 C的问题。 除此之外&#xff0c;本仓库拓展了更加深入的源码分析&#xff0c;多线程并发等的知识&#xff0c;是一个比较全面的 C 学习从入门到进阶提升的仓库。…

用Axure RP 9制作弹出框

制作流程 1.准备文本框 下拉列表 按钮 动态面板 如图 2.先把下拉列表放好 再放动态面板覆盖 3.点动态面板 进入界面 如图 4.给按钮添加交互 3个按钮一样的 如图 5.提交按钮添加交互 如图

PyCharm安装PyQt5及工具Qt Designer程序UI界面的实现工具

1. 工具包安装 对于一个新创建的Python环境&#xff0c;首先需要安装PyQt的相关工具包&#xff0c;因为是Python的依赖包所有可以通过pip进行安装&#xff0c;由于我们在PyCharm中进行程序设计&#xff0c;这里我们可以通过PyCharm中的环境管理界面进行安装。 点击菜单栏“Fi…

Day 28 | 回溯 93.复原IP地址 、78.子集 、 90.子集II

93.复原IP地址 题目 文章讲解 视频讲解 思路&#xff1a;每轮开始的位置需要变化就需要设置start class Solution {List<String> result new ArrayList<>();public List<String> restoreIpAddresses(String s) {if (s.length() < 4 ||s.length() >…

[MySQL]基础的增删改查

目录 1.前置介绍 2.数据库操作 2.1显示当前数据库 2.2创建数据库 2.3 使用数据库 2.4 删除数据库 3.常用数据类型 3.1整型和浮点型 3.2字符串类型 4.表的操作 4.1查看表结构 4.2创建表 4.3删除表 5.重点 5.1操作数据库 5.2常用数据类型 5.3操作表 1.前置介绍 …

Python with Office 054 - Work with Word - 7-9 插入图像 (3)

近日详细学习了寒冰老师的很好的书《让Python遇上Office》&#xff0c;总结了系列视频。 这个是其中的一集&#xff1a;如何在Word中插入图像&#xff0c;我会陆续分享其他的视频并加上相应说明 https://www.ixigua.com/7319498175104942643?logTage9d15418663166a05d10

社区公益培训系统功能说明

社区公益培训系统功能说明 本系统将用于社区面向居民开展的公益培训课程展示&#xff0c;在线报名&#xff0c;并按班级排课上课&#xff0c;上课时学员要扫码签到&#xff0c;经常旷课的学员将禁止再报名其他课程。 1. 用户注册与登录 - 提供用户注册和登录功能&#xff0c;…

linux的kali安装,换源,更新包

下载kali kali.org进入官网后点第二个 然后点第一个 解压kali 下载后获得.7z压缩包&#xff0c;建议移动到合适自己电脑的位置进行解压&#xff0c;我喜欢放在D盘 启动kali 双击进入解压出的文件夹&#xff0c;将唯一一个.vmx文件用vmware打开&#xff08;没装的自行提前装…

《PCI Express体系结构导读》随记 —— 第I篇 第2章 PCI总线的桥与配置(27)

接前一篇文章&#xff1a;《PCI Express体系结构导读》随记 —— 第I篇 第2章 PCI总线的桥与配置&#xff08;26&#xff09; 2.5 非透明PCI桥 本回将结合实例说明直接地址翻译过程。 2.5.2 通过非透明桥片进行数据传递 下文以图2-16中处理器x访问处理器y存储器地址空间的实…