如有错误,恳请指出。
这篇文章主要是介绍点云采样与聚类的实现。
文章目录
点云下采样是对点云以一定的采样规则重新进行采样,目的是在保证点云整体几何特征不变的情况下,降低点云的密度,进而可以降低相关处理的数据量和算法复杂度。下面介绍三种下采样方式:体素下采样、均匀下采样、随机下采样
体素下采样就是把落在每个体素中的点用一个点来表示。这个点的坐标取值就是体素中所有点坐标的平均值,也就是体素中各个点的质心,点云质心可以通过pcd.get_center()或者是简单的np.mean(axis=1)来获得。
Open3d中体素的下采样函数有两个接口:voxel_down_sample与voxel_down_sample_and_trace,参数说明如下所示:
def voxel_down_sample(self, voxel_size): # real signature unknown; restored from __doc__
"""
voxel_down_sample(self, voxel_size)
Function to downsample input pointcloud into output pointcloud with a voxel. Normals and colors are averaged if they exist.
Args:
voxel_size (float): Voxel size to downsample into.
Returns:
open3d.geometry.PointCloud 直接返回点云pcd
"""
pass
def voxel_down_sample_and_trace(self, voxel_size, min_bound, max_bound, approximate_class=False): # real signature unknown; restored from __doc__
"""
voxel_down_sample_and_trace(self, voxel_size, min_bound, max_bound, approximate_class=False)
Function to downsample using PointCloud.VoxelDownSample. Also records point cloud index before downsampling
Args:
voxel_size (float): Voxel size to downsample into.
min_bound (numpy.ndarray[numpy.float64[3, 1]]): Minimum coordinate of voxel boundaries 体素边界的最小坐标
max_bound (numpy.ndarray[numpy.float64[3, 1]]): Maximum coordinate of voxel boundaries 体素边界的最大坐标
approximate_class (bool, optional, default=False) :approximate_class就是用来控制采样后的点云颜色
当approximate_class=True时,体素采样后的点的颜色由体素中大多数点的颜色决定
当approximate_class=False时,体素采样后的点的颜色由体素中所有点的平均颜色决定
Returns:
Tuple[open3d.geometry.PointCloud, numpy.ndarray[numpy.int32[m, n]], List[open3d.utility.IntVector]]
返回两个内容:稀疏后的点云pcd 与 稀疏后的点云在原点云中的索引
"""
pass
参考代码:
def open3d_downsample():
# 读取点云文件
pcd_path = r"E:\Study\Machine Learning\Dataset3d\points_pcd\cat.pcd"
pcd = open3d.io.read_point_cloud(pcd_path)
pcd = open3d.geometry.PointCloud(pcd)
# 数值越大,下采样倍数越高,也就越稀疏
voxel_size = 10
pcd_sample1 = deepcopy(pcd)
pcd_sample1.translate([60, 0, 0]) # x轴左移60(向左)
pcd_sample1.paint_uniform_color(color=[0, 0, 1]) # 蓝色
pcd_sample1 = pcd_sample1.voxel_down_sample(voxel_size=voxel_size)
bound = (pcd_sample1.get_min_bound(), pcd_sample1.get_max_bound())
print(bound)
pcd_sample2 = deepcopy(pcd)
pcd_sample2.translate([0, 0, 60]) # z轴正向移60(向上)
pcd_sample2.paint_uniform_color(color=[0, 1, 0]) # 绿色
pcd_sample2 = pcd_sample2.voxel_down_sample_and_trace(voxel_size=voxel_size,
min_bound=pcd_sample2.get_min_bound() + 10,
max_bound=pcd_sample2.get_max_bound() - 10,
approximate_class=False)[0]
bound = (pcd_sample2.get_min_bound(), pcd_sample2.get_max_bound())
print(bound)
# 可视化点云列表
open3d.visualization.draw_geometries([pcd, pcd_sample1, pcd_sample2],
window_name="pointcloud downsampler",
width=800,
height=600)
结果展示:

