Spaces:
Runtime error
Runtime error
File size: 6,268 Bytes
5fd3fc6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | from __future__ import absolute_import, division
import numpy as np
from .operations import bezier_curve
from .operations import bresenham as bresenham_function
def scribbles2mask(scribbles,
output_resolution,
bezier_curve_sampling=False,
nb_points=1000,
bresenham=True,
default_value=-1,
single_object=False):
""" Convert the scribbles data into a mask.
# Arguments
scribbles: Dictionary. Scribbles in the default format.
output_resolution: Tuple. Output resolution (H, W).
bezier_curve_sampling: Boolean. Weather to sample first the returned
scribbles using bezier curve or not.
nb_points: Integer. If `bezier_curve_sampling` is `True` set the number
of points to sample from the bezier curve.
bresenham: Boolean. Whether to compute bresenham algorithm for the
scribbles lines.
default_value: Integer. Default value for the pixels which do not belong
to any scribble.
# Returns
ndarray: Array with the mask of the scribbles with the index of the
object ids. The shape of the returned array is (B x H x W) by
default or (H x W) if `only_annotated_frame==True`.
"""
if len(output_resolution) != 2:
raise ValueError(
'Invalid output resolution: {}'.format(output_resolution))
for r in output_resolution:
if r < 1:
raise ValueError(
'Invalid output resolution: {}'.format(output_resolution))
nb_frames = len(scribbles['scribbles'])
masks = np.full(
(nb_frames,) + output_resolution, default_value, dtype=np.int)
size_array = np.asarray(output_resolution[::-1], dtype=np.float) - 1
for f in range(nb_frames):
sp = scribbles['scribbles'][f]
for p in sp:
path = p['path']
if single_object:
# Simulate having only one object
obj_id = 1
else:
obj_id = p['object_id']
path = np.asarray(path, dtype=np.float)
if bezier_curve_sampling:
path = bezier_curve(path, nb_points=nb_points)
path *= size_array
path = path.astype(np.int)
if bresenham:
path = bresenham_function(path)
m = masks[f]
m[path[:, 1], path[:, 0]] = obj_id
masks[f] = m
return masks
def scribbles2points(scribbles_data, output_resolution=None):
""" Convert the given scribbles into a list of points and object ids.
# Arguments
scribbles_data: Dictionary. Scribbles in the default format
output_resolution: Tuple. Output resolution (H, W) to scale the
points.
If None given, the points will be floats as a fraction of height
and width.
# Returns
(ndarray, ndarray): Returns (X, Y) where X is a list of points from the
scribbles represented in the output_resolution with shape (N x 3)
with N being the total number of points on all the scribbles. The three
coordinates given correspond the the frame number, height and width,
respectively.
Y is the object id for each given point with shape (N,).
"""
scribbles = scribbles_data['scribbles']
paths, object_ids = [], []
for frame, s in enumerate(scribbles):
for l in s:
# p = l['path']
coordinates = [[frame] + point for point in l['path']]
paths += coordinates
object_ids += [l['object_id']] * len(l['path'])
paths = np.asarray(paths, dtype=np.float)
object_ids = np.asarray(object_ids, dtype=np.int)
if output_resolution:
h, w = output_resolution
img_size = np.asarray([1, h - 1, w - 1], dtype=np.float)
paths *= img_size
paths = paths.astype(np.int)
return paths, object_ids
def fuse_scribbles(scribbles_a, scribbles_b):
""" Fuse two scribbles in the default format.
# Arguments
scribbles_a: Dictionary. Default representation of scribbles A.
scribbles_b: Dictionary. Default representation of scribbles B.
# Returns
dict: Returns a dictionary with scribbles A and B fused.
"""
if scribbles_a['sequence'] != scribbles_b['sequence']:
raise ValueError('Scribbles to fuse are not from the same sequence')
if len(scribbles_a['scribbles']) != len(scribbles_b['scribbles']):
raise ValueError('Scribbles does not have the same number of frames')
scribbles = dict(scribbles_a)
nb_frames = len(scribbles['scribbles'])
for i in range(nb_frames):
scribbles['scribbles'][i] += scribbles_b['scribbles'][i]
return scribbles
def is_empty(scribbles_data):
""" Checks whether the given scribble has any non-empty line.
# Arguments
scribbles_data (dict): Scribble in the default format
# Returns
bool: Whether the scribble is empty or not.
"""
scribbles = scribbles_data['scribbles']
has_lines = [len(s) > 0 for s in scribbles]
return not any(has_lines)
def annotated_frames(scribbles_data):
""" Finds which frames have a scribble.
# Arguments
scribbles_data (dict): Scribble in the default format.
# Returns
list: Number of the frames that contain at least one scribble.
"""
scribbles = scribbles_data['scribbles']
frames_list = [i for i, s in enumerate(scribbles) if s]
return frames_list
def annotated_frames_object(scribbles_data, object_id):
""" Computes which frames have a scribble for a certain object.
# Arguments
scribbles_data (dict): Scribble in the default format.
object_id (int): Id of the object of interest.
# Returns
dict: Number of the frames that contain at least one scribble.
"""
frames_list = []
scribbles = scribbles_data['scribbles']
for ii, scribble_frame in enumerate(scribbles):
for scribble in scribble_frame:
if scribble['object_id'] == object_id:
frames_list.append(ii)
break
return frames_list
|