data augment fo point cloud

1 回表示 (過去 30 日間)
Mangesh KAle
Mangesh KAle 2024 年 4 月 24 日
回答済み: Sai Pavan 2024 年 11 月 25 日
I have 5o datasets of meshes and its centerline. I am using pointNET algorithm for classification purpose. I converted all my meshes into pointcloud and I am applying random rotation, random flip, random noise and random crop.I am trying to add data augmentation techniques to my function prepare_dataset but instead of 300 dataset , I am getting around 10000 or more. Can you please help me out with it
def prepare_dataset(obj_files, augmentation=True):
# Target size per dataset (1 original + 4 augmented)
target_size_per_dataset = 5
total_datasets = 0 # Counter for generated datasets
print(f"Length of obj files: {len(obj_files)}") # Print number of object files
point_clouds = []
classifications = []
# Iterate over each object file
for obj_file in obj_files:
try:
# Get point cloud points
point_cloud = get_point_cloud(directory_path + "/" + obj_file)
# Get centerline points
centerline_file = directory_path + "/" + obj_file[:-4] + '_centerline' + '.dat'
centerline_points = np.loadtxt(centerline_file, skiprows=1, usecols=(0, 1, 2))
# Classify points (done only once for original data)
classification = classify_point(point_cloud, centerline_points)
# Include original data
point_clouds.append(point_cloud)
classifications.append(classification)
# Apply data augmentation techniques if specified
if augmentation:
augmented_point_clouds, augmented_centerline_points = [], []
for _ in range(target_size_per_dataset - 1): # Generate 4 augmented datasets
augmented_pc, augmented_cl = random_rotation(point_cloud, centerline_points)
augmented_pc, augmented_cl = random_crop(augmented_pc, augmented_cl)
augmented_pc, augmented_cl = random_scale(augmented_pc, augmented_cl)
augmented_pc, augmented_cl = random_noise(augmented_pc, augmented_cl)
augmented_point_clouds.append(augmented_pc)
augmented_centerline_points.append(augmented_cl)
# Append augmented data
point_clouds.extend(augmented_point_clouds)
classifications.extend(
[classification.copy()] * (target_size_per_dataset - 1)) # Repeat classifications
print(f"Augmented datasets generated for {obj_file}: {len(point_clouds)}")
# Convert to PointCloudDataset
point_clouds = np.concatenate(point_clouds)
classifications = np.concatenate(classifications)
point_clouds = point_clouds.reshape((point_clouds.shape[0], point_clouds.shape[1], 1))
dataset = PointCloudDataset(point_clouds.astype(np.float32), classifications.astype(np.int64))
length_after_augmentation = len(point_clouds)
print(f"Length of dataset after augmentation: {length_after_augmentation}")
return dataset
def random_rotation(pc, cl, max_angle=0.2):
"""
Applies random rotation to the point cloud and centerline points.
Args:
pc: Point cloud (numpy array).
cl: Centerline points (numpy array).
max_angle: Maximum rotation angle in radians (default: 0.2).
Returns:
Rotated point cloud and centerline points.
"""
rotation_angle = np.random.uniform(-max_angle, max_angle)
rotation_matrix = np.array([[np.cos(rotation_angle), -np.sin(rotation_angle), 0],
[np.sin(rotation_angle), np.cos(rotation_angle), 0],
[0, 0, 1]])
rotated_pc = np.dot(pc, rotation_matrix)
rotated_cl = np.dot(cl, rotation_matrix)
return rotated_pc, rotated_cl
def random_crop(pc, cl, crop_ratio=0.8):
"""
Applies random crop to the point cloud and keeps corresponding centerline points.
Args:
pc: Point cloud (numpy array).
cl: Centerline points (numpy array).
crop_ratio: Ratio of points to keep after cropping (default: 0.8).
Returns:
Cropped point cloud and centerline points.
"""
data_min = np.min(pc, axis=0)
data_max = np.max(pc, axis=0)
crop_range = data_max - data_min
crop_size = crop_range * crop_ratio
# Generate random cropping box within bounds
offset = np.random.uniform(0, 1, size=(3,)) * crop_range
crop_min = data_min + offset
crop_max = crop_min + crop_size
# Filter point cloud and centerline points within the crop box
cropped_indices = np.all((pc >= crop_min) & (pc < crop_max), axis=1)
cropped_pc = pc[cropped_indices]
cropped_cl = cl[np.any((cl >= crop_min) & (cl < crop_max), axis=1)]
return cropped_pc, cropped_cl
def random_scale(pc, cl, scale_range=(0.8, 1.2)):
"""
Applies random scale to the point cloud while keeping centroids intact.
Args:
pc: Point cloud (numpy array).
cl: Centerline points (numpy array).
scale_range: Tuple defining minimum and maximum scaling factor (default: (0.8, 1.2)).
Returns:
Scaled point cloud and centerline points.
"""
scale_factor = np.random.uniform(scale_range[0], scale_range[1])
scaled_pc = pc * scale_factor
# Maintain the original centroid of the point cloud
centroid = np.mean(pc, axis=0)
scaled_centroid = centroid * scale_factor
offset = scaled_centroid - centroid
scaled_pc += offset
return scaled_pc, cl
def random_noise(pc, cl, noise_std=0.01):
"""
Adds random noise to the point cloud coordinates.
Args:
pc: Point cloud (numpy array).
cl: Centerline points (numpy array).
noise_std: Standard deviation of the noise (default: 0.01).
Returns:
Point cloud with added noise.
"""
noise = np.random.normal(scale=noise_std, size=pc.shape)
noisy_pc = pc + noise
return noisy_pc, cl