均匀采样是指每隔固定的点数采样一次。样本按点的顺序执行,始终选择从第 1 个点开始,而不是随机选择。显然点存储的顺序不同,得到的结果也会不一样。从这个角度来看,这种方法比较适合有序点云的降采样。
如果点云本身不均匀,那么以固定点数采样很有可能造成某一部分的点云没被采样到。相比于体素的采样方法,点云均匀采样后的点数是固定可控的,而体素采样后的点云数量是不可控的。(ps:随机采样后的点数也是可控的)
参数说明:
def uniform_down_sample(self, every_k_points): # real signature unknown; restored from __doc__
"""
uniform_down_sample(self, every_k_points)
Function to downsample input pointcloud into output pointcloud uniformly. The sample is performed in the order of the points with the 0-th point always chosen, not at random.
Args:
every_k_points (int): Sample rate, the selected point indices are [0, k, 2k, ...]
Returns:
open3d.geometry.PointCloud
"""
pass
参考代码:
# 均匀下采样
pcd_sample4 = deepcopy(pcd)
pcd_sample4.translate([-60, 0, 0]) # z轴负向移60(向下)
pcd_sample4 = pcd_sample4.uniform_down_sample(every_k_points=10)
print('pcd_sample3 center: ', pcd_sample4.get_center())
在原始点云中随机采样一定点数的点,open3d中的随机采样函数为random_down_sample,其参数是采样后点云数量相对于原始点云数量的比例。
参数说明:
def random_down_sample(self, sampling_ratio): # real signature unknown; restored from __doc__
"""
random_down_sample(self, sampling_ratio)
Function to downsample input pointcloud into output pointcloud randomly. The sample is generated by randomly sampling the indexes from the point cloud.
Args:
sampling_ratio (float): Sampling ratio, the ratio of number of selected points to total number of points[0-1]
Returns:
open3d.geometry.PointCloud
"""
pass
参考代码:
# 随机下采样
pcd_sample3 = deepcopy(pcd)
pcd_sample3.translate([0, 0, -60]) # z轴负向移60(向下)
pcd_sample3 = pcd_sample3.random_down_sample(sampling_ratio=0.2)
print('pcd_sample3 center: ', pcd_sample3.get_center())
除open3d的方法外,也可以自己自定义随机采样的方式(利用numpy的随机模块),这样会更加灵活。numpy的随机模块笔记:Numpy | np.random随机模块的使用介绍
points = np.array(pcd.points)
n = np.random.choice(len(points), 500, replace=False) # 从points中以相同的几率随机采样500个点,同时还可以设置权重p,返回的是原始点云中的索引
pcd.points = open3d.utility.Vector3dVector(points[n])
完整代码:
def open3d_downsample():
# 读取点云文件
pcd_path = r"E:\Study\Machine Learning\Dataset3d\points_pcd\cat.pcd"
pcd = open3d.io.read_point_cloud(pcd_path)
pcd = open3d.geometry.PointCloud(pcd)
pcd.paint_uniform_color(color=[0.5, 0.5, 0.5])
# 数值越大,下采样倍数越高
voxel_size = 10
pcd_sample1 = deepcopy(pcd)
pcd_sample1.translate([60, 0, 0]) # x轴左移60(向左)
pcd_sample1.paint_uniform_color(color=[0, 0, 1]) # 蓝色
pcd_sample1 = pcd_sample1.voxel_down_sample(voxel_size=voxel_size)
bound = (pcd_sample1.get_min_bound(), pcd_sample1.get_max_bound())
print(bound)
pcd_sample2 = deepcopy(pcd)
pcd_sample2.translate([0, 0, 60]) # z轴正向移60(向上)
pcd_sample2.paint_uniform_color(color=[0, 1, 0]) # 绿色
pcd_sample2 = pcd_sample2.voxel_down_sample_and_trace(voxel_size=voxel_size,
min_bound=pcd_sample2.get_min_bound() + 10,
max_bound=pcd_sample2.get_max_bound() - 10,
approximate_class=False)[0]
bound = (pcd_sample2.get_min_bound(), pcd_sample2.get_max_bound())
print(bound)
# 随机下采样
pcd_sample3 = deepcopy(pcd)
pcd_sample3.translate([0, 0, -60]) # z轴负向移60(向下)
pcd_sample3 = pcd_sample3.random_down_sample(sampling_ratio=0.2)
print('pcd_sample3 center: ', pcd_sample3.get_center())
# 均匀下采样
pcd_sample4 = deepcopy(pcd)
pcd_sample4.translate([-60, 0, 0]) # z轴负向移60(向下)
pcd_sample4 = pcd_sample4.uniform_down_sample(every_k_points=10)
print('pcd_sample3 center: ', pcd_sample4.get_center())
# 可视化点云列表
open3d.visualization.draw_geometries([pcd, pcd_sample1, pcd_sample2, pcd_sample3, pcd_sample4],
window_name="pointcloud downsampler",
width=800,
height=600)
结果展示:

