- Each augmentation technique is applied sequentially within the loop to ensure each augmented dataset undergoes all specified augmentations once per iteration.
- Augmented data is appended directly to "point_clouds" and "classifications" within the loop after all augmentations are applied.
- Used "classification.copy()" to ensure each augmented dataset has its own classification label.
data augment fo point cloud
1 回表示 (過去 30 日間)
古いコメントを表示
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
0 件のコメント
回答 (1 件)
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:
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!
0 件のコメント
参考
カテゴリ
Help Center および File Exchange で Point Cloud Processing についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!