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

VTK编程指南<十二>:VTK图像数据结构及图像创建与显示

  数字图像是一种重要的多媒体数据,广泛应用于工业生产、生物医学、地质、气象等重要领域。数字图像处理技术具有重要的应用价值。图像是VTK里非常重要的一种数据结构。本章重点讲解VTK在数字图像处理应用方面的相关技术。

1、VTK图像数据结构

  数字图像文件内容由两个部分组成:图像头信息和数据。图像头信息定义了图像的基本
信息,主要包括起点位置(Origin)、像素间隔(Space)和维数(Dimension)。通过这三个参数即可确定图像空间位置和大小。图像可以看作空间中的一个规则的网格,网格中的每个最小单元称为像素(二维)或者体素(三维),网格在每个方向上的像素或者体素个数即为图像在该方向的维数。像素索引表示每个像素在图像网格中的位置,是图像内部的网格坐标。

  在医学图像中,每个图像除了内部坐标外,还存在一个世界坐标,这个世界坐标依赖于成像设备。在医学图像中,起点位置、像素间隔和图像维数决定了世界坐标系。这样通过起点位置、像素间隔和像素索引即可计算每个像素的世界坐标。

  图5-1表示一个4x2x3体素的图像,即图像的维数,每一个小球表示一个像素;而图像的原点为(5.1,10.0,6.5),两个像素之间的间隔表示像素间隔,每个方向的像素间隔分别为1.5、1.5 和1.8。
在这里插入图片描述

  图像数据即为图像像素的像素值,一般采用一维数组来表示和存储。已知像素索引和图像维数的情况下,即可计算每个像素对应的像素值。通常图像的像素值为一个标量,例如灰度图像;图像像素值也可以是一个矢量,例如梯度图像;另外,图像像素值还可以是张量,如弥散张量成像(Diffusion Tensor Imaging,DTI)。医学图像处理中经常使用的是灰度图像。

  这里需要注意:灰度图像像素或者体素的数据类型在一般的灰度图像处理中不需要考虑因为其范围默认为0~255,可以采用一个unsigned char类型来表示。但是在医学图像处理中,256灰度级远远不能满足要求,因此灰度范围往往大于256级。

  常见医学图像的像素数据类型为 unsigned short,灰度范围为 0~65536。另外,有时为了精度的考虑,也会使用 int、float或者 double 类型,因此需要格外注意。由前面章节内容可知,VTK 中图像数据结构由 vtkImageData 类表示。利用 vtkImageData可以方便地创建、读写和访问图像数据。下面以VTK图像创建为起点,一步步走进VTK图像处理的世界。

2、VTK图像创建

2.1 VTK图像源 Source

  VTK中内置了多个创建图像的 Source 类,利用这些 Source 类可以快速创建图像。这里以vtkImageCanvasSource2D为代表进行说明。该Source类的功能是创建一个画布(空白图像),并提供了多种几何图形(点、线段、圆、矩形以及图像等)的绘制填充功能。
在这里插入图片描述

