如何使用Python的Open3D开源库进行三维数据处理
简介
在本文中,我提供了一个关于如何使用Python的Open3D库(一个用于3D数据处理的开源库)来探索、处理和可视化3D模型的快速演练。
使用Open3D可视化的3D模型(链接https://sketchfab.com/3d-models/tesla-model-s-plaid-9de8855fae324e6cbbb83c9b5288c961处可找到原始3D模型)
如果您正在考虑处理特定任务的3D数据/模型,例如训练3D模型分类和/或分割AI模型,那么您会发现本演练是很有帮助的。互联网上的3D模型(在ShapeNet等数据集中)有多种格式,如.obj、.glb、.gltf等。使用Open3D等库,可以轻松处理、可视化这些模型,并将其转换为其他格式,如点云,因为这些格式更容易理解和解释。
注意,这篇文章也可以作为Jupyter笔记本提供给那些希望跟随并在本地运行代码的人。包含Jupyter笔记本以及所有其他数据和有关资源的zip文件可以从下面的链接下载。
3D Data Processing with Open3D.zip。
在本教程中,我将完成以下任务:
- 将三维模型加载为网格并将其可视化
- 通过采样点将网格转换为点云
- 从点云中删除隐藏点
- 将点云转换为数据帧
- 保存点云和数据帧
下面,让我们从导入所有必要的库开始:
# 导入open3d和所有其他必要的库。import open3d as o3d
import os
import copy
import numpy as np
import pandas as pd
from PIL import Imagenp.random.seed(42)
#正在检查open3d上安装的版本。o3d.__version__
# Open3D version used in this exercise: 0.16.0
将三维模型加载为网格并将其可视化
通过运行以下代码行,可以将3D模型读取为网格:
#定义三维模型文件的路径。
mesh_path = "data/3d_model.obj"# 使用open3d将三维模型文件读取为三维网格。
mesh = o3d.io.read_triangle_mesh(mesh_path)
要可视化网格,请运行以下代码行:
#可视化网格。
draw_geoms_list = [mesh]
o3d.visualization.draw_geometries(draw_geoms_list)
网格应该在一个新窗口中打开,看起来应该像下面的图像(请注意,网格打开时是静态图像,而不是像这里显示的动画图像)。可以使用鼠标指针根据需要旋转网格图像。
可视化为网格的3D模型(在估计曲面法线之前)
如上所述,汽车网格看起来不像典型的3D模型,而是渲染成了统一的灰色。这是因为网格没有任何关于三维模型中顶点和曲面的法线的信息。
什么是法线呢?-曲面在给定点处的法向量是垂直于该点处曲面的向量。法向量通常简称为“法线”。要关于此主题的内容,可以参考以下两个链接:法线向量和估计点云中的曲面法线。
可以通过运行以下代码行来估计上面三维网格的法线:
# 计算网格的法线。
mesh.compute_vertex_normals()#可视化网格。
draw_geoms_list = [mesh]
o3d.visualization.draw_geometries(draw_geoms_list)
一旦可视化,网格应该如下图所示出现。计算法线后,汽车将正确渲染,看起来像一个3D模型。
可视化为网格的3D模型(在估计表面法线之后)
现在,让我们创建一个XYZ坐标系,以了解这个汽车模型在欧几里得空间中的方向。XYZ坐标系可以覆盖在上面的3D网格上,并通过运行以下代码行进行可视化:
# 创建XYZ轴笛卡尔坐标系的网格。
# 该网格将显示X、Y和Z轴指向的方向,并且可以覆盖在3D网格上,以可视化其在欧几里得空间中的方向。
# X-axis : 红色箭头
# Y-axis : 绿色箭头
# Z-axis : 蓝色箭头
mesh_coord_frame = o3d.geometry.TriangleMesh.create_coordinate_frame(size=5, origin=[0, 0, 0])#使用坐标系可视化网格,以了解方向。
draw_geoms_list = [mesh_coord_frame, mesh]
o3d.visualization.draw_geometries(draw_geoms_list)
使用XYZ坐标系可视化的三维网格(X轴:红色箭头,Y轴:绿色箭头,Z轴:蓝色箭;[简记为——XYZ::RGB])
从上面的可视化中,我们可以看到这个汽车网格的方向如下:
- XYZ轴的原点:在汽车模型的体积中心(在上图中看不到,因为它在汽车网格内)。
- X轴(红色箭头):沿着汽车的长度尺寸,正X轴指向汽车的发动机罩(在上图中看不到,因为它在汽车网格内)。
- Y轴(绿色箭头):沿着汽车的高度尺寸,正Y轴指向汽车的车顶。
- Z轴(蓝色箭头):沿着汽车的宽度尺寸,正Z轴指向汽车的右侧。
现在,让我们来看看这个汽车模型里面有什么。为此,我们将在Z轴上裁剪网格,并移除汽车的右半部分(正Z轴)。
#使用其束框裁剪汽车网格以移除其右半部分(正Z轴)。
bbox = mesh.get_axis_aligned_bounding_box()
bbox_points = np.asarray(bbox.get_box_points())
bbox_points[:, 2] = np.clip(bbox_points[:, 2], a_min=None, a_max=0)
bbox_cropped = o3d.geometry.AxisAlignedBoundingBox.create_from_points(o3d.utility.Vector3dVector(bbox_points))
mesh_cropped = mesh.crop(bbox_cropped)# 可视化裁剪的网格。
draw_geoms_list = [mesh_coord_frame, mesh_cropped]
o3d.visualization.draw_geometries(draw_geoms_list)
在移除汽车右半部分的情况下,在Z轴上裁剪三维网格(正Z轴)。裁剪后的网格显示了此3D汽车模型中的详细内部
从上面的可视化中,我们可以看到这款车型有着详细的内饰。现在我们已经看到了这个3D网格内部的内容,我们可以在移除属于汽车内部的“隐藏”点之前将其转换为点云。
通过采样点将网格转换为点云
通过定义,我们希望从网格中采样的点的数量,可以在Open3D中轻松地将网格转换为点云。
#从网格中均匀采样100000个点,将其转换为点云。
n_pts = 100_000
pcd = mesh.sample_points_uniformly(n_pts)#可视化点云。
draw_geoms_list = [mesh_coord_frame, pcd]
o3d.visualization.draw_geometries(draw_geoms_list)
通过从三维网格中均匀采样100000个点创建的三维点云
请注意,上面点云中的颜色仅指示点沿Z轴的位置。
如果我们像裁剪上面的网格一样裁剪点云,它会是这样的:
#使用边界框裁剪汽车点云以移除其右半部分(正Z轴)。
pcd_cropped = pcd.crop(bbox_cropped)#可视化裁剪的点云。
draw_geoms_list = [mesh_coord_frame, pcd_cropped]
o3d.visualization.draw_geometries(draw_geoms_list)
在移除汽车右半部分的情况下在Z轴上裁剪的三维点云(正Z轴)。与上面裁剪的网格一样,裁剪的点云也显示了此3D汽车模型中的详细内部
我们在裁剪点云的可视化中看到,它还包含属于汽车模型内部的点。这是意料之中的,因为该点云是通过对整个网格中的点进行均匀采样而创建的。在下一节中,我们将删除这些属于汽车内部且不在点云外表面的“隐藏”点。
从点云中删除隐藏点
想象一下,你把一盏灯指向汽车模型的右侧。落在三维模型右外表面上的所有点都将被照亮,而点云中的所有其他点则不会被照亮。
显示Open3D的隐藏点移除如何从给定的视点处理点云的插图。所有被照亮的点都被视为“可见”,而所有其他点都被认为是“隐藏”
现在,让我们将这些照明点标记为“可见”,将所有未照明点标记“隐藏”。这些“隐藏”点还将包括属于汽车内部的所有点。
此操作在Open3D中称为“隐藏点删除”。为了使用Open3D在点云上执行此操作,请运行以下代码行:
# 定义隐藏点删除操作的摄影机和半径参数。
diameter = np.linalg.norm(np.asarray(pcd.get_min_bound()) - np.asarray(pcd.get_max_bound()))
camera = [0, 0, diameter]
radius = diameter * 100# 使用上面定义的摄影机和半径参数对点云执行隐藏点删除操作。
#输出是可见点的索引列表。
_, pt_map = pcd.hidden_point_removal(camera, radius)
使用上面的可见点索引输出列表,我们可以在可视化点云之前将可见点和隐藏点涂成不同的颜色。
# 将点云中的所有可见点绘制为蓝色,将所有隐藏点绘制为红色。pcd_visible = pcd.select_by_index(pt_map)
pcd_visible.paint_uniform_color([0, 0, 1]) #蓝色点是可见点(需要保留)。
print("No. of visible points : ", pcd_visible)pcd_hidden = pcd.select_by_index(pt_map, invert=True)
pcd_hidden.paint_uniform_color([1, 0, 0]) # 红色点是隐藏点(要删除)。
print("No. of hidden points : ", pcd_hidden)# 可视化点云中的可见(蓝色)和隐藏(红色)点。
draw_geoms_list = [mesh_coord_frame, pcd_visible, pcd_hidden]
o3d.visualization.draw_geometries(draw_geoms_list)
从上图所示的摄影机视点移除隐藏点操作后的点云。“可见”点为蓝色,而“隐藏”点为红色
从上面的可视化中,我们可以看到隐藏点移除操作是如何从给定的相机视点工作的。该操作消除了背景中被来自给定相机视点的前景中的点遮挡的所有点。
为了更好地理解这一点,我们可以再次重复相同的操作,但这次是在稍微旋转点云之后。实际上,我们正在努力改变这里的观点。但是,我们将旋转点云本身,而不是通过重新定义相机参数来改变它。
复制
#定义将度数转换为弧度的函数。
def deg2rad(deg):return deg * np.pi/180#将点云绕X轴旋转90度。
x_theta = deg2rad(90)
y_theta = deg2rad(0)
z_theta = deg2rad(0)
tmp_pcd_r = copy.deepcopy(pcd)
R = tmp_pcd_r.get_rotation_matrix_from_axis_angle([x_theta, y_theta, z_theta])
tmp_pcd_r.rotate(R, center=(0, 0, 0))#可视化旋转的点云。
draw_geoms_list = [mesh_coord_frame, tmp_pcd_r]
o3d.visualization.draw_geometries(draw_geoms_list)
围绕X轴旋转90度的三维点云。请注意,与以前不同的是,现在Y轴(绿色箭头)沿着汽车的宽度尺寸运行,Z轴(蓝色箭头)沿着车辆的高度尺寸运行。X轴(红色箭头)没有变化,它仍然沿着汽车的长度方向运行
图示显示了隐藏点删除操作如何从与前面相同的给定视点对旋转的点云进行操作。如前所述,所有照明点都被视为“可见”,而所有其他点都被认为是“隐藏”。
通过对旋转的汽车模型再次重复相同的过程,我们可以看到,这一次,落在3D模型(车顶)上外表面的所有点都会被照亮,而点云中的所有其他点都不会被照亮。
我们可以通过运行以下代码行,对旋转的点云重复隐藏点删除操作:
# 使用上面定义的相同摄影机和半径参数对旋转的点云执行隐藏点移除操作。
#输出是可见点的索引列表。
_, pt_map = tmp_pcd_r.hidden_point_removal(camera, radius)# 将旋转的点云中的所有可见点绘制为蓝色,将所有隐藏点绘制为红色。pcd_visible = tmp_pcd_r.select_by_index(pt_map)
pcd_visible.paint_uniform_color([0, 0, 1]) # 蓝色点是可见点(需要保留)。
print("No. of visible points : ", pcd_visible)pcd_hidden = tmp_pcd_r.select_by_index(pt_map, invert=True)
pcd_hidden.paint_uniform_color([1, 0, 0]) #红色点是隐藏点(要删除)。
print("No. of hidden points : ", pcd_hidden)#可视化旋转的点云中的可见(蓝色)和隐藏(红色)点。
draw_geoms_list = [mesh_coord_frame, pcd_visible, pcd_hidden]
o3d.visualization.draw_geometries(draw_geoms_list)
从上图所示的摄影机视点移除隐藏点操作后旋转的点云。同样,“可见”点为蓝色,而“隐藏”点为红色
上面旋转的点云的可视化清楚地说明了隐藏点移除操作是如何工作的。因此,现在,为了从这个汽车点云中移除所有“隐藏”点,我们可以通过将点云围绕所有三个轴从-90度到+90度稍微旋转来依次执行隐藏点移除操作。在每次删除隐藏点操作之后,我们可以聚合点的索引的输出列表。在所有隐藏点移除操作之后,点索引的聚合列表将包含所有未隐藏的点(即,位于点云的外表面上的点)。以下代码执行此顺序隐藏点删除操作:
# 定义一个函数以在X、Y和Z轴上旋转点云。
def get_rotated_pcd(pcd, x_theta, y_theta, z_theta):pcd_rotated = copy.deepcopy(pcd)R = pcd_rotated.get_rotation_matrix_from_axis_angle([x_theta, y_theta, z_theta])pcd_rotated.rotate(R, center=(0, 0, 0))return pcd_rotated# 定义一个函数以获取隐藏点移除操作的点云的相机和半径参数。
def get_hpr_camera_radius(pcd):diameter = np.linalg.norm(np.asarray(pcd.get_min_bound()) - np.asarray(pcd.get_max_bound()))camera = [0, 0, diameter]radius = diameter * 100return camera, radius# 定义一个函数,使用前面定义的摄影机和半径参数对点云执行隐藏点删除操作。
#输出是未隐藏的点的索引列表。
def get_hpr_pt_map(pcd, camera, radius):_, pt_map = pcd.hidden_point_removal(camera, radius) return pt_map
# 通过在三个轴中的每一个轴上将点云从-90度略微旋转到+90度,依次执行隐藏点移除操作,并在每次操作后聚合未隐藏的点的索引列表。# 定义一个列表来存储每个隐藏点删除操作的聚合输出列表。
pt_map_aggregated = []# 定义旋转点云的步长和角度值范围。
theta_range = np.linspace(-90, 90, 7)# 对顺序操作的次数进行计数。
view_counter = 1
total_views = theta_range.shape[0] ** 3# 获取隐藏点移除操作的相机和半径参数。
camera, radius = get_hpr_camera_radius(pcd)# 循环使用上面为每个轴定义的角度值。
for x_theta_deg in theta_range:for y_theta_deg in theta_range:for z_theta_deg in theta_range:print(f"Removing hidden points - processing view {view_counter} of {total_views}.")#按给定的角度值旋转点云。x_theta = deg2rad(x_theta_deg)y_theta = deg2rad(y_theta_deg)z_theta = deg2rad(z_theta_deg)pcd_rotated = get_rotated_pcd(pcd, x_theta, y_theta, z_theta)# 使用上面定义的摄影机和半径参数对旋转的点云执行隐藏点移除操作。pt_map = get_hpr_pt_map(pcd_rotated, camera, radius)# 聚合未隐藏的点的索引的输出列表。pt_map_aggregated += pt_mapview_counter += 1# 通过将聚合列表转换为集合,从聚合列表中删除所有重复的点。
pt_map_aggregated = list(set(pt_map_aggregated))
# 将点云中的所有可见点绘制为蓝色,将所有隐藏点绘制为红色。pcd_visible = pcd.select_by_index(pt_map_aggregated)
pcd_visible.paint_uniform_color([0, 0, 1]) # 蓝色点是可见点(需要保留)。
print("No. of visible points : ", pcd_visible)pcd_hidden = pcd.select_by_index(pt_map_aggregated, invert=True)
pcd_hidden.paint_uniform_color([1, 0, 0]) # 红色点是隐藏点(要删除)。
print("No. of hidden points : ", pcd_hidden)# 可视化点云中的可见(蓝色)和隐藏(红色)点。
draw_geoms_list = [mesh_coord_frame, pcd_visible, pcd_hidden]
# draw_geoms_list = [mesh_coord_frame, pcd_visible]
# draw_geoms_list = [mesh_coord_frame, pcd_hidden]
o3d.visualization.draw_geometries(draw_geoms_list)
从同一摄影机视点执行所有顺序隐藏点移除操作后的点云。聚合的“可见”点(即点云外表面上的点)为蓝色,而“隐藏”点(如不在点云外表面对的点)则为红色
让我们再次裁剪点云,看看属于汽车内部的点。
#使用先前定义的边界框裁剪可见点的点云,以移除其右半部分(正Z轴)。
pcd_visible_cropped = pcd_visible.crop(bbox_cropped)# 使用先前定义的边界框裁剪隐藏点的点云,以移除其右半部分(正Z轴)。
pcd_hidden_cropped = pcd_hidden.crop(bbox_cropped)# 可视化裁剪的点云。
draw_geoms_list = [mesh_coord_frame, pcd_visible_cropped, pcd_hidden_cropped]
o3d.visualization.draw_geometries(draw_geoms_list)
在所有顺序的隐藏点移除操作之后裁剪的点云,以红色显示属于3D汽车模型内部的所有“隐藏”点
从隐藏点移除操作后裁剪的点云的上述可视化中,我们可以看到,属于汽车模型内部的所有“隐藏”点(红色)现在都与点云外表面的“可见”点(蓝色)分离。
将点云转换为数据帧
正如人们所期望的那样,点云中每个点的位置可以由三个数值定义——X、Y和Z坐标。请记住,在上面的部分中,我们还估计了3D网格中每个点的曲面法线。当我们从该网格中采样点以创建点云时,点云中的每个点还包含与这些曲面法线相关的三个附加属性——X、Y和Z方向上的法线单位向量坐标。
因此,为了将点云转换为数据帧,点云中的每个点都可以用以下七个属性列在一行中来表示:
- X坐标(浮动)
- Y坐标(浮动)
- Z坐标(浮动)
- X方向上的法向量坐标(浮点)
- Y方向上的法向量坐标(浮点)
- Z方向上的法向量坐标(浮动)
- 可见点(布尔值True或False)
通过运行以下代码行,可以将点云转换为数据帧:
# 为点云创建一个数据帧,其中包含所有点的X、Y和Z位置坐标以及X、Y、Z方向上的法向单位向量坐标。
pcd_df = pd.DataFrame(np.concatenate((np.asarray(pcd.points), np.asarray(pcd.normals)), axis=1),columns=["x", "y", "z", "norm-x", "norm-y", "norm-z"])# 使用上面隐藏点删除操作中的点索引聚合列表,添加一列以指示点是否可见。
pcd_df["point_visible"] = False
pcd_df.loc[pt_map_aggregated, "point_visible"] = True
这将返回如下所示的数据帧,其中每个点都是由上面解释的七个属性列表示的行。
转换为数据帧的三维点云
保存点云和数据帧
现在可以通过运行以下代码行来保存点云(删除隐藏点之前和之后)和数据帧:
# 将整个点云保存为.pcd文件。
pcd_save_path = "data/3d_model.pcd"
o3d.io.write_point_cloud(pcd_save_path, pcd)# 将删除了隐藏点的点云保存为.pcd文件。
pcd_visible_save_path = "data/3d_model_hpr.pcd"
o3d.io.write_point_cloud(pcd_visible_save_path, pcd_visible)# 将点云数据帧保存为.csv文件。
pcd_df_save_path = "data/3d_model.csv"
pcd_df.to_csv(pcd_df_save_path, index=False)
三维模型(顶部:整体,底部:裁剪)可视化为:1——网格;2——一个点云;3——删除隐藏点后的点云
相关文章:

如何使用Python的Open3D开源库进行三维数据处理
简介 在本文中,我提供了一个关于如何使用Python的Open3D库(一个用于3D数据处理的开源库)来探索、处理和可视化3D模型的快速演练。 使用Open3D可视化的3D模型(链接https://sketchfab.com/3d-models/tesla-model-s-plaid-9de8855fa…...

HarmonyOS应用开发者基础认证试题
判断题 1.Ability是系统调度应用的最小单元,是能够完成一个独立功能的组件。一个应用可以包含一个或多个Ability。(true) 2.Tabs组件仅可包含子组件TabsContent,每一个页签对应一个内容视图即TabContet组件。(true) 3.使用http模块发起网络请求时&#…...

Android Camera2开启电子防抖(EIS)和光学防抖(OIS)
刚好当前项目有录像功能,使用了第三方框架是基于Camera2引擎开发,当使用 Camera2 API 开发相机应用时,启用和关闭 EIS(电子防抖)是一个重要的功能。EIS 可以帮助减少相机拍摄时的抖动,从而提高图像和视频的…...

劲爆:Sam Altman 回归CEO专访确认Q*的存在
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...

Electronica慕尼黑电子展 Samtec团队与21ic分享虎家产品与方案
【摘要/前言】 “希望但凡是能够使用到连接器的场合都有Samtec的身影” 在慕尼黑上海电子展现场,Samtec华东区销售经理章桢彦先生在与21ic副主编刘岩轩老师的采访中,如是说道。这是一种愿景,更是Samtec的努力方向。短短一句话,…...

Vue基本使用(一)
📑前言 本文主要是【Vue】——Vue基本使用的文章,如果有什么需要改进的地方还请大佬指出⛺️ 🎬作者简介:大家好,我是听风与他🥇 ☁️博客首页:CSDN主页听风与他 🌄每日一句&#x…...

Android:BackStackRecord
BackStackRecord:fragment回退栈,继承自FragmentTransaction,并且实现了OpGenerator接口,OpGenerator接口用来添加或弹出事务的,后面会提到。 从《Android:从源码看FragmentManager如何工作》文章知道,每次beginTransaction会创建一个BackStackRecord对象,改对象持有f…...

微信小程序 slider 翻转最大和最小值
微信小程序 slider 翻转最大和最小值 场景代码示例index.wxmlindex.jsutil.js 参考资料 场景 我想使用 slider 时最左边是 10 最右是 -10。 但是想当然的直接改成<slider min"10" max"-10" step"1" /> 并没用。 查了文档和社区也没有现成…...

APITable免费开源的多维表格与可视化数据库本地部署公网远程访问
APITable免费开源的多维表格与可视化数据库公网远程访问 文章目录 APITable免费开源的多维表格与可视化数据库公网远程访问前言1. 部署APITable2. cpolar的安装和注册3. 配置APITable公网访问地址4. 固定APITable公网地址 前言 vika维格表作为新一代数据生产力平台,…...

配电房综合监控系统
配电房综合监控系统是一种集成了实时监控、数据采集、远程控制等多功能的系统,用于对配电房进行全方位的监测和管理。 力安科技配电室综合监控系统依托电易云-智慧电力物联网,实现配电室环境监测、有害气体监测、安防监控、采暖通风、门禁、灯光、风机、…...

【JavaSE】集合(学习笔记)
一、数据结构 1、栈 压栈 / 弹栈栈顶元素、栈底元素先进后出 2、队列 入队列 / 出队列前端、后端先进先出 3、数组 查询效率高,增删效率低 4、链表 查询效率低(必须从头找),增删效率高 5、哈希表 比较方法哈希值equals结构:数组 链…...

Mybatis 的简单运用介绍
Mybatis 用于操作数据库 操作数据库肯定需要: 1.SQL语句 2.数据库对象和 java 对象的映射 接下来我们看看怎么使用 Mybatis 我们先搞一些数据库内容 然后将其这些内容和Java对象进行映射 再创建一个类实现 select * from 再写一个类证明上述代码是否可以实现 别忘了在appli…...

python的itertools库
itertools常用的方法如下: import itertools 1. 生成的列表累加,在生成新的列表x itertools.accumulate(range(10))print(list(x))结果:[0, 1, 3, 6, 10, 15, 21, 28, 36, 45] 2. 连接多个列表或者迭代器x itertools.chain(range(3), rang…...

STM32/GD32_分散加载
Q:如何将一个变量、某个源文件的函数在编译阶段就存储在用户指定的区域? KEIL环境:.map后缀文件、.sct后缀文件 IAR环境:.map后缀文件、.icf后缀文件 【map文件】 对固件里面的变量、函数、常量等元素的存储空间进行分配的说明…...

go clean
移除目标文件和缓存文件。 更多信息:https://golang.org/cmd/go/#hdr-Remove_object_files_and_cached_files. 只打印移除命令,而不会真正移除任何东西: go clean -n 删除编译缓存: go clean -cache 删除所有测试结果缓存&…...

BUUCTF [ACTF新生赛2020]swp 1
BUUCTF:https://buuoj.cn/challenges 题目描述: 得到的 flag 请包上 flag{} 提交。 密文: 下载附件,得到一个.tar文件。 解题思路: 1、使用WinRAR解压.tar文件,得到两个.zip文件。 解压wget.zip文件,得…...

【PTA题目】7-4 缩写期刊名 分数 10
7-4 缩写期刊名 分数 10 全屏浏览题目 切换布局 作者 黄龙军 单位 绍兴文理学院 科研工作者经常要向不同的期刊投稿。但不同期刊的参考文献的格式往往各不相同。有些期刊要求参考文献所发表的期刊名必须采用缩写形式,否则直接拒稿。现对于给定的期刊名ÿ…...

什么是 TLS/SSL 握手
TLS/SSL 握手是一个加密过程,每当客户端(如浏览器)与服务器建立连接时,都会在后台进行,此握手协议有助于客户端和服务器之间的安全连接,从而促进隐私、数据完整性和机密性。 TLS/SSL 握手何时发生 每当客…...

和鲸科技与国科环宇建立战略合作伙伴关系,以软硬件一体化解决方案促进科技创新
近日,在国科环宇土星云算力服务器产品发布会暨合作伙伴年度会上,和鲸科技与国科环宇正式完成战略伙伴签约仪式,宣布达成战略合作伙伴关系。未来,双方将深化合作,充分发挥在产品和市场方面的互补优势,为企事…...

[C++]六大默认成员函数详解
☃️个人主页:fighting小泽 🌸作者简介:目前正在学习C和Linux 🌼博客专栏:C入门 🏵️欢迎关注:评论👊🏻点赞👍🏻留言💪🏻 …...

组合(回溯算法)
77. 组合 - 力扣(LeetCode) 题目描述 给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 样例输入 示例 1: 输入:n 4, k 2 输出: [[2,4],[3,4],[2,3],…...

力扣:1419. 数青蛙
题目: 代码: class Solution { public:int minNumberOfFrogs(string croakOfFrogs){string s "croak";int ns.size();//首先创建一个哈希表来标明每个元素出现的次数!vector<int>hash(n); //不用真的创建一个hash表用一个数…...

java_springboot企业人事考勤请假管理信息系统rsglxx+jsp
(1)熟练掌握Java开发的原理和方法 (2)熟练学习掌握SSM框架 (3)熟悉软件开发的流程 (4)了解中内外互联网中所主流的技术 (5)深层次的了解计算机学科领域的知识…...

java项目之木里风景文化管理平台(ssm+vue)
项目简介 木里风景文化管理平台实现了以下功能: 前台功能:用户进入系统可以实现首页,旅游公告,景区,景区商品,景区美食,旅游交通工具,红黑榜,个人中心,后台…...

源码安装mysql
使用源码安装mysql,这里选择的版本是mysql5.7.35 ,系统是Centos7.6 官网下载地址:https://downloads.mysql.com/archives/community/ 下载源码压缩包 [rootlocalhost ~]# cd /opt[rootlocalhost opt]# wget https://downloads.mysql.com/archives/get/…...

注解方式优雅的实现Redisson分布式锁
1.前言 随着微服务的快速推进,分布式架构也得到蓬勃的发展,那么如何保证多进程之间的并发则成为需要考虑的问题。因为服务是分布式部署模式,本地锁Reentrantlock和Synchnorized就无法使用了,当然很多同学脱口而出的基于Redis的se…...

服务器安装JDK17 版本显示JDK8
服务器之前安装的是JDK8,后面升级JDK17后,发现执行 java -vsrsion 显示的是此时我的环境变量已经换成了JAVA17的路径 输入: vim /etc/profile 解决办法: 1.更新自己环境变量 bash export JAVA_HOME/usr/local/jdk-17.0.7 …...

利用MCMC 获得泊松分布
写出概率流方程如下 if state 0: if np.random.random() < min([Lambda/2, 1]):state 1else:passelif state 1:if choose_prob_state[i] < 0.5:#选择 1 -> 0,此时的接受概率为min[2/Lambda, 1]if np.random.random() < min([2/Lambda, 1]…...

docker-compose脚本编写及常用命令
安装 linux DOCKER_CONFIG/usr/local/lib/docker/cli-plugins sudo mkdir -p $DOCKER_CONFIG/cli-plugins sudo curl -SL https://521github.com/docker/compose/releases/download/v2.6.1/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose sudo c…...

编译企业微信会话内容存档PHP版SDK扩展
1.下载SDK 如果克隆不了,就页面下载 git clone https://github.com/pangdahua/php7-wxwork-finance-sdk2.下载企微官网C版本的最新sdk文件 下载地址:https://wwcdn.weixin.qq.com/node/wework/images/sdk_20201116.rar 下载以后将解压之后的文件夹里l…...