def append(self, x, two_point=False): if isinstance(x, (tuple, list, np.ndarray)): try: x = np.asarray(x) except: raise ValueError("Expected numpy array or list") if x.ndim == 1: x = x[np.newaxis, :] if x.ndim > 1 and x.shape[1] != 4: raise ValueError("Input should have shape Nx4, got {0}".format( x.shape)) # Convert to BBox2D x = BBox2D(x, two_point=two_point) x = x.numpy(two_point=True).reshape(1, 4) elif isinstance(x, BBox2D): # ensure that the input is in 2 point format x = x.numpy(two_point=True).reshape(1, 4) elif isinstance(x, BBox2DList): x = x.numpy(two_point=True) else: raise TypeError( "Expected input of type (list, tuple, np.ndarray, BBox2D)") return BBox2DList(np.append(self.bboxes, x, axis=0), two_point=True)
def insert(self, x, idx, two_point=False): if isinstance(x, (tuple, list, np.ndarray)): try: x = np.asarray(x) except: raise ValueError("Expected numpy array or list") if x.ndim > 1 or x.shape[0] != 4: raise ValueError("Input should have shape Nx4, got {0}".format( x.shape)) # ensure that the input is in 2 point format x = BBox2D(x, two_point=two_point) elif isinstance(x, BBox2D): pass else: raise TypeError( "Expected input of type (list, tuple, np.ndarray, BBox2D)") # ensure that the input is in 2 point format x = x.numpy(two_point=True).reshape(1, 4) return BBox2DList(np.insert(self.bboxes, idx, x, axis=0), two_point=True)
def insert(self, x, idx, mode=XYWH): """ Insert a bounding box at a specific location. Args: x: Bounding box to insert. idx (:py:class:`int`): Position where to insert bounding box. """ if isinstance(x, (tuple, list, np.ndarray)): try: x = np.asarray(x, dtype=float) except (ValueError, ): raise ValueError( "Expected list, tuple, or numpy array of ints/floats") if x.ndim > 1 or x.shape[0] != 4: raise ValueError("Input should have shape Nx4, got {0}".format( x.shape)) # ensure that the input is in 2 point format x = BBox2D(x, mode=mode) elif isinstance(x, BBox2D): # don't need to do anything here pass else: raise TypeError( "Expected input of type (list, tuple, np.ndarray, BBox2D)") # ensure that the input is in 2 point format x = x.numpy(mode=XYXY).reshape(1, 4) return BBox2DList(np.insert(self.bboxes, idx, x, axis=0), mode=XYXY)
def append(self, x, mode=XYWH): if isinstance(x, (tuple, list, np.ndarray)): try: x = np.asarray(x, dtype=np.float) except (ValueError, ): raise ValueError( "Expected list, tuple, or numpy array of ints/floats") if x.ndim == 1: x = x[np.newaxis, :] if x.ndim > 1 and x.shape[1] != 4: raise ValueError("Input should have shape Nx4, got {0}".format( x.shape)) # Convert to BBox2D x = BBox2D(x, mode=mode) x = x.numpy(mode=XYXY).reshape(1, 4) elif isinstance(x, BBox2D): # ensure that the input is in 2 point format x = x.numpy(mode=XYXY).reshape(1, 4) elif isinstance(x, BBox2DList): x = x.numpy(mode=XYXY) else: raise TypeError( "Expected input of type (list, tuple, np.ndarray, BBox2D)") return BBox2DList(np.append(self.bboxes, x, axis=0), mode=XYXY)
def __init__(self, arr, two_point=False): """ Class to reprsent a list of 2D bounding boxes. Expects an iterable of bounding boxes of the form (x, y, w, h) or (x1, y1, x2, y2) if `two_point=True`. Parameters ---------- arr: Sequence of list/tuple/ndarray/BBox2D, each representing a single bounding box. two_point : bool Flag to indicate which format `x` is in (x, y, w, h) or (x1, y1, x2, y2). Attributes ---------- x1 : float Left x coordinate of all boxes y1 : float Top y coordinate of all boxes x2 : float Right x coordinate of all boxes y2 : float Bottom y coordinate of all boxes width : float Width of bounding box of all boxes height : float Height of bounding box of all boxes w : float Syntactic sugar for width h : float Syntactic sugar for height shape : np.ndarray Return the shape of the bounding boxes container in the form (N, 4). Raises ------ ValueError If `x` is not of length 4. TypeError If `x` is not of type {list, tuple, numpy.ndarray, BBox2D} """ # Internally, we record the Bounding Box list as a 2D ndarray in two_point format. # We convert arr to a 2D numpy array when possible # check if input is a list if isinstance(arr, list): # if the list is empty, set the input to be an empty numpy array if len(arr) == 0: self.bboxes = np.empty((0, 4)) # list is not empty, so we continue else: # check if the list elements are either numpy arrays or lists # if yes, then convert to a list of BBox2D objects if all( isinstance(x, np.ndarray) or isinstance(x, list) for x in arr): self.bboxes = np.asarray([ BBox2D(x, two_point=two_point).numpy(two_point=True) for x in arr ]) elif all(isinstance(x, BBox2D) for x in arr): # parse a list of BBox2D objects self.bboxes = np.asarray( [x.numpy(two_point=True) for x in arr]) else: raise TypeError( "Element of input is of invalid type. Elements must be all list, np.ndarray or BBox2D" ) # check if `arr` is a 2D numpy array elif isinstance(arr, np.ndarray): # Check for empty ndarray if arr.ndim == 2 and arr.shape[0] == 0: self.bboxes = np.empty((0, 4)) else: # if input is a 1D vector, we add the second dimension if arr.ndim == 1 and arr.shape[0] == 4: arr = arr[np.newaxis, :] # if the dimensions of the array are incorrect, raise exception. if arr.ndim != 2 or arr.shape[1] != 4: raise ValueError( "Invalid dimensions. Expected 2D array of size Nx4. Extra dimensions should be size 1. Got {0}" .format(arr.shape)) # parse the input self.bboxes = np.asarray([ BBox2D(x, two_point=two_point).numpy(two_point=True) for x in arr ], dtype=np.float64) # if `arr` is a BBox2DList, just make a copy elif isinstance(arr, BBox2DList): self.bboxes = arr.bboxes else: raise TypeError( "Invalid input type. Please use a list or a numpy array.")
def __setitem__(self, key, value): self.bboxes[key] = BBox2D(value).numpy(two_point=True)
def __getitem__(self, key): return BBox2D(self.bboxes[key], two_point=True)
def __init__(self, arr, mode=XYWH): """ Class to reprsent a list of 2D bounding boxes. Expects an iterable of bounding boxes of the form (x, y, w, h) or (x1, y1, x2, y2) if `mode=XYXY`. Args: arr: Sequence of list/tuple/ndarray/BBox2D, each representing a single bounding box. mode (BoxMode): Indicator of box format (x, y, w, h) or (x1, y1, x2, y2). \ The values are 0 for XYWH format and 1 for XYXY format.\ See :py:mod:`~bbox.box_modes`. Raises ValueError: If `x` is not of length 4. TypeError: If `x` is not of type {list, tuple, numpy.ndarray, BBox2D} """ # Internally, we record the Bounding Box list as a 2D ndarray in XYXY format. # We convert arr to a 2D numpy array when possible # check if input is a list if isinstance(arr, list): # if the list is empty, set the input to be an empty numpy array if not arr: self.bboxes = np.empty((0, 4)) # list is not empty, so we continue else: # check if the list elements are either numpy arrays or lists # if yes, then convert to a list of BBox2D objects if all( isinstance(x, np.ndarray) or isinstance(x, list) for x in arr): self.bboxes = np.asarray( [BBox2D(x, mode=mode).numpy(mode=XYXY) for x in arr]) elif all(isinstance(x, BBox2D) for x in arr): # parse a list of BBox2D objects self.bboxes = np.asarray([x.numpy(mode=XYXY) for x in arr]) else: raise TypeError( "Element of input is of invalid type." \ "Elements must be all list, np.ndarray or BBox2D") # check if `arr` is a 2D numpy array elif isinstance(arr, np.ndarray): # Check for empty ndarray if arr.ndim == 2 and arr.shape[0] == 0: self.bboxes = np.empty((0, 4)) else: # if input is a 1D vector, we add the second dimension if arr.ndim == 1 and arr.shape[0] == 4: arr = arr[np.newaxis, :] # if the dimensions of the array are incorrect, raise exception. if arr.ndim != 2 or arr.shape[1] != 4: err_msg = "Invalid dimensions. " \ "Expected 2D array of size Nx4 and extra dimensions should be size 1." \ "Got {0}".format(arr.shape) raise ValueError(err_msg) # parse the input self.bboxes = np.asarray( [BBox2D(x, mode=mode).numpy(mode=XYXY) for x in arr], dtype=np.float64) # if `arr` is a BBox2DList, just make a copy elif isinstance(arr, BBox2DList): self.bboxes = arr.bboxes else: raise TypeError( "Invalid input type. Please use a list or a numpy array.")
def __setitem__(self, key, value): self.bboxes[key] = BBox2D(value).numpy(mode=XYXY)
def __getitem__(self, key): return BBox2D(self.bboxes[key], mode=XYXY)