#include <iostream>#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2);// VTK was built with vtkRenderingOpenGL2
VTK_MODULE_INIT(vtkInteractionStyle);#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <vtkImageCanvasSource2D.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
#include <vtkRenderer.h>
#include <vtkImageActor.h>int main()
{vtkSmartPointer<vtkImageCanvasSource2D> canvas =vtkSmartPointer<vtkImageCanvasSource2D>::New();canvas->SetScalarTypeToUnsignedChar();canvas->SetNumberOfScalarComponents(3);canvas->SetExtent(0, 400, 0, 400, 0, 0);canvas->SetDrawColor(255, 0, 0.0);canvas->FillBox(0, 100, 0, 100);canvas->Update();canvas->SetDrawColor(0, 255, 0.0);canvas->FillBox(100, 200, 100, 200);canvas->Update();// Create actorsvtkSmartPointer<vtkImageActor> redActor =vtkSmartPointer<vtkImageActor>::New();redActor->SetInputData(canvas->GetOutput());// Define viewport ranges// (xmin, ymin, xmax, ymax)double redViewport[4] = { 0.0, 0.0, 1.0, 1.0 };// Setup renderersvtkSmartPointer<vtkRenderer> redRenderer =vtkSmartPointer<vtkRenderer>::New();redRenderer->SetViewport(redViewport);redRenderer->AddActor(redActor);redRenderer->ResetCamera();redRenderer->SetBackground(0.2, 0.2, 0.2);// Setup render windowvtkSmartPointer<vtkRenderWindow> renderWindow =vtkSmartPointer<vtkRenderWindow>::New();renderWindow->AddRenderer(redRenderer);renderWindow->SetSize(480, 480);renderWindow->Render();renderWindow->SetWindowName("ImageCanvasSource2D");// Setup render window interactorvtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =vtkSmartPointer<vtkRenderWindowInteractor>::New();vtkSmartPointer<vtkInteractorStyleImage> style =vtkSmartPointer<vtkInteractorStyleImage>::New();renderWindowInteractor->SetInteractorStyle(style);// Render and start interactionrenderWindowInteractor->SetRenderWindow(renderWindow);renderWindowInteractor->Initialize();renderWindowInteractor->Start();return EXIT_SUCCESS;
}

  上面的代码片段中,先定义了一个vtkImageCanvasSource2D对象,然后设置画布的像素数据类型、像素组分数目和画布的大小;然后,利用画布的FiIlIBox()方法在画布中绘制两个矩形,并通过画布的 SetDrawColor()方法来设置两个矩形的颜色。

  除了vtkImageCanvasSource2D 外,VTK还提供了其他类似的Source 类来快速生成特定的图像,例如vtkImageEllipsoidSource,该类根据指定的中心以及各个轴的半径来生成一个前景为椭圆(球)的二值像;vtkImageGaussianSource 类生成一幅像素值服从高斯分布的图像vtkImageGridSource 用于生成网格线图像;vtkImageNoiseSource 生成一个像素值为随机数的噪声像。vtkImageSinusoidSource 生成的图像像素值由正弦函数决定。

2.2 直接创建图像

  利用上述图像Source可以快速地生成特定的图像,但是实际应用中它们用到得较少。VTK中可以手动生成图像,然后根据需要进行像素赋值。
在这里插入图片描述

#include <iostream>#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2);// VTK was built with vtkRenderingOpenGL2
VTK_MODULE_INIT(vtkInteractionStyle);#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkImageActor.h>
#include <vtkInteractorStyleImage.h>
#include <vtkRenderWindow.h>
#include <vtkType.h>int main()
{vtkSmartPointer<vtkImageData> img = vtkSmartPointer<vtkImageData>::New();img->SetDimensions(16, 16, 1);// 分配标量数据,并设置数据类型为VTK_UNSIGNED_CHARimg->AllocateScalars(VTK_UNSIGNED_CHAR, 1);unsigned char* ptr = (unsigned char*)img->GetScalarPointer();for (int i = 0; i < 16 * 16 * 1; i++){*ptr++ = i % 256;}vtkSmartPointer<vtkImageActor> redActor =vtkSmartPointer<vtkImageActor>::New();redActor->SetInputData(img);double redViewport[4] = { 0.0, 0.0, 1.0, 1.0 };vtkSmartPointer<vtkRenderer> redRenderer =vtkSmartPointer<vtkRenderer>::New();redRenderer->SetViewport(redViewport);redRenderer->AddActor(redActor);redRenderer->ResetCamera();redRenderer->SetBackground(1.0, 1.0, 1.0);vtkSmartPointer<vtkRenderWindow> renderWindow =vtkSmartPointer<vtkRenderWindow>::New();renderWindow->AddRenderer(redRenderer);renderWindow->SetSize(640, 480);renderWindow->Render();renderWindow->SetWindowName("CreateVTKImageData");vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =vtkSmartPointer<vtkRenderWindowInteractor>::New();vtkSmartPointer<vtkInteractorStyleImage> style =vtkSmartPointer<vtkInteractorStyleImage>::New();renderWindowInteractor->SetInteractorStyle(style);renderWindowInteractor->SetRenderWindow(renderWindow);renderWindowInteractor->Initialize();renderWindowInteractor->Start();return EXIT_SUCCESS;
}

  先定义 vtkImageData 对象,然后指定图像的维数,而图像的原点和像素间隔则都是采用默认值,因此不需要设置。SetScalarTypeToUnsignedChar()指定图像的像素数据类型为 unsigned
