コード例 #1
0
def augment(
    coords,
    num_points: int = 1024,
    shuffle: bool = True,
    rotate_scheme: str = rigid.RotateScheme.NONE,
    angle_stddev: Optional[float] = None,
    angle_clip: Optional[float] = None,
    jitter_stddev: float = None,
    jitter_clip: float = None,
    maybe_reflect_x: bool = False,
    uniform_scale_range: Optional[Tuple[float, float]] = None,
    drop_prob_limits: Optional[Tuple[float, float]] = None,
    up_dim: int = 2,
    shuffle_first: bool = False,
):
    coords.shape.assert_has_rank(2)
    assert coords.shape[1] == 3

    if shuffle_first and shuffle:
        coords = tfrng.shuffle(coords)

    if num_points is not None:
        coords = coords[:num_points]

    if not shuffle_first and shuffle:
        coords = tfrng.shuffle(coords)

    if drop_prob_limits is not None:
        lower, upper = drop_prob_limits
        drop_prob = tfrng.uniform((), lower, upper)
        if shuffle:
            size = tf.cast(
                tf.cast(tf.shape(coords)[0], tf.float32) * (1 - drop_prob),
                tf.int64)
            coords = coords[:size]
        else:
            mask = tfrng.uniform((tf.shape(coords)[0], )) > drop_prob
            coords = tf.boolean_mask(coords, mask)

    if up_dim != 2:
        roll = (2 - up_dim) % 3
        coords = tf.roll(coords, roll, axis=-1)
    if jitter_stddev is not None:
        coords = jitter.jitter_positions(coords, jitter_stddev, jitter_clip)
    if angle_stddev is not None:
        coords, _ = rigid.random_rotation(coords,
                                          angle_stddev=angle_stddev,
                                          angle_clip=angle_clip)
    if rotate_scheme is not None:
        coords, _ = rigid.rotate_by_scheme(coords, None, scheme=rotate_scheme)

    if uniform_scale_range is not None:
        coords = rigid.random_scale(coords, uniform_range=uniform_scale_range)

    if maybe_reflect_x:
        prob = tfrng.uniform(()) < 0.5
        coords = tf.cond(prob, lambda: coords, lambda: rigid.reflect(coords))
    assert coords.shape[0] is None
    return coords
コード例 #2
0
def to_bool(maybe: MaybeBool) -> Union[bool, BoolTensor, FloatTensor]:
    if isinstance(maybe, (tf.Tensor, np.ndarray)):
        # dtype = maybe.dtype
        dtype = getattr(maybe, "dtype")
        if dtype.is_bool:
            return maybe
        elif dtype.is_floating:
            return tfrng.uniform(()) < maybe
        else:
            raise ValueError(
                f"maybe must be a bool or float if a tensor, got dtype {maybe.dtype}"
            )
    elif isinstance(maybe, bool):
        return maybe
    else:
        return tfrng.uniform(()) < maybe
コード例 #3
0
ファイル: rigid.py プロジェクト: jackd/pcn
def _maybe_reflect(positions, axis=-1, dim=0, prob=0.5):
    should_reflect = tfrng.uniform(shape=(), dtype=tf.float32) > prob
    return tf.cond(
        should_reflect,
        lambda: tuple(reflect(p, dim=dim, axis=axis) for p in positions),
        lambda: tuple(positions),
    )
コード例 #4
0
ファイル: rigid.py プロジェクト: jackd/pcn
def _rotate(positions, normals=None, angle=None, rotation_dim=2, impl=tf):
    """
    Randomly rotate the point cloud about the z-axis.

    Args:
        positions: (n, 3) float array
        normals (optional): (n, 3) float array
        angle: float scalar. If None, a uniform random angle in [0, 2pi) is
            used.
        rotation_dim: int denoting x (0), y (1), or z (2) axis about which to
            rotate
        impl: tf or np

    Returns:
        rotated (`positions`, `normals`). `normals` will be None if not
        provided. shape and dtype is the same as provided.
    """
    dtype = positions.dtype
    if angle is None:
        angle = tfrng.uniform((), dtype=dtype) * (2 * np.pi)

    if normals is not None:
        assert normals.dtype == dtype
    c = impl.cos(angle)
    s = impl.sin(angle)
    # multiply on right, use non-standard rotation matrix (-s and s swapped)
    rotation_matrix = impl.reshape(
        impl.stack(_pack_rotation_matrix(c, s, rotation_dim=rotation_dim)),
        (3, 3))

    positions = impl.matmul(positions, rotation_matrix)
    if normals is not None:
        normals = impl.matmul(normals, rotation_matrix)
    return positions, normals
