2025-05-27 15:46:31 +08:00

70 lines
2.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import open3d as o3d
import numpy as np
from matplotlib import pyplot as plt
import cv2
color_raw = o3d.io.read_image("aucpuncture2point/configs/using_img/color.png")
depth_raw = o3d.io.read_image("aucpuncture2point/configs/using_img/depth.png")
# 模拟空洞将指定区域的深度值设置为无效值0或者其他很大的值
def create_occlusion(depth_raw, occlusion_rect=(290, 160, 370, 270)):
"""
Create an occlusion (hole) in the depth image by setting a specific rectangular region to zero (no depth).
The rect is defined by (x_min, y_min, x_max, y_max).
"""
depth_image = np.asarray(depth_raw)
x_min, y_min, x_max, y_max = occlusion_rect
# 将指定区域的深度设置为无效可以选择设置为0或其他特定的无效值
depth_image[y_min:y_max, x_min:x_max] = 0 # 模拟遮挡深度值为0
return o3d.geometry.Image(depth_image)
# 在深度图像中创建遮挡
depth_with_occlusion = create_occlusion(depth_raw)
# 将深度图像转换为 NumPy 数组
depth_image = np.asarray(depth_with_occlusion)
# 创建掩膜深度值为0的区域
mask = (depth_image == 0).astype(np.uint8)
# 使用 OpenCV 的 inpaint 函数进行深度修复
depth_image_inpainted = cv2.inpaint(depth_image, mask, inpaintRadius=3, flags=cv2.INPAINT_TELEA)
# 将修复后的深度图像转换回 Open3D 图像
depth_fixed = o3d.geometry.Image(depth_image_inpainted)
rgbd_image = o3d.geometry.RGBDImage.create_from_color_and_depth(
color_raw, depth_fixed, convert_rgb_to_intensity=False)
intrinsics = o3d.camera.PinholeCameraIntrinsic()
intrinsics.set_intrinsics(640, 480, 453.17746, 453.17746, 325.943024, 243.559982)
# 从RGBD生成点云
pcd = o3d.geometry.PointCloud.create_from_rgbd_image(rgbd_image, intrinsics)
pcd.transform([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])
pcd = pcd.voxel_down_sample(voxel_size=0.01)
# 估计点云的法向量
pcd.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.1, max_nn=30))
# 计算几何中心
centroid = np.mean(np.asarray(pcd.points), axis=0)
# 调整法向量方向,使其指向人体内侧
normals = np.asarray(pcd.normals)
for i, normal in enumerate(normals):
point = np.asarray(pcd.points)[i]
if np.dot(normal, centroid - point) < 0: # 法向量与到中心向量的点积如果小于0则需要翻转
normals[i] *= -1
pcd.normals = o3d.utility.Vector3dVector(normals)
# 创建一个小球表示几何中心
sphere = o3d.geometry.TriangleMesh.create_sphere(radius=0.02) # 半径为0.02的小球
sphere.paint_uniform_color([1, 0, 0]) # 颜色为红色
sphere.translate(centroid) # 将小球平移到几何中心
# 可视化点云和几何中心
o3d.visualization.draw_geometries([pcd, sphere], point_show_normal=True)