参考资料:
1. 三种点云下采样方法(一) — open3d python
2. 三种点云下采样方法(二)— open3d python
在sklearn工具包中,有大量的聚类算法提供使用,这里的点云数据可以有效的配置sklearn工具包,以实现效果。其中,open3d也自带了dbscan聚类的使用接口。这里不涉及具体的聚类算法解析。

open3d中DBSCAN聚类方法的函数为cluster_dbscan,且有且仅有这么一种聚类算法,所以建议使用sklearn进行聚类。(可以跳过这节直接看下一节)
第一个参数eps表示DBSCAN算法确定点密度时和邻近点的距离大小,即考虑eps距离范围内的点进行密度计算,如果点云数据过于稀疏,那么这里的参数需要设置得大一些,确保部分点可以实现连通。min_points表示组成一类最少需要多少个点。print_progress可以用来显示运行的进度。
labels返回聚类成功的类别,-1表示没有分到任何类中的点,原始点云中每个点都会分别得到一个类别标签。
参考代码:
# 点云聚类测试
def open3d_cluster():
# 读取点云文件
pcd_path = r"E:\Study\Machine Learning\Dataset3d\points_pcd\cat.pcd"
pcd = open3d.io.read_point_cloud(pcd_path)
pcd = open3d.geometry.PointCloud(pcd)
# 聚类距离设置为4,组成一类至少需要20个点
labels = pcd.cluster_dbscan(eps=4, min_points=20, print_progress=True)
max_label = max(labels)
print(max_label)
# 随机构建n+1种颜色,这里需要归一化
colors = np.random.randint(1, 255, size=(max_label + 1, 3)) / 255.
colors = colors[labels] # 每个点云根据label确定颜色
colors[np.array(labels) < 0] = 0 # 噪点配置为黑色
pcd.colors = open3d.utility.Vector3dVector(colors) # 格式转换(由于pcd.colors需要设置为Vector3dVector格式)
# 可视化点云列表
open3d.visualization.draw_geometries([pcd],
window_name="cluster",
width=800,
height=600)
结果展示:

我们可以利用sklearn中丰富的聚类算法库,为点云进行聚类。Sklearn中的参数在 机器学习学习专栏 中有介绍到。
这里尝试将猫点云聚类成3类,并用不同的颜色进行显示
import open3d
import numpy as np
from copy import deepcopy
from sklearn import cluster
def open3d_sklearn_cluster():
# 读取点云文件
pcd_path = r"E:\Study\Machine Learning\Dataset3d\points_pcd\cat.pcd"
pcd = open3d.io.read_point_cloud(pcd_path)
pcd = open3d.geometry.PointCloud(pcd)
pcd.paint_uniform_color(color=[0, 0, 0])
# 点云聚类
n_clusters = 3 # 聚类簇数
points = np.array(pcd.points)
kmeans = cluster.KMeans(n_clusters=n_clusters, random_state=42)
kmeans.fit(points)
labels = kmeans.labels_
# 显示颜色设置
colors = np.random.randint(0, 255, size=(n_clusters, 3)) / 255
colors = colors[labels]
pcd_cluster = deepcopy(pcd)
pcd_cluster.translate([50, 0, 0])
pcd_cluster.colors = open3d.utility.Vector3dVector(colors)
# 点云可视化
open3d.visualization.draw_geometries([pcd, pcd_cluster],
window_name="sklearn cluster",
width=800,
height=600)
结果展示:

Sklearn聚类的效果还是相当好的,直接将猫规规矩矩的分成了3个部分。
def open3d_sklearn_cluster():
# 读取点云文件
pcd_path = r"E:\Study\Machine Learning\Dataset3d\points_pcd\cat.pcd"
pcd = open3d.io.read_point_cloud(pcd_path)
pcd = open3d.geometry.PointCloud(pcd)
pcd.paint_uniform_color(color=[0, 0, 0])
# 点云聚类
points = np.array(pcd.points)
dbscan = cluster.DBSCAN(eps=4, min_samples=20) # 使用DBSCAN算法进行聚类
dbscan.fit(points)
labels = dbscan.labels_
# 显示颜色设置
colors = np.random.randint(0, 255, size=(max(labels) + 1, 3)) / 255 # 需要设置为n+1类,否则会数据越界造成报错
colors = colors[labels] # 很巧妙,为每个label直接分配一个颜色
colors[labels < 0] = 0 # 噪点直接设置为0,用黑色显示
pcd_cluster = deepcopy(pcd)
pcd_cluster.translate([50, 0, 0])
pcd_cluster.colors = open3d.utility.Vector3dVector(colors)
# 点云可视化
open3d.visualization.draw_geometries([pcd, pcd_cluster],
window_name="sklearn cluster",
width=800,
height=600)
结果展示:

与open3d官方实现的效果类似,但是sklearn可以有效兼容,也就是说点云聚类直接使用sklearn工具即可。其他的聚类算法直接根据API进行稍微更改即可使用,这里的代码参数也不过介绍,在我的机器学习专栏中有笔记介绍过,详细见:机器学习学习专栏
参考资料:
1. 八种点云聚类方法(一)— DBSCAN
2. 八种点云聚类方法(二)— KMeans
3. Sklearn官方手册:cluster部分
RANSAC为Random Sample Consensus的缩写,即随机抽样一致性,它是根据一组包含异常数据的样本数据集,计算出数据的数学模型参数,得到有效样本数据的算法。RANSAC算法的基本理论基础是大数定律,也就是当采样数达到一定数量后采样的数据就会符合它自身原有的概率属性。这是一种通过概率的方式来进行拟合。
以RANSAC平面分割为例,由于三个点可以确定一个平面,因此RANSAC会随机选择三个点来构建一个平面,并用点云中实际上有多少个点落到这个平面上来作为评估这个平面的正确程度。当随机抽样的次数足够多时,我们有较大概率获得所需要的平面: A x + B y + C z + D = 0 Ax + By + Cz + D = 0 Ax+By+Cz+D=0
def segment_plane(self, distance_threshold, ransac_n, num_iterations, seed=None): # real signature unknown; restored from __doc__
"""
segment_plane(self, distance_threshold, ransac_n, num_iterations, seed=None)
Segments a plane in the point cloud using the RANSAC algorithm.
Args:
distance_threshold (float): Max distance a point can be from the plane model, and still be considered an inlier.
ransac_n (int): Number of initial points to be considered inliers in each iteration.
num_iterations (int): Number of iterations.
seed (Optional[int], optional, default=None): Seed value used in the random generator, set to None to use a random seed value with each function call.
Returns:
Tuple[numpy.ndarray[numpy.float64[4, 1]], List[int]]
返回: (A,B,C,D)作为一个平面,对于平面上每个点(x,y,z)满足上面的平面方程; 这个函数还会返回内点索引的列表
"""
测试代码:
def open3d_segment():
# 读取点云文件
pcd_path = r"E:\Study\Machine Learning\Dataset3d\points_pcd\cat.pcd"
pcd = open3d.io.read_point_cloud(pcd_path)
pcd = open3d.geometry.PointCloud(pcd)
pcd.paint_uniform_color(color=[0.5, 0.5, 0.5])
plane_model, inliers = pcd.segment_plane(distance_threshold=1, ransac_n=10, num_iterations=1000)
[A, B, C, D] = plane_model
print(f"Plane equation: {A:.2f}x + {B:.2f}y + {C:.2f}z + {D:.2f} = 0")
colors = np.array(pcd.colors)
colors[inliers] = [0, 0, 1] # 平面内的点设置为蓝色
pcd.colors = open3d.utility.Vector3dVector(colors)
# 点云可视化
open3d.visualization.draw_geometries([pcd],
window_name="segment",
width=800,
height=600)
结果展示:

