Module brevettiai.data.tf_types
Classes which are serializable to tuples to allow use in tensorflow datasets
Expand source code
"""
Classes which are serializable to tuples to allow use in tensorflow datasets
"""
from dataclasses import dataclass, field
import numpy as np
import tensorflow as tf
@dataclass(frozen=True, order=True)
class TfRange:
"""
An object for slicing tensors
"""
start: int = 0
"Index of start frame"
end: int = 0
"Index of frame after last frame in sequence"
def slice(self, sequence):
if self.end == 0:
return sequence[tf.cast(self.start, tf.int32):]
else:
return sequence[tf.cast(self.start, tf.int32):tf.cast(self.end, tf.int32)]
def slice_padded(self, sequence, constant_value):
start = tf.cast(self.start, tf.int32)
end = tf.cast(self.end, tf.int32)
if end <= 0:
end = tf.shape(sequence)[0] + end
pad_start = -tf.minimum(start, 0)
length = tf.shape(sequence)[0]
pad_end = tf.maximum(end-length, 0)
sequence = tf.pad(sequence, [(pad_start, pad_end)], constant_values=constant_value)
return sequence[start + pad_start: end + pad_start]
@classmethod
def build(cls, x):
return cls(x[0], x[1])
@classmethod
def build_single_frame(cls, frame):
frame = int(frame)
return cls(frame, frame + 1)
def __iter__(self):
yield from (self.start, self.end)
def __str__(self):
return f"SequenceRange{self.start, None if self.end == 0 else self.end}"
@dataclass(frozen=True, order=True)
class BBOX:
"""
An object for slicing images according to bounding boxes
y1: vertical offset
x1: horizontal offset
y2: End vertical offset (included)
x2: End horizontal offset (included)
"""
y1: int = 0
"""vertical offset"""
x1: int = 0
"""horizontal offset"""
y2: int = 0
"""End vertical offset (included)"""
x2: int = 0
"""End horizontal offset (included)"""
def slice(self, image, offset_y=0, offset_x=0, zoom=1):
shy, shx = self.shape
y1 = (self.y1 + offset_y) // zoom
y2 = y1 + shy // zoom
x1 = (self.x1 + offset_x) // zoom
x2 = x1 + shx // zoom
return image[y1:y2, x1:x2]
@property
def shape(self):
"""
Get shape of the bounding box
Returns:
height, width
"""
return self.y2 - self.y1 + 1, self.x2 - self.x1 + 1
@property
def area(self):
"""
Get area of bounding box
Returns:
"""
return tf.reduce_prod(self.shape)
#return np.prod(self.shape)
@classmethod
def build(cls, x):
return cls(x[0], x[1], x[2], x[3])
@classmethod
def from_shape(cls, height, width):
return cls(0, 0, height - 1, width - 1)
def numpy(self):
return np.array(tuple(self))
def scale(self, scale):
"""
Scale bounding box
Args:
scale: scaling factor to multiply the coordinates with
Returns:
"""
return BBOX(int(scale * float(self.y1)), int(scale * float(self.x1)),
int(np.floor(scale * float(self.y2))), int(np.floor(scale * float(self.x2))))
def __iter__(self):
yield from (self.y1, self.x1, self.y2, self.x2)
def __str__(self):
return f"BBOX(y1={int(self.y1)}, x1={int(self.x1)}, y2={int(self.y2)}, x2={int(self.x2)})"
Classes
class BBOX (y1: int = 0, x1: int = 0, y2: int = 0, x2: int = 0)-
An object for slicing images according to bounding boxes
y1: vertical offset x1: horizontal offset y2: End vertical offset (included) x2: End horizontal offset (included)
Expand source code
class BBOX: """ An object for slicing images according to bounding boxes y1: vertical offset x1: horizontal offset y2: End vertical offset (included) x2: End horizontal offset (included) """ y1: int = 0 """vertical offset""" x1: int = 0 """horizontal offset""" y2: int = 0 """End vertical offset (included)""" x2: int = 0 """End horizontal offset (included)""" def slice(self, image, offset_y=0, offset_x=0, zoom=1): shy, shx = self.shape y1 = (self.y1 + offset_y) // zoom y2 = y1 + shy // zoom x1 = (self.x1 + offset_x) // zoom x2 = x1 + shx // zoom return image[y1:y2, x1:x2] @property def shape(self): """ Get shape of the bounding box Returns: height, width """ return self.y2 - self.y1 + 1, self.x2 - self.x1 + 1 @property def area(self): """ Get area of bounding box Returns: """ return tf.reduce_prod(self.shape) #return np.prod(self.shape) @classmethod def build(cls, x): return cls(x[0], x[1], x[2], x[3]) @classmethod def from_shape(cls, height, width): return cls(0, 0, height - 1, width - 1) def numpy(self): return np.array(tuple(self)) def scale(self, scale): """ Scale bounding box Args: scale: scaling factor to multiply the coordinates with Returns: """ return BBOX(int(scale * float(self.y1)), int(scale * float(self.x1)), int(np.floor(scale * float(self.y2))), int(np.floor(scale * float(self.x2)))) def __iter__(self): yield from (self.y1, self.x1, self.y2, self.x2) def __str__(self): return f"BBOX(y1={int(self.y1)}, x1={int(self.x1)}, y2={int(self.y2)}, x2={int(self.x2)})"Class variables
var x1 : int-
horizontal offset
var x2 : int-
End horizontal offset (included)
var y1 : int-
vertical offset
var y2 : int-
End vertical offset (included)
Static methods
def build(x)-
Expand source code
@classmethod def build(cls, x): return cls(x[0], x[1], x[2], x[3]) def from_shape(height, width)-
Expand source code
@classmethod def from_shape(cls, height, width): return cls(0, 0, height - 1, width - 1)
Instance variables
var area-
Get area of bounding box
Returns:
Expand source code
@property def area(self): """ Get area of bounding box Returns: """ return tf.reduce_prod(self.shape) var shape-
Get shape of the bounding box
Returns
height, width
Expand source code
@property def shape(self): """ Get shape of the bounding box Returns: height, width """ return self.y2 - self.y1 + 1, self.x2 - self.x1 + 1
Methods
def numpy(self)-
Expand source code
def numpy(self): return np.array(tuple(self)) def scale(self, scale)-
Scale bounding box
Args
scale- scaling factor to multiply the coordinates with
Returns:
Expand source code
def scale(self, scale): """ Scale bounding box Args: scale: scaling factor to multiply the coordinates with Returns: """ return BBOX(int(scale * float(self.y1)), int(scale * float(self.x1)), int(np.floor(scale * float(self.y2))), int(np.floor(scale * float(self.x2)))) def slice(self, image, offset_y=0, offset_x=0, zoom=1)-
Expand source code
def slice(self, image, offset_y=0, offset_x=0, zoom=1): shy, shx = self.shape y1 = (self.y1 + offset_y) // zoom y2 = y1 + shy // zoom x1 = (self.x1 + offset_x) // zoom x2 = x1 + shx // zoom return image[y1:y2, x1:x2]
class TfRange (start: int = 0, end: int = 0)-
An object for slicing tensors
Expand source code
class TfRange: """ An object for slicing tensors """ start: int = 0 "Index of start frame" end: int = 0 "Index of frame after last frame in sequence" def slice(self, sequence): if self.end == 0: return sequence[tf.cast(self.start, tf.int32):] else: return sequence[tf.cast(self.start, tf.int32):tf.cast(self.end, tf.int32)] def slice_padded(self, sequence, constant_value): start = tf.cast(self.start, tf.int32) end = tf.cast(self.end, tf.int32) if end <= 0: end = tf.shape(sequence)[0] + end pad_start = -tf.minimum(start, 0) length = tf.shape(sequence)[0] pad_end = tf.maximum(end-length, 0) sequence = tf.pad(sequence, [(pad_start, pad_end)], constant_values=constant_value) return sequence[start + pad_start: end + pad_start] @classmethod def build(cls, x): return cls(x[0], x[1]) @classmethod def build_single_frame(cls, frame): frame = int(frame) return cls(frame, frame + 1) def __iter__(self): yield from (self.start, self.end) def __str__(self): return f"SequenceRange{self.start, None if self.end == 0 else self.end}"Class variables
var end : int-
Index of frame after last frame in sequence
var start : int-
Index of start frame
Static methods
def build(x)-
Expand source code
@classmethod def build(cls, x): return cls(x[0], x[1]) def build_single_frame(frame)-
Expand source code
@classmethod def build_single_frame(cls, frame): frame = int(frame) return cls(frame, frame + 1)
Methods
def slice(self, sequence)-
Expand source code
def slice(self, sequence): if self.end == 0: return sequence[tf.cast(self.start, tf.int32):] else: return sequence[tf.cast(self.start, tf.int32):tf.cast(self.end, tf.int32)] def slice_padded(self, sequence, constant_value)-
Expand source code
def slice_padded(self, sequence, constant_value): start = tf.cast(self.start, tf.int32) end = tf.cast(self.end, tf.int32) if end <= 0: end = tf.shape(sequence)[0] + end pad_start = -tf.minimum(start, 0) length = tf.shape(sequence)[0] pad_end = tf.maximum(end-length, 0) sequence = tf.pad(sequence, [(pad_start, pad_end)], constant_values=constant_value) return sequence[start + pad_start: end + pad_start]