char,SetNumberOfScalarComponents()则指定每个像素值的组分数为 1,即每个像素值为1个标量值。参数设置完毕,调用 AllocateScalars()分配内存,生成图像数据。图像生成后,默认所有像素值为 0。可以通过访问图像数据数组来设置每个像素值,vtkImageData:: GetScalarPointer()即返回图像的数据数组(图像数据数组采用一维数组,参考本书3.6节的内容),然后根据图像的大小,访问每个像素并为其赋值。

3、VTK图像显示

3.1 vtkImageViewer2

  VTK早期的版本提供了vtkImageViewer 类来显示图像,随着版本的发展,目前使用vtkImageViewer2来代替vtkImageViewer 实现图像的显示。vtkImageViewer2 中封装了VTK图像显示的可视化渲染引擎,包括vtkActor、vtkRender、vtkRenderWindow、vtkInteractorStypeImage等对象,可以方便地完成图像显示和交互。该类提供的主要交互操作有图像放缩、窗宽窗位调节,并提供切片选择及切片方向设置接口,尤其适合三维图像的切片显示。下述代码说明了使vtkImageViewer2显示图像的方法。

在这里插入图片描述

#include <iostream>#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2);// VTK was built with vtkRenderingOpenGL2
VTK_MODULE_INIT(vtkInteractionStyle);#include <vtkSmartPointer.h>
#include <vtkImageViewer2.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkMetaImageReader.h>//测试图像:../data/brain.mhd
int main(int argc, char* argv[])
{std::string sFile = "../data/brain.mhd";vtkSmartPointer<vtkMetaImageReader> reader =vtkSmartPointer<vtkMetaImageReader>::New();reader->SetFileName(sFile.c_str());reader->Update();vtkSmartPointer<vtkImageViewer2> imageViewer =vtkSmartPointer<vtkImageViewer2>::New();imageViewer->SetInputConnection(reader->GetOutputPort());vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =vtkSmartPointer<vtkRenderWindowInteractor>::New();imageViewer->SetupInteractor(renderWindowInteractor);imageViewer->SetColorLevel(500);imageViewer->SetColorWindow(2000);imageViewer->SetSlice(40);imageViewer->SetSliceOrientationToXY();imageViewer->Render();imageViewer->GetRenderer()->SetBackground(1.0, 1.0, 1.0);imageViewer->SetSize(640, 480);imageViewer->GetRenderWindow()->SetWindowName("DisplayImageExample");renderWindowInteractor->Start();return EXIT_SUCCESS;
}

  这里为了更好地演示vtkImageViewer2的功能,以一幅三维医学图像为例进行说明。首先使用 vtkMetalmageReader 读入一个*.mhd 格式的图像,然后定义vtkImageViewer2 对象显示图像。为了实现鼠标、键盘消息响应,定义vtkRenderWindowInteractor 对象,并通过vtkImageViewer2::SetInteractor()设置交互对象。最后设置了窗位(ColorLevel)、窗宽(ColorWindow)、切片索引(Slice)和切片方向(Orientation)等参数。

  在渲染窗口中,按下鼠标左键拖动鼠标,可以调节图像的窗宽窗位,从而显示不同灰度范围内容;按下鼠标右键拖动鼠标可以缩放图像。当然,这些交互操作可以由用户根据需要自己定义vtkInteractorStyle子类,并响应相应的操作。

