//  [python]
def parse_and_preprocess(self, example_proto):
        """
        Returns:
            crops: a float tensor with shape [num_persons, height, width, 17].
            labels: a float tensor with shape [num_persons, height, width, 17].
        """
        features = {
            'image': tf.FixedLenFeature([], tf.string),
            'num_persons': tf.FixedLenFeature([], tf.int64),
            'boxes': tf.FixedLenSequenceFeature([], tf.float32, allow_missing=True),
            'keypoints': tf.FixedLenSequenceFeature([], tf.int64, allow_missing=True)
        }
        parsed_features = tf.parse_single_example(example_proto, features)

        # get size of the image
        shape = tf.image.extract_jpeg_shape(parsed_features['image'])
        image_height, image_width = shape[0], shape[1]
        scaler = tf.cast(tf.stack(2 * [image_height, image_width]), tf.float32)

        # get number of people on the image
        num_persons = tf.cast(parsed_features['num_persons'], tf.int32)
        # it is assumed that num_persons > 0

        # get groundtruth boxes, they are in absolute coordinates
        boxes = tf.reshape(parsed_features['boxes'], [num_persons, 4])

        # get keypoints, they are in absolute coordinates
        keypoints = tf.cast(parsed_features['keypoints'], tf.int32)
        keypoints = tf.reshape(keypoints, [num_persons, 17, 3])

        if self.max_keypoints is not None:

            # curriculum learning by sorting
            # annotations based on number of keypoints

            is_visible = tf.cast(keypoints[:, :, 2] > 0, tf.int32)  # shape [num_persons, 17]
            is_good = tf.less_equal(tf.reduce_sum(is_visible, axis=1), self.max_keypoints)
            # it has shape [num_persons]

            keypoints = tf.boolean_mask(keypoints, is_good)
            boxes = tf.boolean_mask(boxes, is_good)
            num_persons = tf.shape(boxes)[0]

        heatmaps = tf.py_func(
            lambda k, b, w, h: get_heatmaps(k, b, w, h, DOWNSAMPLE),
            [keypoints, boxes, image_width, image_height],
            tf.float32, stateful=False
        )
        heatmaps.set_shape([None, None, 17])

        box_indices = tf.zeros([num_persons], dtype=tf.int32)
        crops = tf.image.crop_and_resize(
            tf.expand_dims(heatmaps, 0),
            boxes/scaler, box_indices,
            crop_size=CROP_SIZE
        )

        def fn(x):
            """
            Arguments:
                keypoints: a float tensor with shape [17, 3].
                box: a float tensor with shape [4].
            Returns:
                a float tensor with shape [height, width, 17].
            """
            keypoints, box = x

            ymin, xmin, ymax, xmax = tf.unstack(box, axis=0)
            y, x, v = tf.unstack(keypoints, axis=1)
            keypoints = tf.stack([y, x], axis=1)

            part_id = tf.where(v > 0.0)  # shape [num_visible, 1]
            part_id = tf.cast(part_id, tf.int32)
            num_visible = tf.shape(part_id)[0]
            keypoints = tf.gather(keypoints, tf.squeeze(part_id, 1))
            # it has shape [num_visible, 2], they have absolute coordinates

            # transform keypoints coordinates
            # to be relative to the box
            h, w = ymax - ymin, xmax - xmin
            height, width = CROP_SIZE
            translation = tf.stack([ymin, xmin])
            scaler = tf.cast(tf.stack([height/h, width/w], axis=0), tf.float32)

            keypoints -= translation
            keypoints *= scaler
            keypoints = tf.cast(tf.round(keypoints), tf.int32)
            # it has shape [num_visible, 2]

            y, x = tf.unstack(keypoints, axis=1)
            y = tf.clip_by_value(y, 0, height - 1)
            x = tf.clip_by_value(x, 0, width - 1)
            keypoints = tf.stack([y, x], axis=1)

            indices = tf.cast(tf.concat([keypoints, part_id], axis=1), tf.int64)
            values = tf.ones([num_visible], dtype=tf.float32)
            binary_map = tf.sparse.SparseTensor(indices, values, dense_shape=[height, width, 17])
            binary_map = tf.sparse.to_dense(binary_map, default_value=0, validate_indices=False)
            return binary_map

        labels = tf.map_fn(
            fn, (tf.cast(keypoints, tf.float32), boxes),
            dtype=tf.float32, back_prop=False,
        )

        if self.is_training:
            crops, labels = random_flip_left_right(crops, labels)

        return crops, labels