update strategy and overlap rate compute method
This commit is contained in:
@@ -17,11 +17,50 @@ class DataLoadUtil:
|
||||
return path
|
||||
|
||||
@staticmethod
|
||||
def load_model_points(root, scene_name):
|
||||
model_path = os.path.join(root, scene_name, "sampled_model_points.txt")
|
||||
def get_sampled_model_points_path(root, scene_name):
|
||||
path = os.path.join(root,scene_name, f"sampled_model_points.txt")
|
||||
return path
|
||||
|
||||
@staticmethod
|
||||
def get_scene_seq_length(root, scene_name):
|
||||
camera_params_path = os.path.join(root, scene_name, "camera_params")
|
||||
return len(os.listdir(camera_params_path))
|
||||
|
||||
@staticmethod
|
||||
def load_downsampled_world_model_points(root, scene_name):
|
||||
model_path = DataLoadUtil.get_sampled_model_points_path(root, scene_name)
|
||||
model_points = np.loadtxt(model_path)
|
||||
return model_points
|
||||
|
||||
@staticmethod
|
||||
def save_downsampled_world_model_points(root, scene_name, model_points):
|
||||
model_path = DataLoadUtil.get_sampled_model_points_path(root, scene_name)
|
||||
np.savetxt(model_path, model_points)
|
||||
|
||||
@staticmethod
|
||||
def load_original_model_points(model_dir, object_name):
|
||||
model_path = os.path.join(model_dir, object_name, "mesh.obj")
|
||||
mesh = trimesh.load(model_path)
|
||||
return mesh.vertices
|
||||
|
||||
|
||||
@staticmethod
|
||||
def load_scene_info(root, scene_name):
|
||||
scene_info_path = os.path.join(root, scene_name, "scene_info.json")
|
||||
with open(scene_info_path, "r") as f:
|
||||
scene_info = json.load(f)
|
||||
return scene_info
|
||||
|
||||
@staticmethod
|
||||
def load_target_object_pose(root, scene_name):
|
||||
scene_info = DataLoadUtil.load_scene_info(root, scene_name)
|
||||
target_name = scene_info["target_name"]
|
||||
transformation = scene_info[target_name]
|
||||
location = transformation["location"]
|
||||
rotation_euler = transformation["rotation_euler"]
|
||||
pose_mat = trimesh.transformations.euler_matrix(*rotation_euler)
|
||||
pose_mat[:3, 3] = location
|
||||
return pose_mat
|
||||
|
||||
@staticmethod
|
||||
def load_depth(path):
|
||||
depth_path = os.path.join(os.path.dirname(path), "depth", os.path.basename(path) + ".png")
|
||||
@@ -83,8 +122,9 @@ class DataLoadUtil:
|
||||
y = (j - cam_intrinsic[1, 2]) * z / cam_intrinsic[1, 1]
|
||||
|
||||
points_camera = np.stack((x, y, z), axis=-1).reshape(-1, 3)
|
||||
mask = mask.reshape(-1, 3)
|
||||
target_mask = np.all(mask == target_mask_label)
|
||||
mask = mask.reshape(-1)
|
||||
|
||||
target_mask = mask == target_mask_label
|
||||
target_points_camera = points_camera[target_mask]
|
||||
target_points_camera_aug = np.concatenate([target_points_camera, np.ones((target_points_camera.shape[0], 1))], axis=-1)
|
||||
|
||||
@@ -104,10 +144,10 @@ class DataLoadUtil:
|
||||
return point_cloud['points_world']
|
||||
|
||||
@staticmethod
|
||||
def get_point_cloud_list_from_seq(root, seq_idx, num_frames):
|
||||
def get_point_cloud_list_from_seq(root, scene_name, num_frames):
|
||||
point_cloud_list = []
|
||||
for idx in range(num_frames):
|
||||
path = DataLoadUtil.get_path(root, seq_idx, idx)
|
||||
for frame_idx in range(num_frames):
|
||||
path = DataLoadUtil.get_path(root, scene_name, frame_idx)
|
||||
point_cloud = DataLoadUtil.get_point_cloud_world_from_path(path)
|
||||
point_cloud_list.append(point_cloud)
|
||||
return point_cloud_list
|
||||
|
17
utils/pts.py
Normal file
17
utils/pts.py
Normal file
@@ -0,0 +1,17 @@
|
||||
import numpy as np
|
||||
import open3d as o3d
|
||||
|
||||
class PtsUtil:
|
||||
|
||||
@staticmethod
|
||||
def voxel_downsample_point_cloud(point_cloud, voxel_size=0.005):
|
||||
o3d_pc = o3d.geometry.PointCloud()
|
||||
o3d_pc.points = o3d.utility.Vector3dVector(point_cloud)
|
||||
downsampled_pc = o3d_pc.voxel_down_sample(voxel_size)
|
||||
return np.asarray(downsampled_pc.points)
|
||||
|
||||
@staticmethod
|
||||
def transform_point_cloud(points, pose_mat):
|
||||
points_h = np.concatenate([points, np.ones((points.shape[0], 1))], axis=1)
|
||||
points_h = np.dot(pose_mat, points_h.T).T
|
||||
return points_h[:, :3]
|
@@ -1,6 +1,6 @@
|
||||
import numpy as np
|
||||
import open3d as o3d
|
||||
from scipy.spatial import cKDTree
|
||||
from utils.pts import PtsUtil
|
||||
|
||||
class ReconstructionUtil:
|
||||
|
||||
@@ -13,18 +13,12 @@ class ReconstructionUtil:
|
||||
return coverage_rate
|
||||
|
||||
@staticmethod
|
||||
def compute_overlap_rate(point_cloud1, point_cloud2, threshold=0.01):
|
||||
kdtree1 = cKDTree(point_cloud1)
|
||||
kdtree2 = cKDTree(point_cloud2)
|
||||
distances1, _ = kdtree2.query(point_cloud1)
|
||||
distances2, _ = kdtree1.query(point_cloud2)
|
||||
overlapping_points1 = np.sum(distances1 < threshold)
|
||||
overlapping_points2 = np.sum(distances2 < threshold)
|
||||
|
||||
overlap_rate1 = overlapping_points1 / point_cloud1.shape[0]
|
||||
overlap_rate2 = overlapping_points2 / point_cloud2.shape[0]
|
||||
|
||||
return (overlap_rate1 + overlap_rate2) / 2
|
||||
def compute_overlap_rate(new_point_cloud, combined_point_cloud, threshold=0.01):
|
||||
kdtree = cKDTree(combined_point_cloud)
|
||||
distances, _ = kdtree.query(new_point_cloud)
|
||||
overlapping_points = np.sum(distances < threshold)
|
||||
overlap_rate = overlapping_points / new_point_cloud.shape[0]
|
||||
return overlap_rate
|
||||
|
||||
@staticmethod
|
||||
def combine_point_with_view_sequence(point_list, view_sequence):
|
||||
@@ -41,46 +35,14 @@ class ReconstructionUtil:
|
||||
|
||||
for view_index, view in enumerate(views):
|
||||
candidate_views = combined_point_cloud + [view]
|
||||
down_sampled_combined_point_cloud = ReconstructionUtil.downsample_point_cloud(candidate_views, threshold)
|
||||
down_sampled_combined_point_cloud = PtsUtil.voxel_downsample_point_cloud(candidate_views, threshold)
|
||||
new_coverage = ReconstructionUtil.compute_coverage_rate(target_point_cloud, down_sampled_combined_point_cloud, threshold)
|
||||
coverage_increase = new_coverage - current_coverage
|
||||
if coverage_increase > best_coverage_increase:
|
||||
best_coverage_increase = coverage_increase
|
||||
best_view = view_index
|
||||
return best_view, best_coverage_increase
|
||||
|
||||
@staticmethod
|
||||
def compute_next_best_view_sequence(target_point_cloud, point_cloud_list, threshold=0.01):
|
||||
selected_views = []
|
||||
current_coverage = 0.0
|
||||
remaining_views = list(range(len(point_cloud_list)))
|
||||
view_sequence = []
|
||||
target_point_cloud = ReconstructionUtil.downsample_point_cloud(target_point_cloud, threshold)
|
||||
while remaining_views:
|
||||
best_view = None
|
||||
best_coverage_increase = -1
|
||||
|
||||
for view_index in remaining_views:
|
||||
candidate_views = selected_views + [point_cloud_list[view_index]]
|
||||
combined_point_cloud = np.vstack(candidate_views)
|
||||
|
||||
down_sampled_combined_point_cloud = ReconstructionUtil.downsample_point_cloud(combined_point_cloud,threshold)
|
||||
new_coverage = ReconstructionUtil.compute_coverage_rate(target_point_cloud, down_sampled_combined_point_cloud, threshold)
|
||||
coverage_increase = new_coverage - current_coverage
|
||||
|
||||
if coverage_increase > best_coverage_increase:
|
||||
best_coverage_increase = coverage_increase
|
||||
best_view = view_index
|
||||
|
||||
if best_view is not None:
|
||||
if best_coverage_increase <=1e-3:
|
||||
break
|
||||
selected_views.append(point_cloud_list[best_view])
|
||||
current_coverage += best_coverage_increase
|
||||
view_sequence.append((best_view, current_coverage))
|
||||
remaining_views.remove(best_view)
|
||||
return view_sequence, remaining_views
|
||||
|
||||
|
||||
|
||||
@staticmethod
|
||||
def compute_next_best_view_sequence_with_overlap(target_point_cloud, point_cloud_list, threshold=0.01, overlap_threshold=0.3):
|
||||
@@ -88,7 +50,6 @@ class ReconstructionUtil:
|
||||
current_coverage = 0.0
|
||||
remaining_views = list(range(len(point_cloud_list)))
|
||||
view_sequence = []
|
||||
target_point_cloud = ReconstructionUtil.downsample_point_cloud(target_point_cloud, threshold)
|
||||
|
||||
while remaining_views:
|
||||
best_view = None
|
||||
@@ -98,15 +59,15 @@ class ReconstructionUtil:
|
||||
|
||||
if selected_views:
|
||||
combined_old_point_cloud = np.vstack(selected_views)
|
||||
down_sampled_old_point_cloud = ReconstructionUtil.downsample_point_cloud(combined_old_point_cloud,threshold)
|
||||
down_sampled_new_view_point_cloud = ReconstructionUtil.downsample_point_cloud(point_cloud_list[view_index],threshold)
|
||||
overlap_rate = ReconstructionUtil.compute_overlap_rate(down_sampled_old_point_cloud,down_sampled_new_view_point_cloud , threshold)
|
||||
down_sampled_old_point_cloud = PtsUtil.voxel_downsample_point_cloud(combined_old_point_cloud,threshold)
|
||||
down_sampled_new_view_point_cloud = PtsUtil.voxel_downsample_point_cloud(point_cloud_list[view_index],threshold)
|
||||
overlap_rate = ReconstructionUtil.compute_overlap_rate(down_sampled_new_view_point_cloud,down_sampled_old_point_cloud, threshold)
|
||||
if overlap_rate < overlap_threshold:
|
||||
continue
|
||||
|
||||
candidate_views = selected_views + [point_cloud_list[view_index]]
|
||||
combined_point_cloud = np.vstack(candidate_views)
|
||||
down_sampled_combined_point_cloud = ReconstructionUtil.downsample_point_cloud(combined_point_cloud,threshold)
|
||||
down_sampled_combined_point_cloud = PtsUtil.voxel_downsample_point_cloud(combined_point_cloud,threshold)
|
||||
new_coverage = ReconstructionUtil.compute_coverage_rate(target_point_cloud, down_sampled_combined_point_cloud, threshold)
|
||||
coverage_increase = new_coverage - current_coverage
|
||||
#print(f"view_index: {view_index}, coverage_increase: {coverage_increase}")
|
||||
@@ -128,12 +89,5 @@ class ReconstructionUtil:
|
||||
break
|
||||
|
||||
return view_sequence, remaining_views
|
||||
|
||||
|
||||
def downsample_point_cloud(point_cloud, voxel_size=0.005):
|
||||
o3d_pc = o3d.geometry.PointCloud()
|
||||
o3d_pc.points = o3d.utility.Vector3dVector(point_cloud)
|
||||
downsampled_pc = o3d_pc.voxel_down_sample(voxel_size)
|
||||
return np.asarray(downsampled_pc.points)
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user