参考资料:
简要归纳各函数的使用方法,最后贴上完整代码与展示效果
open3d中对应的函数为TriangleMesh.create_from_point_cloud_alpha_shape,其关键参数为alpha。alpha是该方法在搜索外轮廓时的半径大小。alpha值越小,网格的细节就越多,分辨率越高。
# 1. Alpha shapes轮廓提取
pcd_rc1 = deepcopy(pcd)
pcd_rc1.translate([-100, 0, 50])
mesh_rc1 = open3d.geometry.TriangleMesh.create_from_point_cloud_alpha_shape(pcd_rc1, alpha=6)
mesh_rc1 = open3d.geometry.TriangleMesh(mesh_rc1)
mesh_rc1.paint_uniform_color([1, 0, 0]) # 红色
open3d中对应的函数为TriangleMesh.create_from_point_cloud_ball_pivoting,其关键参数为radii。radii是滚球的半径,而且可以设置多个值,也就是可以用多个尺寸的滚球来进行三角面构建。重建需要先计算点云法向量。
# 2. Ball pivoting滚球算法
pcd_rc2 = deepcopy(pcd)
pcd_rc2.translate([-50, 0, 50])
pcd_rc2.estimate_normals( # 法向量计算
search_param=open3d.geometry.KDTreeSearchParamHybrid(radius=0.01, max_nn=30)
)
radii = [2, 5, 8]
mesh_rc2 = open3d.geometry.TriangleMesh.create_from_point_cloud_ball_pivoting(
pcd=pcd_rc2,
radii=open3d.utility.DoubleVector(radii)
)
mesh_rc2 = open3d.geometry.TriangleMesh(mesh_rc2)
mesh_rc2.paint_uniform_color([0, 1, 0]) # 绿色
open3d中对应的函数为 TriangleMesh.create_from_point_cloud_poisson。该函数的一个重要参数是depth,它定义了用于曲面重建的八叉树的深度,因此表示生成的三角形网格的分辨率。depth值越高,网格的细节就越多,分辨率越高。
create_from_point_cloud_poisson除返回重建的表面之外,还会返回各处重建后的点密度,通过设置一个阈值来去除一些低密度处的重建结果(可以配合分位点来设置)。重建需要先计算点云法向量。
# 3. Poisson泊松曲面重建
pcd_rc3 = deepcopy(pcd)
pcd_rc3.translate([0, 0, 50])
pcd_rc3.estimate_normals( # 法向量计算
search_param=open3d.geometry.KDTreeSearchParamHybrid(radius=0.01, max_nn=30)
)
mesh_rc3, densities = open3d.geometry.TriangleMesh.create_from_point_cloud_poisson(pcd_rc3, depth=12)
mesh_rc3 = open3d.geometry.TriangleMesh(mesh_rc3)
# 设置阈值去除低密度重建结果
threshold_value = np.quantile(densities, 0.35) # 寻找低密度列表中35%的分位数,返回的是数值而不是索引
vertices_to_remove = densities < threshold_value # 低于分位数的值设置为False, 依次对其进行消除
mesh_rc3.remove_vertices_by_mask(vertices_to_remove)
mesh_rc3.paint_uniform_color([0, 0, 1])
open3d中对应的函数为 VoxelGrid.create_from_point_cloud,其关键参数体素尺寸voxel_size=0.05。尺寸越小,网格的细节就越多,分辨率越高。严格上来说,这种方法只是一种下采样的效果。
# 4. Voxel体素重建
pcd_rc4 = deepcopy(pcd)
pcd_rc4.translate([50, 0, 50])
pcd_rc4.paint_uniform_color(color=[0, 1, 1])
mesh_rc4 = open3d.geometry.VoxelGrid.create_from_point_cloud(pcd_rc4, voxel_size=2)
完整代码展示:
def open3d_reconstruction():
# 读取点云文件
pcd_path = r"E:\Study\Machine Learning\Dataset3d\points_pcd\cat.pcd"
pcd = open3d.io.read_point_cloud(pcd_path)
pcd = open3d.geometry.PointCloud(pcd)
pcd.paint_uniform_color(color=[0, 0, 0])
# 1. Alpha shapes轮廓提取
pcd_rc1 = deepcopy(pcd)
pcd_rc1.translate([-100, 0, 50])
mesh_rc1 = open3d.geometry.TriangleMesh.create_from_point_cloud_alpha_shape(pcd_rc1, alpha=6)
mesh_rc1 = open3d.geometry.TriangleMesh(mesh_rc1)
mesh_rc1.paint_uniform_color([1, 0, 0]) # 红色
# 2. Ball pivoting滚球算法
pcd_rc2 = deepcopy(pcd)
pcd_rc2.translate([-50, 0, 50])
pcd_rc2.estimate_normals( # 法向量计算
search_param=open3d.geometry.KDTreeSearchParamHybrid(radius=0.01, max_nn=30)
)
radii = [2, 5, 8]
mesh_rc2 = open3d.geometry.TriangleMesh.create_from_point_cloud_ball_pivoting(
pcd=pcd_rc2,
radii=open3d.utility.DoubleVector(radii)
)
mesh_rc2 = open3d.geometry.TriangleMesh(mesh_rc2)
mesh_rc2.paint_uniform_color([0, 1, 0]) # 绿色
# 3. Poisson泊松曲面重建
pcd_rc3 = deepcopy(pcd)
pcd_rc3.translate([0, 0, 50])
pcd_rc3.estimate_normals( # 法向量计算
search_param=open3d.geometry.KDTreeSearchParamHybrid(radius=0.01, max_nn=30)
)
mesh_rc3, densities = open3d.geometry.TriangleMesh.create_from_point_cloud_poisson(pcd_rc3, depth=12)
mesh_rc3 = open3d.geometry.TriangleMesh(mesh_rc3)
# 设置阈值去除低密度重建结果
threshold_value = np.quantile(densities, 0.35) # 寻找低密度列表中35%的分位数,返回的是数值而不是索引
vertices_to_remove = densities < threshold_value # 低于分位数的值设置为False, 依次对其进行消除
mesh_rc3.remove_vertices_by_mask(vertices_to_remove)
mesh_rc3.paint_uniform_color([0, 0, 1])
# 4. Voxel体素重建
pcd_rc4 = deepcopy(pcd)
pcd_rc4.translate([50, 0, 50])
pcd_rc4.paint_uniform_color(color=[0, 1, 1])
mesh_rc4 = open3d.geometry.VoxelGrid.create_from_point_cloud(pcd_rc4, voxel_size=2)
# 点云可视化
pcd.translate([-25, 0, 0])
open3d.visualization.draw_geometries([pcd, mesh_rc1, mesh_rc2, mesh_rc3, mesh_rc4],
window_name="rebuild",
width=800,
height=600)
结果展示:

参考资料:
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
这里是Ruby新手。完成一些练习后碰壁了。练习:计算一系列成绩的字母等级创建一个方法get_grade来接受测试分数数组。数组中的每个分数应介于0和100之间,其中100是最大分数。计算平均分并将字母等级作为字符串返回,即“A”、“B”、“C”、“D”、“E”或“F”。我一直返回错误:avg.rb:1:syntaxerror,unexpectedtLBRACK,expecting')'defget_grade([100,90,80])^avg.rb:1:syntaxerror,unexpected')',expecting$end这是我目前所拥有的。我想坚持使用下面的方法或.join,
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList()Obt
本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01 客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02 数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit
Unity自动旋转动画1.开门需要门把手先动,门再动2.关门需要门先动,门把手再动3.中途播放过程中不可以再次进行操作觉得太复杂?查看我的文章开关门简易进阶版效果:如果这个门可以直接打开的话,就不需要放置"门把手"如果门把手还有钥匙需要旋转,那就可以把钥匙放在门把手的"门把手",理论上是可以无限套娃的可调整参数有:角度,反向,轴向,速度运行时点击Test进行测试自己写的代码比较垃圾,命名与结构比较拉,高手轻点喷,新手有类似的需求可以拿去做参考上代码usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;u
之前说过10之后的版本没有3dScan了,所以还是9.8的版本或者之前更早的版本。 3d物体扫描需要先下载扫描的APK进行扫面。首先要在手机上装一个扫描程序,扫描现实中的三维物体,然后上传高通官网,在下载成UnityPackage类型让Unity能够使用这个扫描程序可以从高通官网上进行下载,是一个安卓程序。点到Tools往下滑,找到VuforiaObjectScanner下载后解压数据线连接手机,将apk文件拷入手机安装然后刚才解压文件中的Media文件夹打开,两个PDF图打印第一张A4-ObjectScanningTarget.pdf,主要是用来辅助扫描的。好了,接下来就是扫描三维物体。将瓶
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.