- 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
    8 visualizzazioni (ultimi 30 giorni)
  
       Mostra commenti meno recenti
    
     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 Commenti
Risposte (1)
  Sai Pavan
      
 il 25 Nov 2024
        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 Commenti
Vedere anche
Categorie
				Scopri di più su Point Cloud Processing in Help Center e File Exchange
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!