回答 (1 件)

Sai Pavan
Sai Pavan 2024 年 11 月 25 日
Hi Magnesh,
I understand that you are trying to augment the point cloud data with 4 augmentation techniques to further use the dataset for classification purpose.
It looks like you're applying multiple augmentation techniques sequentially, and each technique is being applied separately for each of the 4 augmented datasets. This could lead to an unexpected number of total datasets if not managed correctly.
Please find the changes made to your code, along with the updated code snippet:
  1. Each augmentation technique is applied sequentially within the loop to ensure each augmented dataset undergoes all specified augmentations once per iteration.
  2. Augmented data is appended directly to "point_clouds" and "classifications" within the loop after all augmentations are applied.
  3. Used "classification.copy()" to ensure each augmented dataset has its own classification label.
def prepare_dataset(obj_files, augmentation=True):
# Target size per dataset (1 original + 4 augmented)
target_size_per_dataset = 5
total_datasets = 0 # Counter for generated datasets
print(f"Length of obj files: {len(obj_files)}") # Print number of object files
point_clouds = []
classifications = []
# Iterate over each object file
for obj_file in obj_files:
try:
# Get point cloud points
point_cloud = get_point_cloud(directory_path + "/" + obj_file)
# Get centerline points
centerline_file = directory_path + "/" + obj_file[:-4] + '_centerline' + '.dat'
centerline_points = np.loadtxt(centerline_file, skiprows=1, usecols=(0, 1, 2))
# Classify points (done only once for original data)
classification = classify_point(point_cloud, centerline_points)
# Include original data
point_clouds.append(point_cloud)
classifications.append(classification)
# Apply data augmentation techniques
if augmentation:
for _ in range(target_size_per_dataset - 1): # Generate 4 augmented datasets
augmented_pc, augmented_cl = point_cloud, centerline_points
augmented_pc, augmented_cl = random_rotation(augmented_pc, augmented_cl)
augmented_pc, augmented_cl = random_crop(augmented_pc, augmented_cl)
augmented_pc, augmented_cl = random_scale(augmented_pc, augmented_cl)
augmented_pc, augmented_cl = random_noise(augmented_pc, augmented_cl)
# Append augmented data
point_clouds.append(augmented_pc)
classifications.append(classification.copy())
print(f"Augmented datasets generated for {obj_file}: {len(point_clouds)}")
# Convert to PointCloudDataset
point_clouds = np.concatenate(point_clouds)
classifications = np.concatenate(classifications)
point_clouds = point_clouds.reshape((point_clouds.shape[0], point_clouds.shape[1], 1))
dataset = PointCloudDataset(point_clouds.astype(np.float32), classifications.astype(np.int64))
length_after_augmentation = len(point_clouds)
print(f"Length of dataset after augmentation: {length_after_augmentation}")
return dataset
I hope it helps!

カテゴリ

Help Center および File ExchangePoint Cloud Processing についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by