Example #1
0
        def generate_confmaps(example):
            """Local processing function for dataset mapping."""
            # Pull out first instance as (n_nodes, 2) tensor.
            example["points"] = tf.gather(example["instances"], 0, axis=0)

            # Generate confidence maps.
            example["confidence_maps"] = make_confmaps(example["points"],
                                                       xv=xv,
                                                       yv=yv,
                                                       sigma=self.sigma *
                                                       self.output_stride)

            if self.with_offsets:
                example["offsets"] = mask_offsets(
                    make_offsets(example["points"],
                                 xv,
                                 yv,
                                 stride=self.output_stride),
                    example["confidence_maps"],
                    self.offsets_threshold,
                )
                if self.flatten_offsets:
                    shape = tf.shape(example["offsets"])
                    example["offsets"] = tf.reshape(example["offsets"],
                                                    [shape[0], shape[1], -1])

            return example
Example #2
0
def test_mask_offsets():
    points = np.array([[1.0, 1.0]], "float32")
    xv, yv = sleap.nn.data.confidence_maps.make_grid_vectors(4,
                                                             4,
                                                             output_stride=1)
    off = offset_regression.make_offsets(points, xv, yv, stride=1)
    cm = sleap.nn.data.confidence_maps.make_confmaps(points, xv, yv, sigma=1)
    off_mask = offset_regression.mask_offsets(off, cm, threshold=0.2)

    np.testing.assert_array_equal(off_mask[:3, :3], off[:3, :3])
    np.testing.assert_array_equal(off_mask[3:, :], 0.0)
    np.testing.assert_array_equal(off_mask[:, 3:], 0.0)
Example #3
0
        def generate_confmaps(example):
            """Local processing function for dataset mapping."""
            example["instance_confidence_maps"] = make_confmaps(
                example["center_instance"],
                xv=xv,
                yv=yv,
                sigma=self.sigma * self.output_stride,
            )

            if self.with_offsets:
                example["offsets"] = mask_offsets(
                    make_offsets(example["center_instance"],
                                 xv,
                                 yv,
                                 stride=self.output_stride),
                    example["instance_confidence_maps"],
                    self.offsets_threshold,
                )
                if self.flatten_offsets:
                    shape = tf.shape(example["offsets"])
                    example["offsets"] = tf.reshape(example["offsets"],
                                                    [shape[0], shape[1], -1])

            if self.all_instances:
                if self.with_offsets:
                    cms, offsets = make_multi_confmaps_with_offsets(
                        example["all_instances"],
                        xv,
                        yv,
                        self.output_stride,
                        self.sigma * self.output_stride,
                        offsets_threshold=self.offsets_threshold,
                    )
                    example["all_instance_offsets"] = offsets
                    if self.flatten_offsets:
                        shape = tf.shape(example["all_instance_offsets"])
                        example["all_instance_offsets"] = tf.reshape(
                            example["all_instance_offsets"],
                            [shape[0], shape[1], -1])
                else:
                    cms = make_multi_confmaps(
                        example["all_instances"],
                        xv=xv,
                        yv=yv,
                        sigma=self.sigma * self.output_stride,
                    )
                example["all_instance_confidence_maps"] = cms

            return example
Example #4
0
def test_make_offsets():
    points = np.array([[1.8, 2.3], [0.4, 3.1], [np.nan, np.nan]], "float32")
    xv, yv = sleap.nn.data.confidence_maps.make_grid_vectors(4,
                                                             4,
                                                             output_stride=1)
    off = offset_regression.make_offsets(points, xv, yv, stride=1)

    assert off.shape == (4, 4, 3, 2)

    XX, YY = tf.meshgrid(xv, yv)
    np.testing.assert_allclose(XX + off[..., 0, 0], 1.8, atol=1e-6)
    np.testing.assert_allclose(YY + off[..., 0, 1], 2.3, atol=1e-6)
    np.testing.assert_allclose(XX + off[..., 1, 0], 0.4, atol=1e-6)
    np.testing.assert_allclose(YY + off[..., 1, 1], 3.1, atol=1e-6)
    np.testing.assert_array_equal(off[..., 2, :], 0)
Example #5
0
def make_multi_confmaps_with_offsets(
    instances: tf.Tensor,
    xv: tf.Tensor,
    yv: tf.Tensor,
    stride: int,
    sigma: float,
    offsets_threshold: float,
) -> tf.Tensor:
    """Make confidence maps and offsets for multiple instances through reduction.

    Args:
        instances: A tensor of shape `(n_instances, n_nodes, 2)` and dtype `tf.float32`
            containing instance points where the last axis corresponds to (x, y) pixel
            coordinates on the image. This must be rank-3 even if a single instance is
            present.
        xv: Sampling grid vector for x-coordinates of shape `(grid_width,)` and dtype
            `tf.float32`. This can be generated by
            `sleap.nn.data.utils.make_grid_vectors`.
        yv: Sampling grid vector for y-coordinates of shape `(grid_height,)` and dtype
            `tf.float32`. This can be generated by
            `sleap.nn.data.utils.make_grid_vectors`.
        stride: Scaling factor for offset coordinates. The individual offset vectors
            will be divided by this value. Useful for adjusting for strided sampling
            grids so that the offsets point to the smaller grid coordinates.
        sigma: Standard deviation of the 2D Gaussian distribution sampled to generate
            confidence maps.
        offsets_threshold: Minimum confidence map value below which offsets will be
            replaced with zeros.
        flatten_offsets: If `True`, the last two channels of the offset maps will be
            flattened to produce rank-3 tensors. If `False`, the generated offset maps
            will be rank-4 with shaape `(height, width, n_nodes, 2)`.

    Returns:
        A tuple of `(confmaps, offsets)`.

        `confmaps` are confidence maps as a tensor of shape
        `(grid_height, grid_width, n_nodes)` and dtype `tf.float32`.

        Each channel will contain the elementwise maximum of the confidence maps
        generated from all individual points for the associated node.

        `offsets` are offset maps as a `tf.Tensor` of shape
        `(grid_height, grid_width, n_nodes, 2)` and dtype `tf.float32`. The last axis
        corresponds to the x- and y-offsets at each grid point for each node.

    Notes:
        The confidence maps and offsets are computed individually for each instance
        and immediately max-reduced to avoid maintaining the entire set of all instance
        maps. This enables memory-efficient generation of multi-instance maps for
        examples with large numbers of instances.

    See also: sleap.nn.data.make_grid_vectors, make_confmaps, make_multi_confmaps
    """
    # Initialize output tensors.
    grid_height = tf.shape(yv)[0]
    grid_width = tf.shape(xv)[0]
    n_nodes = tf.shape(instances)[1]
    cms = tf.zeros((grid_height, grid_width, n_nodes), tf.float32)
    offsets = tf.zeros((grid_height, grid_width, n_nodes, 2), tf.float32)

    # Eliminate instances completely outside of image.
    in_img = (instances > 0) & (instances < tf.reshape(
        tf.stack([xv[-1], yv[-1]], axis=0), [1, 1, 2]))
    in_img = tf.reduce_any(tf.reduce_all(in_img, axis=-1), axis=1)
    in_img = tf.ensure_shape(in_img, [None])
    instances = tf.boolean_mask(instances, in_img)

    # Generate and reduce outputs by instance.
    for points in instances:
        cms_instance = make_confmaps(points, xv, yv, sigma=sigma)
        cms = tf.maximum(cms, cms_instance)
        offsets_instance = mask_offsets(
            make_offsets(points, xv, yv, stride=stride),
            cms_instance,
            threshold=offsets_threshold,
        )
        offsets += offsets_instance

    return cms, offsets