Converts object detection annotations (ground truth or predictions) to
    stacked format (an `SFrame` where each row is one object instance).

    Parameters
    ----------
    annotations_sarray: SArray
        An `SArray` with unstacked predictions, exactly formatted as the
        annotations column when training an object detector or when making
        predictions.

    Returns
    -------
    annotations_sframe: An `SFrame` with stacked annotations.

    See also
    --------
    unstack_annotations

    Examples
    --------
    Predictions are returned by the object detector in unstacked format:

    >>> predictions = detector.predict(images)

    By converting it to stacked format, it is easier to get an overview of
    object instances:

    >>> turicreate.object_detector.util.stack_annotations(predictions)
    Data:
    +--------+------------+-------+-------+-------+-------+--------+
    | row_id | confidence | label |   x   |   y   | width | height |
    +--------+------------+-------+-------+-------+-------+--------+
    |   0    |    0.98    |  dog  | 123.0 | 128.0 |  80.0 | 182.0  |
    |   0    |    0.67    |  cat  | 150.0 | 183.0 | 129.0 | 101.0  |
    |   1    |    0.8     |  dog  |  50.0 | 432.0 |  65.0 |  98.0  |
    +--------+------------+-------+-------+-------+-------+--------+
    [3 rows x 7 columns]

def stack_annotations(annotations_sarray):
    """
    Converts object detection annotations (ground truth or predictions) to
    stacked format (an `SFrame` where each row is one object instance).

    Parameters
    ----------
    annotations_sarray: SArray
        An `SArray` with unstacked predictions, exactly formatted as the
        annotations column when training an object detector or when making
        predictions.

    Returns
    -------
    annotations_sframe: An `SFrame` with stacked annotations.

    See also
    --------
    unstack_annotations

    Examples
    --------
    Predictions are returned by the object detector in unstacked format:

    >>> predictions = detector.predict(images)

    By converting it to stacked format, it is easier to get an overview of
    object instances:

    >>> turicreate.object_detector.util.stack_annotations(predictions)
    Data:
    +--------+------------+-------+-------+-------+-------+--------+
    | row_id | confidence | label |   x   |   y   | width | height |
    +--------+------------+-------+-------+-------+-------+--------+
    |   0    |    0.98    |  dog  | 123.0 | 128.0 |  80.0 | 182.0  |
    |   0    |    0.67    |  cat  | 150.0 | 183.0 | 129.0 | 101.0  |
    |   1    |    0.8     |  dog  |  50.0 | 432.0 |  65.0 |  98.0  |
    +--------+------------+-------+-------+-------+-------+--------+
    [3 rows x 7 columns]
    """
    _raise_error_if_not_sarray(annotations_sarray, variable_name='annotations_sarray')
    sf = _tc.SFrame({'annotations': annotations_sarray}).add_row_number('row_id')
    sf = sf.stack('annotations', new_column_name='annotations', drop_na=True)
    if len(sf) == 0:
        cols = ['row_id', 'confidence', 'label', 'height', 'width', 'x', 'y']
        return _tc.SFrame({k: [] for k in cols})
    sf = sf.unpack('annotations', column_name_prefix='')
    sf = sf.unpack('coordinates', column_name_prefix='')
    del sf['type']
    return sf