1.窗宽/窗位的概念
  窗宽是图像显示的灰度范围。一般显示器的灰度范围为256级,而医学图像的灰度范围则远远大于该范围,因此通过显示器显示时不能显示所有灰度级,需要使用窗宽来定义欲显示的灰度范围。当灰度值高于该范围的最大值时,均以白影显示;当低于该范围时,均以黑色显示。若增大窗宽,则显示具有不同灰度值的组织结构增多,但是会降低组织之间的对比度,若减小窗宽,则可视的不同灰度组织结构会减少,同时增大组织结构的对比度。

  窗位是窗宽的中心位置(见图5-5)。窗宽只是确定了CT图像灰度范围上的可视部分范围,还需要窗位来确定可视灰度范围的具体位置。同样的窗宽,会根据窗位的位置变化来显示不同的组织结构。比如,窗宽为200,当窗位为100时,可视灰度范围为0-200:当窗位为500时,可视灰度范围为400~600。当窗宽窗位确定以后,显示时底层会将可视灰度范围转换到256灰度级进行显示。
在这里插入图片描述

2.医学图像二维视图
  切片(Slice)或切面是三维图像比较常用的概念,尤其在医学图像中,不同方向的切面
都有特定的名字(见图5-6),分别是:矢状面(Sagital Plane),沿着身体前后径所做的与地面垂直的切面;冠状面(Coronal Plane),沿着身体左右径所做的与地面垂直的切面:横断面(Transverse/AxialPlane),是指横断身体与地面平行的切面。设置切片的方向即是通过不同的方向来观察人体内部组织结构。
在这里插入图片描述
  常见的医学图像可视化软件通常会提供四个视图用来显示图像:横断面视图、矢状面视图、冠状面视图和三维视图,例如图5-7所示的视图是来自德国癌症研究中心的MITK3M3医学图像处理软件。
