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

Python项目实战:基于napari的3D可视化(点云+slice)

文章目录

  • 一、napari 简介
  • 二、napari 安装与更新
  • 三、napari【巨巨巨大的一个BUG】
  • 四、napari 使用指南
    • 4.1、菜单栏(File + View + Plugins + Window + Help)
    • 4.2、Window:layer list(参数详解)
    • 4.3、Window:layer controls(points layer + shapes layer + labels layer)
  • 五、项目实战
    • 5.1、查看图像:napari.view_image()
    • 5.2、添加图像:viewer.add_image()
    • 5.3、添加点云:viewer.add_points()
    • 5.4、添加形状:viewer.add_shapes() —— 获取线条坐标(起点和终点)
  • 六、在napari中自定义组件,并与PyQt完成交互

一、napari 简介

基于 Python 编写的快速、交互式多维图像查看器

🥗napari 官网首页:https://napari.org/0.4.18/index.html#
🥪napari 使用案例:https://napari.org/0.4.18/gallery.html#gallery

二、napari 安装与更新

  • 安装napari:pip install napari
  • 更新napari:pip install --upgrade napari

三、napari【巨巨巨大的一个BUG】

  • 【BUG】:点击View - Toggle Full Screen将最大化软件界面,且菜单栏和很多按钮都将不可用。
  • 【影响】:此时,想要任何操作都无法退出最大化,即使关闭后重试,卸载后重试都无法达到,没有试过关机后重试。
  • 【解决方法】:Window + Tab切换窗口,菜单栏可以短暂有效且可点击,瞬间点击View - Toggle Full Screen,可解除BUG。

四、napari 使用指南

4.1、菜单栏(File + View + Plugins + Window + Help)

File(文件)
1Open File打开文件
2Opencv File as Stack打开文件(适用于大尺度)
3Open Sample + napari builtins(提供了很多的内置样本)初学者可以直接导入后研究
4Preferences设置(主题 + 快捷键等等)
5Save Selected Layer(s)(所有帧图像)保存选定的单层或多层(指定后缀,修改图像格式)
6Save All Layers(所有帧图像)保存所有层(指定后缀,修改图像格式)
7Save Screenshot(单帧图像)保存当前窗口内容(不显示界面)
8Save Screenshot with Viewer(单帧图像)保存整个视图内容(图像 + 界面)
  • Plugins(插件):安装和卸载插件(也可以自定义)
View(视图)
1Axes
2Scale Bar刻度条
3Toggle Full Screen切换全屏
4Toggle Menubar Visibity切换菜单可见性
5Toggle Paly切换面板
6Toggle Layer Tooltips切换图层工具提示
7Toggle Activity Dock切换活动区
Window(窗口)
1console控制面板(命令行窗口)
2layer controls图层控制(点层、形状层、标签层)
3layer list图层列表
Help(帮助)直接跳转官网页面
1Getting started开始
2Tutorials教程
3Using Layers Guides使用图层指南
4Examples Gallery示例图库
5Release Notes版本说明
6napari homepagenapari 主页
7napari Infonapari 信息

4.2、Window:layer list(参数详解)

在这里插入图片描述

4.3、Window:layer controls(points layer + shapes layer + labels layer)

在这里插入图片描述

五、项目实战

5.1、查看图像:napari.view_image()

在napari查看器中显示单个或多个图像,并提供了许多可选参数来自定义图像的显示。

在这里插入图片描述

