예제 #1
0
def sym_bbox_from_point(point, bbox_size):
    """Given a size and a point, the symmetric bounding box around that point is returned.
    If there is ambiguity due to floats, the result is randomly rounded."""
    bbox_size = cast_numpy(bbox_size)
    point = cast_numpy(point)
    bbox_coords = prob_round(point - bbox_size / 2.)
    bbox = _combine_bbox(bbox_coords, bbox_size)
    return bbox
예제 #2
0
def _combine_bbox(bbox_coords, bbox_size):
    """Combine coordinates and size into a bounding box.

    Parameters:
    bbox_coords : tuple or ndarray
    bbox_size : tuple or ndarray

    Returns
    -------
    bounding box

    """
    bbox_coords = cast_numpy(bbox_coords).astype(int)
    bbox_size = cast_numpy(bbox_size).astype(int)
    bbox = tuple(bbox_coords.tolist() + bbox_size.tolist())
    return bbox
예제 #3
0
def _split_bbox(bbox):
    """Split bbox into coordinates and size

    Parameters
    ----------
    bbox : tuple or ndarray. Given dimension n, first n coordinates are the starting point, the other n the size.

    Returns
    -------
    coordinates and size, both ndarrays.
    """
    bbox = cast_numpy(bbox)

    ndim = int(len(bbox) / 2)
    bbox_coords = bbox[:ndim]
    bbox_size = bbox[ndim:]
    return bbox_coords, bbox_size
예제 #4
0
def sample_from_mask(mask, avoid, num_tries=100):
    """A random index is sampled for a mask in the non-zero values.
    As a first try, num_tries iterations randomly select a point and if found,
    proceeds. This is more efficient than finding all possible non-zero
    values which is O(n x m). If this fails within num_tries iterators, we look
    through all non-positive indices. Otherwise, we look through all
    possible indexes.

    Parameters
    ----------
    mask : str or ndarray
        Path to file containing mask or ndarray.

    Returns
    -------
    An index sampled within the mask.
    """
    if isinstance(mask, basestring):
        mask, _ = read_dcm(mask, window_leveling=False, dtype=int)

    bbox = bounding_box(mask)
    mask = extract_patch(mask, bbox)

    i = 0
    rand_idx = None
    while i < num_tries:
        # We sample up to a part of the edge
        rand_idx = tuple([
            np.random.randint(x, y) for x, y in zip(avoid, mask.shape - avoid)
        ])
        if mask[rand_idx] != 0:
            break
        i += 1
    # If that didn't work, we unfortunately have to do a full search.
    # Here we do not try to avoid the edge.
    if not rand_idx:
        rand_idx = random_mask_idx(mask)

    bbox_coords, _ = _split_bbox(bbox)
    rand_idx = cast_numpy(bbox_coords)
    idx = tuple(rand_idx + bbox_coords)
    return idx
예제 #5
0
def rebuild_bbox(bbox, new_size):
    """Given a bounding box and a requested size return the new bounding box around the center of the old.
    If the coordinate would be non-integer, the value is randomly rounded up or down.

    Parameters
    ----------
    bbox : tuple, list or ndarray
    new_size : tuple or list


    Returns
    -------
    New bounding box.
    """
    new_size = cast_numpy(new_size)

    bbox_coords, bbox_size = _split_bbox(bbox)
    bbox_center = bbox_coords - bbox_size / 2.
    new_bbox_coords = prob_round(bbox_center - new_size / 2.)

    new_bbox = _combine_bbox(new_bbox_coords, new_size)
    return new_bbox