在这里插入图片描述

  类vtkImageViewer2提供了SetSlice()函数来设置切片索引,SetSliceOrientationToXY()则将切片的方向设置为垂直XY平面方向。此外还可以设置为垂直YZ或者XZ平面方向,其对应函数分别为SetSliceOrientationToYZ(和 SetSliceOrientationToXZ()。默认情况下切片方向为垂直于XY平面即沿着乙轴方向,根据设置的切片索引获取乙轴方向的具体切片进行显示。

3.2 vtkImageActor

  vtkImageActor 是一个三维图像渲染Actor,通过纹理映射将图像映射到一个多边形上进行显示。使用vtkImageActor 较vtkImageViewer2 要复杂一些,需要建立完整的渲染管线:包括 vtkImageActor、vtkRender、vtkRenderWindow 和 vtkRenderWindowInteractor。另外,作为二
维图像浏览器,不需要在三维空间中进行旋转操作,因此还需要为vtkRenderWindowlInteractor
定义一个vtkInteractorStylelmage 对象。下例中使用vtkImageActor 建立图像渲染管线来显示图
像并实现交互功能。
在这里插入图片描述

#include <iostream>#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2);// VTK was built with vtkRenderingOpenGL2
VTK_MODULE_INIT(vtkInteractionStyle);#include <vtkSmartPointer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
#include <vtkRenderer.h>
#include <vtkBMPReader.h>
#include <vtkImageActor.h>//测试图像:../data/lena.bmp
int main(int argc, char* argv[])
{std::string sFile = "../data/lena.bmp";vtkSmartPointer<vtkBMPReader> reader =vtkSmartPointer<vtkBMPReader>::New();reader->SetFileName(sFile.c_str());reader->Update();vtkSmartPointer<vtkImageActor> imgActor =vtkSmartPointer<vtkImageActor>::New();imgActor->SetInputData(reader->GetOutput());vtkSmartPointer<vtkRenderer> renderer =vtkSmartPointer<vtkRenderer>::New();renderer->AddActor(imgActor);renderer->SetBackground(1.0, 1.0, 1.0);vtkSmartPointer<vtkRenderWindow> renderWindow =vtkSmartPointer<vtkRenderWindow>::New();renderWindow->AddRenderer(renderer);renderWindow->SetSize(640, 480);renderWindow->Render();renderWindow->SetWindowName("DisplayImageExample2");vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =vtkSmartPointer<vtkRenderWindowInteractor>::New();vtkSmartPointer<vtkInteractorStyleImage> style =vtkSmartPointer<vtkInteractorStyleImage>::New();renderWindowInteractor->SetInteractorStyle(style);renderWindowInteractor->SetRenderWindow(renderWindow);renderWindowInteractor->Initialize();renderWindowInteractor->Start();return EXIT_SUCCESS;
}

4、VTK图像融合

  前面介绍的两种显示图像的方法都是在窗口中显示一幅图像。在实际应用中经常需要在窗口中同时显示多幅图像,这就会用到图像融合技术。图像融合是利用图像的不透明度来合
成图像。在VTK中,用类vtkImageBlend实现图像的融合。vtkImageBlend 可以接收多个图像输入,其输出为融合图像。输出图像的像素间隔、原点、范围以及像素组分个数与第一个图像一致。该类提供了两种融合模式。

  第一种是标准模式,也是默认的融合方式。第二种是混合模式(Compound)。该模式下输出结果利用不透明度的和做归一化。当像素的不透明度 alpha*opacity 小于或等于阈值 threshold 时,该像素会被忽略。

在这里插入图片描述

#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <vtkImageCanvasSource2D.h>
#include <vtkImageBlend.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
#include <vtkRenderer.h>
#include <vtkJPEGReader.h>
#include <vtkImageActor.h>
#include <vtkImageCast.h>#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2);// VTK was built with vtkRenderingOpenGL2
VTK_MODULE_INIT(vtkInteractionStyle);//测试图像:../data/lena-gray.jpg
int main(int argc, char* argv[])
{std::string sFile = "../data/lena-gray.jpg";vtkSmartPointer<vtkJPEGReader> reader =vtkSmartPointer<vtkJPEGReader>::New();reader->SetFileName (sFile.c_str());reader->Update();vtkSmartPointer<vtkImageCanvasSource2D> imageSource = vtkSmartPointer<vtkImageCanvasSource2D>::New();imageSource->SetNumberOfScalarComponents(1);imageSource->SetScalarTypeToUnsignedChar();imageSource->SetExtent(0, 512, 0, 512, 0, 0);imageSource->SetDrawColor(0.0);imageSource->FillBox(0, 512, 0, 512);imageSource->SetDrawColor(255.0);imageSource->FillBox(100,400,100,400);imageSource->Update();vtkSmartPointer<vtkImageBlend> imageBlend = vtkSmartPointer<vtkImageBlend>::New();imageBlend->AddInputData(reader->GetOutput());imageBlend->AddInputData(imageSource->GetOutput());imageBlend->SetOpacity(0, 0.4);imageBlend->SetOpacity(1, 0.6);imageBlend->Update();// Create actorsvtkSmartPointer<vtkImageActor> originalActor1 =vtkSmartPointer<vtkImageActor>::New();originalActor1->SetInputData(reader->GetOutput());vtkSmartPointer<vtkImageActor> originalActor2 =vtkSmartPointer<vtkImageActor>::New();originalActor2->SetInputData(imageSource->GetOutput());vtkSmartPointer<vtkImageActor> blendActor =vtkSmartPointer<vtkImageActor>::New();blendActor->SetInputData(imageBlend->GetOutput());// Define viewport ranges// (xmin, ymin, xmax, ymax)double leftViewport[4] = {0.0, 0.0, 0.33, 1.0};double midViewport[4] = {0.33, 0.0, 0.66, 1.0};double rightViewport[4] = {0.66, 0.0, 1.0, 1.0};// Setup renderersvtkSmartPointer<vtkRenderer> originalRenderer1 =vtkSmartPointer<vtkRenderer>::New();originalRenderer1->SetViewport(leftViewport);originalRenderer1->AddActor(originalActor1);originalRenderer1->ResetCamera();originalRenderer1->SetBackground(1.0, 1.0, 1.0);vtkSmartPointer<vtkRenderer> originalRenderer2 =vtkSmartPointer<vtkRenderer>::New();originalRenderer2->SetViewport(midViewport);originalRenderer2->AddActor(originalActor2);originalRenderer2->ResetCamera();originalRenderer2->SetBackground(1.0, 1.0, 1.0);vtkSmartPointer<vtkRenderer> blendRenderer =vtkSmartPointer<vtkRenderer>::New();blendRenderer->SetViewport(rightViewport);blendRenderer->AddActor(blendActor);blendRenderer->ResetCamera();blendRenderer->SetBackground(1.0, 1.0, 1.0);vtkSmartPointer<vtkRenderWindow> renderWindow =vtkSmartPointer<vtkRenderWindow>::New();renderWindow->AddRenderer(originalRenderer1);renderWindow->AddRenderer(originalRenderer2);renderWindow->AddRenderer(blendRenderer);renderWindow->SetSize( 640, 320 );renderWindow->Render();renderWindow->SetWindowName("ImageBlendExample");vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =vtkSmartPointer<vtkRenderWindowInteractor>::New();vtkSmartPointer<vtkInteractorStyleImage> style =vtkSmartPointer<vtkInteractorStyleImage>::New();renderWindowInteractor->SetInteractorStyle(style);renderWindowInteractor->SetRenderWindow(renderWindow);renderWindowInteractor->Initialize();renderWindowInteractor->Start();return EXIT_SUCCESS;
}

该示例中先读入一幅灰度图像,另外生成一个二值图像;然后定义了vtkImageBlend 对象,SetInput()函数设置两个图像作为输入。这里设置输入图像时,由于可以输入多个图像,因此需要给定图像的id号来设置输入。SetOpacity()函数用于设置对应id号的图像不透明度的大小,当不透明度为1.0时,为完全不透明。

相关文章:

VTK编程指南<十二>:VTK图像数据结构及图像创建与显示

数字图像是一种重要的多媒体数据&#xff0c;广泛应用于工业生产、生物医学、地质、气象等重要领域。数字图像处理技术具有重要的应用价值。图像是VTK里非常重要的一种数据结构。本章重点讲解VTK在数字图像处理应用方面的相关技术。 1、VTK图像数据结构 数字图像文件内容由两个…...

EasyGBS国标GB28181平台P2P远程访问故障排查指南:客户端角度的排查思路

在现代视频监控系统中&#xff0c;P2P&#xff08;点对点&#xff09;技术因其便捷性和高效性而被广泛应用。然而&#xff0c;当用户在使用P2P远程访问时遇到设备不在线或无法访问的问题时&#xff0c;有效的排查方法显得尤为重要。本文将从客户端的角度出发&#xff0c;详细探…...

打造智慧医院挂号枢纽:SSM 与 Vue 融合的系统设计与实施

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…...

网络编程 02:IP 地址,IP 地址的作用、分类,通过 Java 实现 IP 地址的信息获取

一、概述 记录时间 [2024-12-18] 前置文章&#xff1a;网络编程 01&#xff1a;计算机网络概述&#xff0c;网络的作用&#xff0c;网络通信的要素&#xff0c;以及网络通信协议与分层模型 本文讲述网络编程相关知识——IP 地址&#xff0c;包括 IP 地址的作用、分类&#xff…...

如何使用Python WebDriver爬取ChatGPT内容(完整教程)

大背景 虽然我们能用网页版chatGPT来聊天、写文章&#xff0c;但是我们采集大量的内容&#xff0c;就得不断地手动输入提问来获取答案&#xff0c;并且将结果复制到数据库来保存。如果整个过程能使用程序来做自然要节省很多的人力&#xff0c;精力和时间。 Python webdirver …...

WSL切换默认发行版

查看适用于wsl的子系统有哪些: wslconfig /list 设置wsl的默认发行版 wslconfig /setdefault Ubuntu-20.04...

全志H618 Android12修改doucmentsui功能菜单项

背景: 由于当前的文件管理器在我们的产品定义当中,某些界面有改动的需求,所以需要在Android12 rom中进行定制以符合当前产品定义。 需求: 在进入File文件管理器后,查看...功能菜单时,有不需要的功能菜单,需要隐藏,如:新建窗口、不显示的文件夹、故代码分析以及客制…...

移动网络(2,3,4,5G)设备TCP通讯调试方法

背景&#xff1a; 当设备是移动网络设备连接云平台的时候&#xff0c;如果服务器没有收到网络数据&#xff0c;移动物联设备发送不知道有没有有丢失数据的时候&#xff0c;需要一个抓取设备出来的数据和服务器下发的数据的方法。 1.服务器系统是很成熟的&#xff0c;一般是linu…...

网络安全概论——入侵检测系统IDS

一、入侵检测的概念 1、入侵检测的概念 检测对计算机系统的非授权访问对系统的运行状态进行监视&#xff0c;发现各种攻击企图、攻击行为或攻击结果&#xff0c;以保证系统资源的保密性、完整性和可用性识别针对计算机系统和网络系统或广义上的信息系统的非法攻击&#xff0c…...

Linux通信System V:消息队列 信号量

Linux通信System V&#xff1a;消息队列 & 信号量 一、信号量概念二、信号量意义三、操作系统如何管理ipc资源&#xff08;2.36版本&#xff09;四、如何对信号量资源进行管理 一、信号量概念 信号量本质上就是计数器&#xff0c;用来保护共享资源。多个进程在进行通信时&a…...

计算机网络基础图解

注&#xff1a;本文为来自 猿小许 的 “计算机网络” 相关系列文章合辑。 一、计算机网络概述 猿小许于 2021-06-03 18:39:47 发布 一、计算机网络的概念 1.1 计算机网络 概念 计算机网络&#xff1a; 是一个将分散的、具有独立功能的计算机系统&#xff0c;通过通信设备与…...

TDesign:NavBar 导航栏

NavBar 导航栏 左图&#xff0c;右标 appBar: TDNavBar(padding: EdgeInsets.only(left: 0,right: 30.w), // 重写左右内边距centerTitle:false, // 不显示标题height: 45, // 高度titleWidget: TDImage( // 左图assetUrl: assets/img/logo.png,width: 147.w,height: 41.w,),ba…...

hive注释comment中文乱码解决

问题描述 当使用以下命令查看表的元数据信息时出现中文乱码&#xff08;使用的是idea连接hive&#xff09; desc formatted test.t_archer; 解决 连接保存hive元数据的MySQL数据库&#xff0c;执行以下命令&#xff1a; use hive3; show tables;alter table hive3.COLUMNS_…...

电脑提示ntdll.d缺失是什么原因?不处理的话会怎么样?ntdll.dll文件缺失快速解决方案来啦!

电脑提示ntdll.dll缺失&#xff1a;原因、影响与解决方案 在日常的电脑使用中&#xff0c;我们偶尔会遇到一些令人困惑的系统错误&#xff0c;其中“ntdll.dll缺失”便是较为常见的一种。作为软件开发从业者&#xff0c;我深知这一错误给用户带来的不便&#xff0c;因此&#…...

MFC/C++学习系列之简单记录——序列化机制

MFC/C学习系列之简单记录——序列化机制 前言简述六大机制序列化机制使用反序列化总结 前言 MFC有六大机制&#xff0c;分别是程序启动机制、窗口创建机制、动态创建机制、运行时类信息机制、消息映射机制、序列化机制。 简述六大机制 程序启动机制&#xff1a;全局的应用程序…...

二十、服务发布Ingress

Ingress Kubernetes使用了一个Ingress策略定义和一个具体提供转发服务的Ingress Controller,两者结合,实现了基于灵活Ingress策略定义的服务路由功能。如果是对Kubernetes集群外部的客户端提供服务,那么IngressController实现的是类似于边缘路由器(Edge Router)的功能。需…...

计算机网络 八股青春版

什么是HTTP&#xff1f;HTTP和HTTPS的区别 HTTP HTTP是超文本运输协议&#xff0c;是一种无状态&#xff08;每次请求都是独立的&#xff09;的应用层协议。用于在客户端和服务器之间传输超文本数据&#xff08;如HTML文件&#xff09;。默认端口是80数据以明文形式传输&#…...

java全栈day18--Web后端实战(java操作数据库2)

前言&#xff1a;在上节入门程序当中我们见到了JDBC所提供的API&#xff0c;本节来详细说明一下。 一、JDBC--API详解 1.1DriverManager&#xff08;驱动管理器&#xff09; 回顾&#xff1a;作用获取连接&#xff0c;调用它里面的getConnection。即如下 作用 1.注册驱动解…...

electron-vite【实战】自定义标题栏【组件封装】(含异形标题栏,指定区域拖拽,窗口置顶,窗口最小化,窗口最大化,取消最大化,隐藏窗口到托盘等)

效果预览 技术要点 透明背景 src/main/index.ts 的 new BrowserWindow 中添加 transparent: true, // 设置窗口背景透明frame: false, // 隐藏窗口边框仅图标和标题部分可拖拽 仅图标和标题部分添加样式 drag .drag {-webkit-app-region: drag; }图标与标题栏的融合 标题栏的…...

vue2 项目webpack 4升5

项目背景 公司项目需要将进行微前端改造.主应用和子应用会需要共享依赖,考虑使用模块联邦进行依赖共享. 由于模块联邦要升级到webpack 5才能用,所以老项目要从webpack 4升级到webpack 5 实现思路 原来的项目用的是vue-cli 3,查了一下可以vue-cli 5用的就是webpack 5,所以可以…...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...

【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具

第2章 虚拟机性能监控&#xff0c;故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令&#xff1a;jps [options] [hostid] 功能&#xff1a;本地虚拟机进程显示进程ID&#xff08;与ps相同&#xff09;&#xff0c;可同时显示主类&#x…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP

编辑-虚拟网络编辑器-更改设置 选择桥接模式&#xff0c;然后找到相应的网卡&#xff08;可以查看自己本机的网络连接&#xff09; windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置&#xff0c;选择刚才配置的桥接模式 静态ip设置&#xff1a; 我用的ubuntu24桌…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...

R 语言科研绘图第 55 期 --- 网络图-聚类

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…...

深入理解Optional:处理空指针异常

1. 使用Optional处理可能为空的集合 在Java开发中&#xff0c;集合判空是一个常见但容易出错的场景。传统方式虽然可行&#xff0c;但存在一些潜在问题&#xff1a; // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...

沙箱虚拟化技术虚拟机容器之间的关系详解

问题 沙箱、虚拟化、容器三者分开一一介绍的话我知道他们各自都是什么东西&#xff0c;但是如果把三者放在一起&#xff0c;它们之间到底什么关系&#xff1f;又有什么联系呢&#xff1f;我不是很明白&#xff01;&#xff01;&#xff01; 就比如说&#xff1a; 沙箱&#…...

webpack面试题

面试题&#xff1a;webpack介绍和简单使用 一、webpack&#xff08;模块化打包工具&#xff09;1. webpack是把项目当作一个整体&#xff0c;通过给定的一个主文件&#xff0c;webpack将从这个主文件开始找到你项目当中的所有依赖文件&#xff0c;使用loaders来处理它们&#x…...

Win系统权限提升篇UAC绕过DLL劫持未引号路径可控服务全检项目

应用场景&#xff1a; 1、常规某个机器被钓鱼后门攻击后&#xff0c;我们需要做更高权限操作或权限维持等。 2、内网域中某个机器被钓鱼后门攻击后&#xff0c;我们需要对后续内网域做安全测试。 #Win10&11-BypassUAC自动提权-MSF&UACME 为了远程执行目标的exe或者b…...