import napari
import tifffileimage_path = 'output_8bit.tif'
marked_image = tifffile.imread(image_path)viewer = napari.view_image(marked_image, name='image', rgb=False)
napari.run()"""
#########################################################################################################
# 函数说明:napari.view_image(data, channel_axis=None, name=None, colormap=None, blending=None, interpolation=None, gamma=None, 
# is_pyramid=None, rgb=None, scale=None, translate=None, contrast_limits=None, rendering=None)
# 输入参数:
#       - data:要显示的图像数据。可以是以下格式之一:
#                 2D NumPy array:灰度图像数据。
#                 3D NumPy array:3D图像数据,例如多张2D图像叠加形成的图像序列。
#                 4D NumPy array:4D图像数据,例如多通道彩色图像。
#                 List of 2D, 3D, or 4D arrays:多个图像数据列表。
#                 Dask array:支持分块加载的大型图像数据。
#                 ImageData:来自dask_image.imread()等函数的图像数据对象。
#         channel_axis:用于多通道图像的通道轴的索引。默认值为None,表示使用最后一个轴作为通道轴。
#       - name:图像的名称,将在napari查看器中显示。
#       - colormap:图像的颜色映射。可以是字符串表示的颜色映射名称,或是colormap函数。默认值为None,表示使用默认颜色映射。
#         blending:图像的混合模式。可以是字符串表示的混合模式名称,例如"translucent"、"additive"等。默认值为None,表示使用默认混合模式。
#         interpolation:图像的插值方法。可以是字符串表示的插值方法名称,例如"nearest"、"bilinear"、"bicubic"等。默认值为None,表示使用默认插值方法。
#         gamma:图像的gamma值,用于对图像进行伽马校正。默认值为None,表示不进行伽马校正。
#         is_pyramid:布尔值,用于指示是否使用金字塔结构显示图像。默认值为None,表示不使用金字塔结构。
#         rgb:布尔值,用于指示输入图像是否为RGB彩色图像。默认值为None,表示根据输入图像数据自动判断。
#         scale:图像的缩放因子。可以是单个值,表示在所有轴上应用相同的缩放,也可以是每个轴的缩放因子列表。默认值为None,表示不进行缩放。
#         translate:图像的平移量。可以是单个值,表示在所有轴上应用相同的平移,也可以是每个轴的平移量列表。默认值为None,表示不进行平移。
#         contrast_limits:图像的对比度限制,用于控制图像显示的亮度范围。可以是单个值,表示在所有轴上应用相同的对比度限制,也可以是每个轴的对比度限制列表。默认值为None,表示不设置对比度限制。
#         rendering:图像的渲染模式。可以是字符串表示的渲染模式名称,例如"mip"、"translucent"、"attenuated_mip"等。默认值为None,表示使用默认渲染模式。
#########################################################################################################
"""

5.2、添加图像:viewer.add_image()

将单个或多个图像添加到napari查看器中,并提供了多个可选参数来自定义图像的显示。

在这里插入图片描述