コード例 #5
0
def augment(
    time: IntTensor,
    coords: IntTensor,
    polarity: BoolTensor,
    grid_shape: GridShape,
    flip_lr: MaybeBool = False,
    flip_ud: MaybeBool = False,
    flip_time: MaybeBool = False,
    rotate_limits: Optional[Tuple[float, float]] = None,
) -> Tuple[IntTensor, IntTensor, BoolTensor, Optional[BoolTensor]]:
    mask = None
    if all(b is False for b in (flip_lr, flip_ud, flip_time)) and rotate_limits is None:
        return time, coords, polarity, mask
    if flip_lr is not False or flip_ud is not False:
        # autograph complains about lambdas
        def flipx():
            return grid_shape[0] - 1 - x

        def no_flipx():
            return x

        def flipy():
            return grid_shape[1] - 1 - y

        def no_flipy():
            return y

        x, y = tf.unstack(coords, axis=-1)
        x = smart_cond(to_bool(flip_lr), flipx, no_flipx)
        y = smart_cond(to_bool(flip_ud), flipy, no_flipy)
        coords = tf.stack((x, y), axis=-1)

    def flipt():
        return reverse_time(time, coords, polarity)

    def no_flipt():
        return (time, coords, polarity)

    time, coords, polarity = smart_cond(to_bool(flip_time), flipt, no_flipt)

    if rotate_limits is not None:
        min_rot, max_rot = rotate_limits
        radians = tfrng.uniform((), minval=min_rot, maxval=max_rot)
        dtype = coords.dtype
        coords = tf.cast(coords, tf.float32)
        coords = rotate2d(coords, radians, center=tf.cast(grid_shape, tf.float32) / 2)
        coords = tf.cast(tf.round(coords), dtype)
        mask = tf.reduce_all(tf.logical_and(coords >= 0, coords < grid_shape), axis=-1)
        time = tf.boolean_mask(time, mask)
        coords = tf.boolean_mask(coords, mask)
        polarity = tf.boolean_mask(polarity, mask)

    return time, coords, polarity, mask
コード例 #6
0
ファイル: rigid.py プロジェクト: jackd/pcn
def random_scale(positions: tf.Tensor,
                 stddev=None,
                 uniform_range=None) -> tf.Tensor:
    if stddev is not None:
        scale = tfrng.truncated_normal(shape=(), mean=1.0, stddev=stddev)
    elif uniform_range is not None:
        minval, maxval = uniform_range
        scale = tfrng.uniform(shape=(), minval=minval, maxval=maxval)
    else:
        raise NotImplementedError(
            "One of stddev or uniform_range must be defined")
    return positions * scale
コード例 #7
0
ファイル: rigid.py プロジェクト: jackd/pcn
def rotate_by_scheme(positions,
                     normals=None,
                     scheme: str = RotateScheme.RANDOM
                     ) -> Tuple[tf.Tensor, Optional[tf.Tensor]]:
    """scheme should be in ("random", "pca-xy", "none")."""
    RotateScheme.validate(scheme)
    if scheme == RotateScheme.NONE:
        return positions, normals

    if scheme == RotateScheme.PCA_XY:
        angle = get_pca_xy_angle(positions)
    elif scheme == RotateScheme.RANDOM:
        angle = tfrng.uniform(shape=(), dtype=positions.dtype) * (2 * np.pi)
    else:
        raise ValueError('Unrecognized scheme "%s"' % scheme)
    return rotate(positions, normals, angle)
コード例 #8
0
def augment_segmentation(
    coords,
    normals,
    labels,
    num_points=None,
    shuffle=True,
    rotate_scheme="none",
    angle_stddev: Optional[float] = None,
    angle_clip: Optional[float] = None,
    jitter_stddev: float = None,
    jitter_clip: float = None,
    maybe_reflect_x=False,
    uniform_scale_range: Optional[Tuple[float, float]] = None,
    drop_prob_limits: Optional[Tuple[float, float]] = None,
    up_dim: int = 2,
):
    coords.shape.assert_has_rank(2)
    assert coords.shape[1] == 3
    normals.shape.assert_has_rank(2)
    assert normals.shape[1] == 3

    if num_points is not None:
        coords = coords[:num_points]
        normals = normals[:num_points]
        labels = labels[:num_points]

    size = tf.size(labels)
    if shuffle:
        order = tfrng.shuffle(tf.range(size))
        coords, normals, labels = (tf.gather(x, order)
                                   for x in (coords, normals, labels))

    if drop_prob_limits is not None:
        lower, upper = drop_prob_limits
        drop_prob = tfrng.uniform((), lower, upper)
        if shuffle:
            size = tf.cast(
                tf.cast(tf.shape(coords)[0], tf.float32) * (1 - drop_prob),
                tf.int64)

            def f(x):
                return x[:size]

        else:
            mask = tfrng.uniform((tf.shape(coords)[0], )) > drop_prob

            def f(x):
                return tf.boolean_mask(x, mask)

        coords, normals, labels = (f(x) for x in (coords, normals, labels))

    if up_dim != 2:
        roll = (2 - up_dim) % 3
        coords, normals = (tf.roll(x, roll, axis=-1)
                           for x in (coords, normals))
    if jitter_stddev is not None:
        coords = jitter.jitter_positions(coords, jitter_stddev, jitter_clip)
    if angle_stddev is not None:
        coords, normals = rigid.random_rotation(coords,
                                                normals,
                                                angle_stddev=angle_stddev,
                                                angle_clip=angle_clip)
    if rotate_scheme is not None:
        coords, normals = rigid.rotate_by_scheme(coords,
                                                 normals,
                                                 scheme=rotate_scheme)

    if uniform_scale_range is not None:
        coords = rigid.random_scale(coords, uniform_range=uniform_scale_range)

    if maybe_reflect_x:
        prob = tfrng.uniform(()) < 0.5
        coords, normals = tf.cond(
            prob,
            lambda: (coords, normals),
            lambda: (rigid.reflect(coords), rigid.reflect(normals)),
        )

    return coords, normals, labels
コード例 #9
0
def map_func(x):
    return x + tfrng.uniform(())
コード例 #10
0
def tfrng_map_func(x):
    scale = tfrng.normal((), stddev=0.1, mean=1.0)
    shift = tfrng.uniform(())
    return transform(x, scale, shift)