import napari
import tifffileimage_path = '561result-1-part.tif'
marked_image = tifffile.imread(image_path)viewer = napari.Viewer()  # 创建napari视图
viewer.add_image(marked_image, name="image", colormap='red')  # 添加图像(指定红色)
################################################################################
# 隐藏面板
# viewer.window.qt_viewer.controls.hide()  # 隐藏后不可使用该功能(重新打开也不行)
# viewer.window.qt_viewer.layers.hide()# viewer.window.qt_viewer.controls.close()
# viewer.window.qt_viewer.layers.close()
################################################################################
napari.run()  # 显示napari图形界面"""
#########################################################################################################
# 函数说明:viewer.add_image(data, *, name=None, scale=None, translate=None, contrast_limits=None, 
#                          colormap=None, blending=None, visible=True, opacity=1.0, interpolation='bilinear', 
#                          rendering='mip', rgb=None, colormap_range=None)
# 输入参数:
#       - data:要添加的图像数据。可以是以下格式之一:
#                 2D NumPy array:灰度图像数据。
#                 3D NumPy array:3D图像数据,例如多张2D图像叠加形成的图像序列。
#                 4D NumPy array:4D图像数据,例如多通道彩色图像。
#       - name:图像的名称,将在napari查看器中显示。
#         scale:图像的缩放因子。可以是单个值,表示在所有轴上应用相同的缩放,也可以是每个轴的缩放因子列表。
#         translate:图像的平移量。可以是单个值,表示在所有轴上应用相同的平移,也可以是每个轴的平移量列表。
#         contrast_limits:图像的对比度限制,用于控制图像显示的亮度范围。可以是单个值,表示在所有轴上应用相同的对比度限制,也可以是每个轴的对比度限制列表。
#       - colormap:图像的颜色映射。可以是字符串表示的颜色映射名称,或是colormap函数。
#         blending:图像的混合模式。可以是字符串表示的混合模式名称,例如"translucent"、"additive"等。
#         visible:图像是否可见。布尔值,默认为True。
#         opacity:图像的不透明度。默认为1.0,表示完全不透明。
#         interpolation:图像的插值方法。可以是字符串表示的插值方法名称,例如"nearest"、"bilinear"、"bicubic"等。
#         rendering:图像的渲染模式。可以是字符串表示的渲染模式名称,例如"mip"、"translucent"、"attenuated_mip"等。
#         rgb:布尔值,用于指示输入图像是否为RGB彩色图像。
#         colormap_range:颜色映射的范围。可以是字符串,例如"auto"或"full",表示自动计算颜色映射范围或使用完整范围。
#########################################################################################################
"""

5.3、添加点云:viewer.add_points()

将点的坐标和可选的其他属性添加到napari查看器中,并提供了多个可选参数来自定义点云的显示。

  • viewer.add_points()用于添加点云数据,但不能直接显示。需要先添加viewer.view_image(),然后再显示点云数据。
  • 点云数据:由离散点(x, y, z)坐标的集合组成。

在这里插入图片描述

import napari
import tifffile
import numpy as np# (1)通过tifffile加载tif图像
marked_image = tifffile.imread('marked_image.tif')# (2)获取图像的长宽高
if len(marked_image.shape) == 3:  # 灰度3D图像:10x10x10depth, height, width = marked_image.shape
elif len(marked_image.shape) == 4:  # 彩色3D图像:3x10x10x10depth, height, width, _ = marked_image.shape# (3)根据图像类型自适应变量值
if marked_image.dtype == np.uint8:max_gray_value = 255
elif marked_image.dtype == np.uint16:max_gray_value = 65535
elif marked_image.dtype == np.uint32:max_gray_value = 4294967295
####################################################################
# (4.1)提取指定像素
indices = np.argwhere(marked_image == max_gray_value)# (4.2)指定范围内的像素值,获取坐标,并绘制为标记点
# min_gray_value = 50
# max_gray_value = max_gray_value - 1
# indices = np.argwhere((marked_image >= min_gray_value) & (marked_image <= max_gray_value))
####################################################################
viewer = napari.Viewer()  # 创建napari查看器
viewer.add_image(marked_image)  # 添加图像到napari视图
viewer.add_points(indices[:, [0, 1, 2]], size=2, face_color='red', shading='spherical', edge_width=0)  # 添加点云
napari.run()  # 显示napari图形界面

5.4、添加形状:viewer.add_shapes() —— 获取线条坐标(起点和终点)

注意:shapes层和image_data层是两个独立的层,故线的坐标映射到image_data需要进行高度和宽度限制。
在这里插入图片描述
在这里插入图片描述

import napari
import cv2# (1)加载图像
image_path = 'blank.png'
image_data = cv2.imread(image_path)
print("height:", image_data.shape[0], "width:", image_data.shape[1])
# (2)创建napari Viewer
viewer = napari.Viewer()
viewer.add_image(image_data)  # 添加图像
# 添加形状(线条 + 线宽 + 颜色)
shapes_layer = viewer.add_shapes(data=None, shape_type='line', edge_width=3, edge_color='red')  
shapes_layer.mode = 'add_line'  # 直接开始绘制线条
napari.run()  # 运行napari# (3)打印坐标
# image_shape = image_data.shape  # 获取图像的形状
line_layer = viewer.layers['Shapes']  # 获取绘制的线的图层
line_coordinates1 = []  # 获取绘制的所有线的坐标
line_coordinates2 = []  # 获取绘制的所有线的坐标:删除超出图像的线条if line_layer.data:  # 检查图层数据是否存在for line in line_layer.data:  # 遍历线的坐标coordinates1 = [line[0, 0], line[0, 1], line[1, 0], line[1, 1]]line_coordinates1.append(coordinates1)for line in line_layer.data:  # 遍历线的坐标# 【高度限制】:删除超出图像的线条if line[0, 0] < 0:line[0, 0] = 0elif line[0, 0] > image_data.shape[0]:line[0, 0] = image_data.shape[0]if line[1, 0] < 0:line[1, 0] = 0elif line[1, 0] > image_data.shape[0]:line[1, 0] = image_data.shape[0]# 【宽度限制】:删除超出图像的线条if line[0, 1] < 0:line[0, 1] = 0elif line[0, 1] > image_data.shape[1]:line[0, 1] = image_data.shape[1]if line[1, 1] < 0:line[1, 1] = 0elif line[1, 1] > image_data.shape[1]:line[1, 1] = image_data.shape[1]coordinates2 = [line[0, 0], line[0, 1], line[1, 0], line[1, 1]]line_coordinates2.append(coordinates2)# 输出所有坐标(shapes:线坐标)for idx, coordinates in enumerate(line_coordinates1):print(f'Line {idx + 1} coordinates1:', coordinates)print("")# 输出所有坐标(image:线坐标映射到图像的坐标):高度限制+宽度限制for idx, coordinates in enumerate(line_coordinates2):print(f'Line {idx + 1} coordinates2:', coordinates)

六、在napari中自定义组件,并与PyQt完成交互

在napari中自定义组件与PyQt新建组件的方法相同,区别是需要将插件的主窗口添加到napari界面的控制面板中:self.viewer.window.add_dock_widget(widget, area='right') # 添加到napari的右侧,其中:widget是插件的主窗口。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

import tifffile
import napari
import numpy as np
import sys
import os
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, \QPushButton, QFileDialog, QTextEdit, QSlider, QCheckBox
from PyQt5.QtCore import Qtclass Window(QMainWindow):def __init__(self):super().__init__()self.setWindowTitle("Window")##########################################################layout = QVBoxLayout()button_layout = QHBoxLayout()self.load_button = QPushButton("Load Image", self)self.load_button.clicked.connect(self.load_image)self.image_name_label = QLabel("")button_layout.addWidget(self.load_button)button_layout.addWidget(self.image_name_label)layout.addLayout(button_layout)##########################################################widget = QWidget()widget.setLayout(layout)self.setCentralWidget(widget)########################################################### 初始化参数self.image_path = ""self.image_name = ""##########################################################def load_image(self):file_dialog = QFileDialog()image_path, _ = file_dialog.getOpenFileName(self, "Select Image", "", "Image Files (*.tif *.png *.jpg *.jpeg)")if image_path:self.image_path = image_pathself.image_name = os.path.basename(image_path)self.image_name_label.setText(self.image_name)self.image_slices = tifffile.imread(image_path)self.napari_gray_view()  # 调用napari_gray_view方法来显示第一个切片def napari_gray_view(self):# (1)napari:创建视图、添加图层、显示视图self.viewer = napari.Viewer()  # 创建napari视图self.viewer.add_image(self.image_slices, name='image')  # 添加napari图层########################################################################## (2)自定义组件########################################################################## (2.1)创建滑动条self.slider = QSlider()  # 新建滑动条self.slider.setMinimum(0)  # 设置滑动条的最小值self.slider.setMaximum(np.max(self.image_slices))  # 设置滑动条的最大值self.slider.setValue(0)  # 设置滑动条的初始值# (2.2)创建标签self.slider_label = QLabel(str(self.slider.value()))# (2.3)复选框self.checkbox = QCheckBox("checkbox")  # 复选框self.slider.setEnabled(False)  # 复选框的初始状态:Falseself.input_box = QLineEdit()  # 新建输入框self.input_box.setEnabled(True)  # 复选框的初始状态:Trueself.input_label = QLabel("range: " + str(np.min(self.image_slices)) + "/" + str(np.max(self.image_slices)))  # 输入框标签# (3)创建布局并将滑动条和标签添加到布局中layout = QVBoxLayout()layout.addWidget(self.slider)layout.addWidget(self.slider_label)layout.addWidget(self.checkbox)layout.addWidget(self.input_box)layout.addWidget(self.input_label)# (4)创建一个QWidget作为插件的主窗口widget = QWidget()widget.setLayout(layout)# (5)连接复选框的状态变化信号与槽函数self.checkbox.stateChanged.connect(self.onCheckboxStateChanged)self.slider.valueChanged.connect(self.napari_update_gray)  # 根据滑动条的值,显示第一个切片self.input_box.returnPressed.connect(self.napari_update_gray)  # 根据输入框的值,显示第一个切片# (6)将插件的主窗口添加到napari界面的控制面板中self.viewer.window.add_dock_widget(widget, area='right')  # 添加到napari的右侧########################################################################## (7)napari:显示视图self.viewer.window.show()def onCheckboxStateChanged(self, state):if state == Qt.Checked:self.slider.setEnabled(True)self.input_box.setEnabled(False)else:self.slider.setEnabled(False)self.input_box.setEnabled(True)def napari_update_gray(self):# (1)获取napari视图中的图层对象,并获取图像数据napari_image = self.image_slices.data# (2)获取当前切片滑动条的值current_slice = int(self.viewer.dims.current_step[0])# (3)获取当前灰度滑动条的值self.slider_label.setText(str(self.slider.value()))if self.checkbox.isChecked():current_gray = self.slider.value()else:current_gray = int(self.input_box.text())print("current_slice:", current_slice, "current_gray:", current_gray)if __name__ == '__main__':app = QApplication(sys.argv)window = Window()window.show()sys.exit(app.exec_())

相关文章:

Python项目实战:基于napari的3D可视化(点云+slice)

文章目录 一、napari 简介二、napari 安装与更新三、napari【巨巨巨大的一个BUG】四、napari 使用指南4.1、菜单栏&#xff08;File View Plugins Window Help&#xff09;4.2、Window&#xff1a;layer list&#xff08;参数详解&#xff09;4.3、Window&#xff1a;layer…...

go的gin和gorm框架实现切换身份的接口

使用go的gin和gorm框架实现切换身份的接口&#xff0c;接收前端发送的JSON对象&#xff0c;查询数据库并更新&#xff0c;返回前端信息 接收前端发来的JSON对象&#xff0c;包含由openid和登陆状态组成的一个string和要切换的身份码int型 后端接收后判断要切换的身份是否低于该…...

仓库库存管理难点在哪?有哪些仓库库存管理软件?

仓库库存管理常见的难点有&#xff1a;库存数据混乱、库存成本较高、库存积压严重等问题 使用仓库管理软件&#xff0c;企业可以更好地管理库存、优化供应链、提高操作效率&#xff0c;并基于准确的数据进行决策和规划&#xff0c;从而解决许多仓库库存管理中的难题。 一、仓库…...

服务链路追踪

一、基础概念 1.背景 对于一个大型的几十个、几百个微服务构成的微服务架构系统&#xff0c;通常会遇到下面一些问题&#xff0c;比如&#xff1a; 如何串联整个调用链路&#xff0c;快速定位问题&#xff1f;如何理清各个微服务之间的依赖关系&#xff1f;如何进行各个微服…...

macOS - 安装使用 libvirt、virsh

文章目录 关于 libvirt使用安装启动服务virsh 交互模式virsh 帮助命令 关于 libvirt libvirt 官网&#xff1a; https://libvirt.org/gitlab : https://gitlab.com/libvirt/libvirtgithub : https://github.com/libvirt/libvirt 只读&#xff0c;gitlab 的镜像 libvirt是一套…...

Windows Server 2019设置使用照片查看器查看图片的设置方法

1、使用winR快捷键快速打开运行&#xff0c;输入regedit打开注册表&#xff1a; 2、在注册表中找到&#xff1a;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Photo Viewer\Capabilities\FileAssociations 3、在右侧新建字符串项&#xff1a; 4、例如新建两项.jpg 和.png值…...

【需求输出】流程图输出

文章目录 1、什么是流程图2、绘制流程图的工具和基本要素3、流程图的分类和应用场景4、如何根据具体场景输出流程图 1、什么是流程图 2、绘制流程图的工具和基本要素 3、流程图的分类和应用场景 4、如何根据具体场景输出流程图...

opencv+ffmpeg+QOpenGLWidget开发的音视频播放器demo

前言 本篇文档的demo包含了 1.使用OpenCV对图像进行处理&#xff0c;对图像进行置灰&#xff0c;旋转&#xff0c;抠图&#xff0c;高斯模糊&#xff0c;中值滤波&#xff0c;部分区域清除置黑&#xff0c;背景移除&#xff0c;边缘检测等操作&#xff1b;2.单纯使用opencv播放…...

stable-diffusion-webui 的模型更新

shared.py和sd_models.py中 shared.py: options_templates.update(options_section((sd, "Stable Diffusion"), {"sd_model_checkpoint": OptionInfo(None, "Stable Diffusion checkpoint", gr.Dropdown, lambda: {"choices": list_…...

Gin模板语法

Gin模板语法 文章目录 <center> Gin模板语法前提提醒Gin框架启动服务器模板解析模板渲染遇到不同目录下相同的文件如何加载和渲染自定义函数加载静态文件 前提提醒 由于有了前面template包的基础,所以该笔记不再过多详细分析 Gin框架启动服务器 语法: r:gin.Default()/…...

Go http.Handle和http.HandleFunc的路由问题

Golang的net/http包提供了原生的http服务&#xff0c;其中http.Handle和http.HandleFunc是两个重要的路由函数。 1. 函数介绍 http.HandleFunc和http.Handle的函数原型如下&#xff0c;其中DefaultServeMux是http包提供的一个默认的路由选择器。 func HandleFunc(pattern st…...

如何使用Kali Linux进行渗透测试?

1. 渗透测试简介 渗透测试是通过模拟恶意攻击&#xff0c;评估系统、应用或网络的安全性的过程。Kali Linux为渗透测试人员提供了丰富的工具和资源&#xff0c;用于发现漏洞、弱点和安全风险。 2. 使用Kali Linux进行渗透测试的步骤 以下是使用Kali Linux进行渗透测试的基本…...

简单易用且高效的跨平台开发工具:Xojo 2023 for Mac

Xojo for Mac是Mac平台上一个跨平台的针对桌面、Web、移动和Raspberry Pi的快速应用程序开发软件。与其他多平台开发工具相比&#xff0c;Xojo for Mac为开发人员提供了显着的生产率提高。 Xojo for Mac具有拖放功能&#xff0c;使您能够快速创建用户界面设计&#xff0c;然后…...

HIVE SQL实现分组字符串拼接concat

在Mysql中可以通过group_concat()函数实现分组字符串拼接&#xff0c;在HIVE SQL中可以使用concat_ws()collect_set()/collect_list()函数实现相同的效果。 实例&#xff1a; abc2014B92015A82014A102015B72014B6 1.concat_wscollect_list 非去重拼接 select a ,concat_ws(-…...

【问心篇】渴望、热情和选择

加班太严重完全没有时间学习&#xff0c;怎么办&#xff1f; 我真的不算聪明的人&#xff0c;但是&#xff0c;我对学习真的是有渴望的。说得好听一点&#xff0c;我希望自己在不停地成长&#xff0c;不辜负生活在这个信息化大变革的时代。说得不好的一点&#xff0c;就是我从…...

【贪心】CF1841 D

Codeforces 题意&#xff1a; 思路&#xff1a; 首先模拟一下样例 并没有发现什么 那么就去考虑特殊情况&#xff0c;看看有没有什么启发 考虑一个大区间包含所有小区间的情形&#xff0c;这种情况就是在这么多区间中找出两个区间 换句话说&#xff0c;这么多区间组成一个…...

移动端预览指定链接的pdf文件流

场景 直接展示外部系统返回的获取文件流时出现了跨域问题&#xff1a; 解决办法 1. 外部系统返回的请求头中调整&#xff08;但是其他系统不会给你改的&#xff09; 2. 我们系统后台获取文件流并转为新的文件流提供给前端 /** 获取传入url文件流 */ GetMapping("/get…...

【Go 基础篇】Go语言字符类型:解析字符的本质与应用

介绍 字符类型是计算机编程中用于表示文本和字符的数据类型&#xff0c;是构建字符串的基本单位。在Go语言&#xff08;Golang&#xff09;中&#xff0c;字符类型具有独特的特点和表示方式&#xff0c;包括Unicode编码、字符字面值以及字符操作。本篇博客将深入探讨Go语言中的…...

Java基础(十二)面向对象编程 OOP

一、抽象数据类型 1.面向对象基本概念 1. 面向对象 面向对象程序设计&#xff08;OOP&#xff09;是一种基于对象概念的软件开发方法&#xff0c;是目前软件开发的主流方式。 常见面向对象的语言&#xff1a;C 、Python 、Java 常见面向过程的语言&#xff1a;C 面向对象的三…...

在阿里云服务器上安装Microsoft SharePoint 2016流程

本教程阿里云百科分享如何在阿里云ECS上搭建Microsoft SharePoint 2016。Microsoft SharePoint是Microsoft SharePoint Portal Server的简称。SharePoint Portal Server是一个门户站点&#xff0c;使得企业能够开发出智能的门户站点。 目录 背景信息 步骤一&#xff1a;添加…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

在rocky linux 9.5上在线安装 docker

前面是指南&#xff0c;后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

Mysql中select查询语句的执行过程

目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析&#xff08;Parser&#xff09; 2.4、执行sql 1. 预处理&#xff08;Preprocessor&#xff09; 2. 查询优化器&#xff08;Optimizer&#xff09; 3. 执行器…...

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要&#xff1a; 近期&#xff0c;在使用较新版本的OpenSSH客户端连接老旧SSH服务器时&#xff0c;会遇到 "no matching key exchange method found"​, "n…...

Java数值运算常见陷阱与规避方法

整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...

【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅

目录 前言 操作系统与驱动程序 是什么&#xff0c;为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中&#xff0c;我们在使用电子设备时&#xff0c;我们所输入执行的每一条指令最终大多都会作用到硬件上&#xff0c;比如下载一款软件最终会下载到硬盘上&am…...

若依登录用户名和密码加密

/*** 获取公钥&#xff1a;前端用来密码加密* return*/GetMapping("/getPublicKey")public RSAUtil.RSAKeyPair getPublicKey() {return RSAUtil.rsaKeyPair();}新建RSAUti.Java package com.ruoyi.common.utils;import org.apache.commons.codec.binary.Base64; im…...

海云安高敏捷信创白盒SCAP入选《中国网络安全细分领域产品名录》

近日&#xff0c;嘶吼安全产业研究院发布《中国网络安全细分领域产品名录》&#xff0c;海云安高敏捷信创白盒&#xff08;SCAP&#xff09;成功入选软件供应链安全领域产品名录。 在数字化转型加速的今天&#xff0c;网络安全已成为企业生存与发展的核心基石&#xff0c;为了解…...