diff --git a/bindings/python/powerboxes/__init__.py b/bindings/python/powerboxes/__init__.py index 3b6f155..35d34b1 100644 --- a/bindings/python/powerboxes/__init__.py +++ b/bindings/python/powerboxes/__init__.py @@ -3,26 +3,25 @@ import numpy as np import numpy.typing as npt -from ._boxes import ( - _dtype_to_func_box_areas, - _dtype_to_func_box_convert, - _dtype_to_func_remove_small_boxes, -) -from ._diou import _dtype_to_func_diou_distance -from ._giou import ( - _dtype_to_func_giou_distance, - _dtype_to_func_parallel_giou_distance, -) -from ._iou import ( - _dtype_to_func_iou_distance, - _dtype_to_func_parallel_iou_distance, -) -from ._nms import _dtype_to_func_nms, _dtype_to_func_rtree_nms -from ._powerboxes import masks_to_boxes as _masks_to_boxes -from ._powerboxes import rotated_giou_distance as _rotated_giou_distance -from ._powerboxes import rotated_iou_distance as _rotated_iou_distance -from ._powerboxes import rotated_tiou_distance as _rotated_tiou_distance -from ._tiou import _dtype_to_func_tiou_distance +from ._boxes import _dtype_to_func_box_areas +# _dtype_to_func_box_convert, +# _dtype_to_func_remove_small_boxes, +# ) +# from ._diou import _dtype_to_func_diou_distance +# from ._giou import ( +# _dtype_to_func_giou_distance, +# _dtype_to_func_parallel_giou_distance, +# ) +# from ._iou import ( +# _dtype_to_func_iou_distance, +# _dtype_to_func_parallel_iou_distance, +# ) +# from ._nms import _dtype_to_func_nms, _dtype_to_func_rtree_nms +# from ._powerboxes import masks_to_boxes as _masks_to_boxes +# from ._powerboxes import rotated_giou_distance as _rotated_giou_distance +# from ._powerboxes import rotated_iou_distance as _rotated_iou_distance +# from ._powerboxes import rotated_tiou_distance as _rotated_tiou_distance +# from ._tiou import _dtype_to_func_tiou_distance _BOXES_NOT_SAME_TYPE = "boxes1 and boxes2 must have the same dtype" _BOXES_NOT_NP_ARRAY = "boxes must be numpy array" @@ -55,309 +54,309 @@ ) -def diou_distance( - boxes1: npt.NDArray[Union[np.float32, np.float64]], - boxes2: npt.NDArray[Union[np.float32, np.float64]], -) -> npt.NDArray[np.float64]: - """Compute pairwise box diou distances. - - DIoU distance is defined in https://arxiv.org/pdf/1911.08287.pdf - - Args: - boxes1: 2d array of boxes in xyxy format - boxes2: 2d array of boxes in xyxy format - - Raises: - TypeError: if boxes1 or boxes2 are not numpy arrays - ValueError: if boxes1 and boxes2 have different dtypes - - Returns: - np.ndarray: 2d matrix of pairwise distances - """ - if not isinstance(boxes1, np.ndarray) or not isinstance(boxes2, np.ndarray): - raise TypeError(_BOXES_NOT_NP_ARRAY) - if boxes1.dtype == boxes2.dtype: - try: - return _dtype_to_func_diou_distance[boxes1.dtype](boxes1, boxes2) - except KeyError: - raise TypeError( - f"Box dtype: {boxes1.dtype} not in supported dtypes np.float32, np.float64" - ) - else: - raise ValueError(_BOXES_NOT_SAME_TYPE) - - -def iou_distance( - boxes1: npt.NDArray[T], boxes2: npt.NDArray[T] -) -> npt.NDArray[np.float64]: - """Compute pairwise box iou distances. - - Args: - boxes1: 2d array of boxes in xyxy format - boxes2: 2d array of boxes in xyxy format - - Raises: - TypeError: if boxes1 or boxes2 are not numpy arrays - ValueError: if boxes1 and boxes2 have different dtypes - - Returns: - np.ndarray: 2d matrix of pairwise distances - """ - if not isinstance(boxes1, np.ndarray) or not isinstance(boxes2, np.ndarray): - raise TypeError(_BOXES_NOT_NP_ARRAY) - if boxes1.dtype == boxes2.dtype: - try: - return _dtype_to_func_iou_distance[boxes1.dtype](boxes1, boxes2) - except KeyError: - raise TypeError( - f"Box dtype: {boxes1.dtype} not in supported dtypes {supported_dtypes}" - ) - else: - raise ValueError(_BOXES_NOT_SAME_TYPE) - - -def parallel_iou_distance( - boxes1: npt.NDArray[T], boxes2: npt.NDArray[T] -) -> npt.NDArray[np.float64]: - """Compute pairwise box iou distances, in parallel. - - Args: - boxes1: 2d array of boxes in xyxy format - boxes2: 2d array of boxes in xyxy format - - Raises: - TypeError: if boxes1 or boxes2 are not numpy arrays - ValueError: if boxes1 and boxes2 have different dtypes - - Returns: - np.ndarray: 2d matrix of pairwise distances - """ - if not isinstance(boxes1, np.ndarray) or not isinstance(boxes2, np.ndarray): - raise TypeError(_BOXES_NOT_NP_ARRAY) - if boxes1.dtype == boxes2.dtype: - try: - return _dtype_to_func_parallel_iou_distance[boxes1.dtype](boxes1, boxes2) # type: ignore - except KeyError: - raise TypeError( - f"Box dtype: {boxes1.dtype} not in supported dtypes {supported_dtypes}" - ) - else: - raise ValueError(_BOXES_NOT_SAME_TYPE) - - -def parallel_giou_distance( - boxes1: npt.NDArray[T], boxes2: npt.NDArray[T] -) -> npt.NDArray[np.float64]: - """Compute pairwise box giou distances, in parallel. - - see [here](https://giou.stanford.edu/) for giou distance definition - - Args: - boxes1: 2d array of boxes in xyxy format - boxes2: 2d array of boxes in xyxy format - - Raises: - TypeError: if boxes1 or boxes2 are not numpy arrays - ValueError: if boxes1 and boxes2 have different dtypes - - Returns: - np.ndarray: 2d matrix of pairwise distances - """ - if not isinstance(boxes1, np.ndarray) or not isinstance(boxes2, np.ndarray): - raise TypeError(_BOXES_NOT_NP_ARRAY) - if boxes1.dtype == boxes2.dtype: - try: - return _dtype_to_func_parallel_giou_distance[boxes1.dtype](boxes1, boxes2) # type: ignore - except KeyError: - raise TypeError( - f"Box dtype: {boxes1.dtype} not in supported dtypes {supported_dtypes}" - ) - else: - raise ValueError(_BOXES_NOT_SAME_TYPE) - - -def giou_distance( - boxes1: npt.NDArray[T], boxes2: npt.NDArray[T] -) -> npt.NDArray[np.float64]: - """Compute pairwise box giou distances. - - see [here](https://giou.stanford.edu/) for giou distance definition - - Args: - boxes1: 2d array of boxes in xyxy format - boxes2: 2d array of boxes in xyxy format - - Raises: - TypeError: if boxes1 or boxes2 are not numpy arrays - ValueError: if boxes1 and boxes2 have different dtypes - - Returns: - np.ndarray: 2d matrix of pairwise distances - """ - if not isinstance(boxes1, np.ndarray) or not isinstance(boxes2, np.ndarray): - raise TypeError(_BOXES_NOT_NP_ARRAY) - if boxes1.dtype == boxes2.dtype: - try: - return _dtype_to_func_giou_distance[boxes1.dtype](boxes1, boxes2) # type: ignore - except KeyError: - raise TypeError( - f"Box dtype: {boxes1.dtype} not in supported dtypes {supported_dtypes}" - ) - else: - raise ValueError(_BOXES_NOT_SAME_TYPE) - - -def tiou_distance( - boxes1: npt.NDArray[T], boxes2: npt.NDArray[T] -) -> npt.NDArray[np.float64]: - """Compute pairwise box tiou (tracking iou) distances. - - see [here](https://arxiv.org/pdf/2310.05171.pdf) for tiou definition - - Args: - boxes1: 2d array of boxes in xyxy format - boxes2: 2d array of boxes in xyxy format - - Raises: - TypeError: if boxes1 or boxes2 are not numpy arrays - ValueError: if boxes1 and boxes2 have different dtypes - - Returns: - np.ndarray: 2d matrix of pairwise distances - """ - if not isinstance(boxes1, np.ndarray) or not isinstance(boxes2, np.ndarray): - raise TypeError(_BOXES_NOT_NP_ARRAY) - if boxes1.dtype == boxes2.dtype: - try: - return _dtype_to_func_tiou_distance[boxes1.dtype](boxes1, boxes2) # type: ignore - except KeyError: - raise TypeError( - f"Box dtype: {boxes1.dtype} not in supported dtypes {supported_dtypes}" - ) - else: - raise ValueError(_BOXES_NOT_SAME_TYPE) - - -def rotated_iou_distance( - boxes1: npt.NDArray[np.float64], boxes2: npt.NDArray[np.float64] -) -> npt.NDArray[np.float64]: - """Compute the pairwise iou distance between rotated boxes - - Boxes should be in (cx, cy, w, h, a) format - where cx and cy are center coordinates, w and h - width and height and a, the angle in degrees - - Args: - boxes1: 2d array of boxes in cxywha format - boxes2: 2d array of boxes in cxywha format - - Raises: - TypeError: if boxes1 or boxes2 are not numpy arrays - ValueError: if boxes1 and boxes2 have different dtypes - - Returns: - np.ndarray: 2d matrix of pairwise distances - """ - if not isinstance(boxes1, np.ndarray) or not isinstance(boxes2, np.ndarray): - raise TypeError(_BOXES_NOT_NP_ARRAY) - if boxes1.dtype == boxes2.dtype == np.dtype("float64"): - return _rotated_iou_distance(boxes1, boxes2) - else: - raise TypeError( - f"Boxes dtype: {boxes1.dtype}, {boxes2.dtype} not in float64 dtype" - ) - - -def rotated_giou_distance( - boxes1: npt.NDArray[np.float64], boxes2: npt.NDArray[np.float64] -) -> npt.NDArray[np.float64]: - """Compute the pairwise giou distance between rotated boxes - - Boxes should be in (cx, cy, w, h, a) format - where cx and cy are center coordinates, w and h - width and height and a, the angle in degrees - - Args: - boxes1: 2d array of boxes in cxywha format - boxes2: 2d array of boxes in cxywha format - - Raises: - TypeError: if boxes1 or boxes2 are not numpy arrays - ValueError: if boxes1 and boxes2 have different dtypes - - Returns: - np.ndarray: 2d matrix of pairwise distances - """ - if not isinstance(boxes1, np.ndarray) or not isinstance(boxes2, np.ndarray): - raise TypeError(_BOXES_NOT_NP_ARRAY) - if boxes1.dtype == boxes2.dtype == np.dtype("float64"): - return _rotated_giou_distance(boxes1, boxes2) - else: - raise TypeError( - f"Boxes dtype: {boxes1.dtype}, {boxes2.dtype} not in float64 dtype" - ) - - -def rotated_tiou_distance( - boxes1: npt.NDArray[np.float64], boxes2: npt.NDArray[np.float64] -) -> npt.NDArray[np.float64]: - """Compute pairwise box tiou (tracking iou) distances. - - see [here](https://arxiv.org/pdf/2310.05171.pdf) for tiou definition - - Boxes should be in (cx, cy, w, h, a) format - where cx and cy are center coordinates, w and h - width and height and a, the angle in degrees - - Args: - boxes1: 2d array of boxes in cxywha format - boxes2: 2d array of boxes in cxywha format - - Raises: - TypeError: if boxes1 or boxes2 are not numpy arrays - ValueError: if boxes1 and boxes2 have different dtypes - - Returns: - np.ndarray: 2d matrix of pairwise distances - """ - if not isinstance(boxes1, np.ndarray) or not isinstance(boxes2, np.ndarray): - raise TypeError(_BOXES_NOT_NP_ARRAY) - if boxes1.dtype == boxes2.dtype == np.dtype("float64"): - return _rotated_tiou_distance(boxes1, boxes2) - else: - raise TypeError( - f"Boxes dtype: {boxes1.dtype}, {boxes2.dtype} not in float64 dtype" - ) - - -def remove_small_boxes(boxes: npt.NDArray[T], min_size: float) -> npt.NDArray[T]: - """Remove boxes with area less than min_area. - - Args: - boxes: 2d array of boxes in xyxy format - min_size: minimum area of boxes to keep - - Raises: - TypeError: if boxes is not numpy array - - Returns: - np.ndarray: 2d array of boxes in xyxy format - """ - if not isinstance(boxes, np.ndarray): - raise TypeError(_BOXES_NOT_NP_ARRAY) - try: - return _dtype_to_func_remove_small_boxes[boxes.dtype](boxes, min_size) # type: ignore - except KeyError: - raise TypeError( - f"Box dtype: {boxes.dtype} not in supported dtypes {supported_dtypes}" - ) +# def diou_distance( +# boxes1: npt.NDArray[Union[np.float32, np.float64]], +# boxes2: npt.NDArray[Union[np.float32, np.float64]], +# ) -> npt.NDArray[np.float64]: +# """Compute pairwise box diou distances. + +# DIoU distance is defined in https://arxiv.org/pdf/1911.08287.pdf + +# Args: +# boxes1: 2d array of boxes in xyxy format +# boxes2: 2d array of boxes in xyxy format + +# Raises: +# TypeError: if boxes1 or boxes2 are not numpy arrays +# ValueError: if boxes1 and boxes2 have different dtypes + +# Returns: +# np.ndarray: 2d matrix of pairwise distances +# """ +# if not isinstance(boxes1, np.ndarray) or not isinstance(boxes2, np.ndarray): +# raise TypeError(_BOXES_NOT_NP_ARRAY) +# if boxes1.dtype == boxes2.dtype: +# try: +# return _dtype_to_func_diou_distance[boxes1.dtype](boxes1, boxes2) +# except KeyError: +# raise TypeError( +# f"Box dtype: {boxes1.dtype} not in supported dtypes np.float32, np.float64" +# ) +# else: +# raise ValueError(_BOXES_NOT_SAME_TYPE) + + +# def iou_distance( +# boxes1: npt.NDArray[T], boxes2: npt.NDArray[T] +# ) -> npt.NDArray[np.float64]: +# """Compute pairwise box iou distances. + +# Args: +# boxes1: 2d array of boxes in xyxy format +# boxes2: 2d array of boxes in xyxy format + +# Raises: +# TypeError: if boxes1 or boxes2 are not numpy arrays +# ValueError: if boxes1 and boxes2 have different dtypes + +# Returns: +# np.ndarray: 2d matrix of pairwise distances +# """ +# if not isinstance(boxes1, np.ndarray) or not isinstance(boxes2, np.ndarray): +# raise TypeError(_BOXES_NOT_NP_ARRAY) +# if boxes1.dtype == boxes2.dtype: +# try: +# return _dtype_to_func_iou_distance[boxes1.dtype](boxes1, boxes2) +# except KeyError: +# raise TypeError( +# f"Box dtype: {boxes1.dtype} not in supported dtypes {supported_dtypes}" +# ) +# else: +# raise ValueError(_BOXES_NOT_SAME_TYPE) + + +# def parallel_iou_distance( +# boxes1: npt.NDArray[T], boxes2: npt.NDArray[T] +# ) -> npt.NDArray[np.float64]: +# """Compute pairwise box iou distances, in parallel. + +# Args: +# boxes1: 2d array of boxes in xyxy format +# boxes2: 2d array of boxes in xyxy format + +# Raises: +# TypeError: if boxes1 or boxes2 are not numpy arrays +# ValueError: if boxes1 and boxes2 have different dtypes + +# Returns: +# np.ndarray: 2d matrix of pairwise distances +# """ +# if not isinstance(boxes1, np.ndarray) or not isinstance(boxes2, np.ndarray): +# raise TypeError(_BOXES_NOT_NP_ARRAY) +# if boxes1.dtype == boxes2.dtype: +# try: +# return _dtype_to_func_parallel_iou_distance[boxes1.dtype](boxes1, boxes2) # type: ignore +# except KeyError: +# raise TypeError( +# f"Box dtype: {boxes1.dtype} not in supported dtypes {supported_dtypes}" +# ) +# else: +# raise ValueError(_BOXES_NOT_SAME_TYPE) + + +# def parallel_giou_distance( +# boxes1: npt.NDArray[T], boxes2: npt.NDArray[T] +# ) -> npt.NDArray[np.float64]: +# """Compute pairwise box giou distances, in parallel. + +# see [here](https://giou.stanford.edu/) for giou distance definition + +# Args: +# boxes1: 2d array of boxes in xyxy format +# boxes2: 2d array of boxes in xyxy format + +# Raises: +# TypeError: if boxes1 or boxes2 are not numpy arrays +# ValueError: if boxes1 and boxes2 have different dtypes + +# Returns: +# np.ndarray: 2d matrix of pairwise distances +# """ +# if not isinstance(boxes1, np.ndarray) or not isinstance(boxes2, np.ndarray): +# raise TypeError(_BOXES_NOT_NP_ARRAY) +# if boxes1.dtype == boxes2.dtype: +# try: +# return _dtype_to_func_parallel_giou_distance[boxes1.dtype](boxes1, boxes2) # type: ignore +# except KeyError: +# raise TypeError( +# f"Box dtype: {boxes1.dtype} not in supported dtypes {supported_dtypes}" +# ) +# else: +# raise ValueError(_BOXES_NOT_SAME_TYPE) + + +# def giou_distance( +# boxes1: npt.NDArray[T], boxes2: npt.NDArray[T] +# ) -> npt.NDArray[np.float64]: +# """Compute pairwise box giou distances. + +# see [here](https://giou.stanford.edu/) for giou distance definition + +# Args: +# boxes1: 2d array of boxes in xyxy format +# boxes2: 2d array of boxes in xyxy format + +# Raises: +# TypeError: if boxes1 or boxes2 are not numpy arrays +# ValueError: if boxes1 and boxes2 have different dtypes + +# Returns: +# np.ndarray: 2d matrix of pairwise distances +# """ +# if not isinstance(boxes1, np.ndarray) or not isinstance(boxes2, np.ndarray): +# raise TypeError(_BOXES_NOT_NP_ARRAY) +# if boxes1.dtype == boxes2.dtype: +# try: +# return _dtype_to_func_giou_distance[boxes1.dtype](boxes1, boxes2) # type: ignore +# except KeyError: +# raise TypeError( +# f"Box dtype: {boxes1.dtype} not in supported dtypes {supported_dtypes}" +# ) +# else: +# raise ValueError(_BOXES_NOT_SAME_TYPE) + + +# def tiou_distance( +# boxes1: npt.NDArray[T], boxes2: npt.NDArray[T] +# ) -> npt.NDArray[np.float64]: +# """Compute pairwise box tiou (tracking iou) distances. + +# see [here](https://arxiv.org/pdf/2310.05171.pdf) for tiou definition + +# Args: +# boxes1: 2d array of boxes in xyxy format +# boxes2: 2d array of boxes in xyxy format + +# Raises: +# TypeError: if boxes1 or boxes2 are not numpy arrays +# ValueError: if boxes1 and boxes2 have different dtypes + +# Returns: +# np.ndarray: 2d matrix of pairwise distances +# """ +# if not isinstance(boxes1, np.ndarray) or not isinstance(boxes2, np.ndarray): +# raise TypeError(_BOXES_NOT_NP_ARRAY) +# if boxes1.dtype == boxes2.dtype: +# try: +# return _dtype_to_func_tiou_distance[boxes1.dtype](boxes1, boxes2) # type: ignore +# except KeyError: +# raise TypeError( +# f"Box dtype: {boxes1.dtype} not in supported dtypes {supported_dtypes}" +# ) +# else: +# raise ValueError(_BOXES_NOT_SAME_TYPE) + + +# def rotated_iou_distance( +# boxes1: npt.NDArray[np.float64], boxes2: npt.NDArray[np.float64] +# ) -> npt.NDArray[np.float64]: +# """Compute the pairwise iou distance between rotated boxes + +# Boxes should be in (cx, cy, w, h, a) format +# where cx and cy are center coordinates, w and h +# width and height and a, the angle in degrees + +# Args: +# boxes1: 2d array of boxes in cxywha format +# boxes2: 2d array of boxes in cxywha format + +# Raises: +# TypeError: if boxes1 or boxes2 are not numpy arrays +# ValueError: if boxes1 and boxes2 have different dtypes + +# Returns: +# np.ndarray: 2d matrix of pairwise distances +# """ +# if not isinstance(boxes1, np.ndarray) or not isinstance(boxes2, np.ndarray): +# raise TypeError(_BOXES_NOT_NP_ARRAY) +# if boxes1.dtype == boxes2.dtype == np.dtype("float64"): +# return _rotated_iou_distance(boxes1, boxes2) +# else: +# raise TypeError( +# f"Boxes dtype: {boxes1.dtype}, {boxes2.dtype} not in float64 dtype" +# ) + + +# def rotated_giou_distance( +# boxes1: npt.NDArray[np.float64], boxes2: npt.NDArray[np.float64] +# ) -> npt.NDArray[np.float64]: +# """Compute the pairwise giou distance between rotated boxes + +# Boxes should be in (cx, cy, w, h, a) format +# where cx and cy are center coordinates, w and h +# width and height and a, the angle in degrees + +# Args: +# boxes1: 2d array of boxes in cxywha format +# boxes2: 2d array of boxes in cxywha format + +# Raises: +# TypeError: if boxes1 or boxes2 are not numpy arrays +# ValueError: if boxes1 and boxes2 have different dtypes + +# Returns: +# np.ndarray: 2d matrix of pairwise distances +# """ +# if not isinstance(boxes1, np.ndarray) or not isinstance(boxes2, np.ndarray): +# raise TypeError(_BOXES_NOT_NP_ARRAY) +# if boxes1.dtype == boxes2.dtype == np.dtype("float64"): +# return _rotated_giou_distance(boxes1, boxes2) +# else: +# raise TypeError( +# f"Boxes dtype: {boxes1.dtype}, {boxes2.dtype} not in float64 dtype" +# ) + + +# def rotated_tiou_distance( +# boxes1: npt.NDArray[np.float64], boxes2: npt.NDArray[np.float64] +# ) -> npt.NDArray[np.float64]: +# """Compute pairwise box tiou (tracking iou) distances. + +# see [here](https://arxiv.org/pdf/2310.05171.pdf) for tiou definition + +# Boxes should be in (cx, cy, w, h, a) format +# where cx and cy are center coordinates, w and h +# width and height and a, the angle in degrees + +# Args: +# boxes1: 2d array of boxes in cxywha format +# boxes2: 2d array of boxes in cxywha format + +# Raises: +# TypeError: if boxes1 or boxes2 are not numpy arrays +# ValueError: if boxes1 and boxes2 have different dtypes + +# Returns: +# np.ndarray: 2d matrix of pairwise distances +# """ +# if not isinstance(boxes1, np.ndarray) or not isinstance(boxes2, np.ndarray): +# raise TypeError(_BOXES_NOT_NP_ARRAY) +# if boxes1.dtype == boxes2.dtype == np.dtype("float64"): +# return _rotated_tiou_distance(boxes1, boxes2) +# else: +# raise TypeError( +# f"Boxes dtype: {boxes1.dtype}, {boxes2.dtype} not in float64 dtype" +# ) + + +# def remove_small_boxes(boxes: npt.NDArray[T], min_size: float) -> npt.NDArray[T]: +# """Remove boxes with area less than min_area. + +# Args: +# boxes: 2d array of boxes in xyxy format +# min_size: minimum area of boxes to keep + +# Raises: +# TypeError: if boxes is not numpy array + +# Returns: +# np.ndarray: 2d array of boxes in xyxy format +# """ +# if not isinstance(boxes, np.ndarray): +# raise TypeError(_BOXES_NOT_NP_ARRAY) +# try: +# return _dtype_to_func_remove_small_boxes[boxes.dtype](boxes, min_size) # type: ignore +# except KeyError: +# raise TypeError( +# f"Box dtype: {boxes.dtype} not in supported dtypes {supported_dtypes}" +# ) def boxes_areas(boxes: npt.NDArray[T]) -> npt.NDArray[np.float64]: """Compute areas of boxes. Args: - boxes: 2d array of boxes in xyxy format + boxes: 2d array of boxes in xyxy format and shape (N,4) Returns: np.ndarray: 1d array of areas @@ -372,114 +371,114 @@ def boxes_areas(boxes: npt.NDArray[T]) -> npt.NDArray[np.float64]: ) -def box_convert(boxes: npt.NDArray[T], in_fmt: str, out_fmt: str) -> npt.NDArray[T]: - """Convert boxes from one format to another. - - Available formats are: - - 'xyxy': (xmin, ymin, xmax, ymax) - - 'xywh': (xmin, ymin, width, height) - - 'cxcywh': (center_x, center_y, width, height) - - Args: - boxes: 2d array of boxes in in_fmt - in_fmt: format of input boxes - out_fmt: format of output boxes - - Returns: - np.ndarray: boxes in out_fmt - """ - if not isinstance(boxes, np.ndarray): - raise TypeError(_BOXES_NOT_NP_ARRAY) - try: - return _dtype_to_func_box_convert[boxes.dtype](boxes, in_fmt, out_fmt) # type: ignore - except KeyError: - raise TypeError( - f"Box dtype: {boxes.dtype} not in supported dtypes {supported_dtypes}" - ) - - -def masks_to_boxes(masks: npt.NDArray[np.bool_]) -> npt.NDArray[np.uint64]: - """Convert masks to boxes in xyxy format. - - Args: - masks: 3d array of masks in (N, H, W) format - - Raises: - TypeError: if masks is not numpy array - - Returns: - npt.NDArray[np.uint64]: 2d array of boxes in xyxy format - """ - if not isinstance(masks, np.ndarray): - raise TypeError(_BOXES_NOT_NP_ARRAY) - return _masks_to_boxes(masks) - - -def nms( - boxes: npt.NDArray[T], - scores: npt.NDArray[np.float64], - iou_threshold: float, - score_threshold: float, -) -> npt.NDArray[np.uint64]: - """Apply non-maximum suppression to boxes. - - Args: - boxes: 2d array of boxes in xyxy format - scores: 1d array of scores - iou_threshold: threshold for iou - score_threshold: threshold for scores - - Raises: - TypeError: if boxes or scores are not numpy arrays - - Returns: - npt.NDArray[np.uint64]: 1d array of indices to keep - """ - if not isinstance(boxes, np.ndarray) or not isinstance(scores, np.ndarray): - raise TypeError("Boxes and scores must be numpy arrays") - try: - return _dtype_to_func_nms[boxes.dtype]( # type: ignore - boxes, scores, iou_threshold, score_threshold - ) - except KeyError: - raise TypeError( - f"Box dtype: {boxes.dtype} not in supported dtypes {supported_dtypes}" - ) - - -def rtree_nms( - boxes: npt.NDArray[Union[np.float64, np.float32, np.int64, np.int32, np.int16]], - scores: npt.NDArray[np.float64], - iou_threshold: float, - score_threshold: float, -) -> npt.NDArray[np.uint64]: - """Apply non-maximum suppression to boxes. - - Uses an rtree to speed up computation. This is only available for - signed integer dtypes and float32 and float64. - - Args: - boxes: 2d array of boxes in xyxy format - scores: 1d array of scores - iou_threshold: threshold for iou - score_threshold: threshold for scores - - Raises: - TypeError: if boxes or scores are not numpy arrays - - Returns: - npt.NDArray[np.uint64]: 1d array of indices to keep - """ - if not isinstance(boxes, np.ndarray) or not isinstance(scores, np.ndarray): - raise TypeError("Boxes and scores must be numpy arrays") - try: - return _dtype_to_func_rtree_nms[boxes.dtype]( # type: ignore - boxes, scores, iou_threshold, score_threshold - ) - except KeyError: - raise TypeError( - f"Box dtype: {boxes.dtype} not in supported dtypes {supported_dtypes}" - ) +# def box_convert(boxes: npt.NDArray[T], in_fmt: str, out_fmt: str) -> npt.NDArray[T]: +# """Convert boxes from one format to another. + +# Available formats are: +# - 'xyxy': (xmin, ymin, xmax, ymax) +# - 'xywh': (xmin, ymin, width, height) +# - 'cxcywh': (center_x, center_y, width, height) + +# Args: +# boxes: 2d array of boxes in in_fmt +# in_fmt: format of input boxes +# out_fmt: format of output boxes + +# Returns: +# np.ndarray: boxes in out_fmt +# """ +# if not isinstance(boxes, np.ndarray): +# raise TypeError(_BOXES_NOT_NP_ARRAY) +# try: +# return _dtype_to_func_box_convert[boxes.dtype](boxes, in_fmt, out_fmt) # type: ignore +# except KeyError: +# raise TypeError( +# f"Box dtype: {boxes.dtype} not in supported dtypes {supported_dtypes}" +# ) + + +# def masks_to_boxes(masks: npt.NDArray[np.bool_]) -> npt.NDArray[np.uint64]: +# """Convert masks to boxes in xyxy format. + +# Args: +# masks: 3d array of masks in (N, H, W) format + +# Raises: +# TypeError: if masks is not numpy array + +# Returns: +# npt.NDArray[np.uint64]: 2d array of boxes in xyxy format +# """ +# if not isinstance(masks, np.ndarray): +# raise TypeError(_BOXES_NOT_NP_ARRAY) +# return _masks_to_boxes(masks) + + +# def nms( +# boxes: npt.NDArray[T], +# scores: npt.NDArray[np.float64], +# iou_threshold: float, +# score_threshold: float, +# ) -> npt.NDArray[np.uint64]: +# """Apply non-maximum suppression to boxes. + +# Args: +# boxes: 2d array of boxes in xyxy format +# scores: 1d array of scores +# iou_threshold: threshold for iou +# score_threshold: threshold for scores + +# Raises: +# TypeError: if boxes or scores are not numpy arrays + +# Returns: +# npt.NDArray[np.uint64]: 1d array of indices to keep +# """ +# if not isinstance(boxes, np.ndarray) or not isinstance(scores, np.ndarray): +# raise TypeError("Boxes and scores must be numpy arrays") +# try: +# return _dtype_to_func_nms[boxes.dtype]( # type: ignore +# boxes, scores, iou_threshold, score_threshold +# ) +# except KeyError: +# raise TypeError( +# f"Box dtype: {boxes.dtype} not in supported dtypes {supported_dtypes}" +# ) + + +# def rtree_nms( +# boxes: npt.NDArray[Union[np.float64, np.float32, np.int64, np.int32, np.int16]], +# scores: npt.NDArray[np.float64], +# iou_threshold: float, +# score_threshold: float, +# ) -> npt.NDArray[np.uint64]: +# """Apply non-maximum suppression to boxes. + +# Uses an rtree to speed up computation. This is only available for +# signed integer dtypes and float32 and float64. + +# Args: +# boxes: 2d array of boxes in xyxy format +# scores: 1d array of scores +# iou_threshold: threshold for iou +# score_threshold: threshold for scores + +# Raises: +# TypeError: if boxes or scores are not numpy arrays + +# Returns: +# npt.NDArray[np.uint64]: 1d array of indices to keep +# """ +# if not isinstance(boxes, np.ndarray) or not isinstance(scores, np.ndarray): +# raise TypeError("Boxes and scores must be numpy arrays") +# try: +# return _dtype_to_func_rtree_nms[boxes.dtype]( # type: ignore +# boxes, scores, iou_threshold, score_threshold +# ) +# except KeyError: +# raise TypeError( +# f"Box dtype: {boxes.dtype} not in supported dtypes {supported_dtypes}" +# ) __all__ = [ diff --git a/bindings/python/powerboxes/_boxes.py b/bindings/python/powerboxes/_boxes.py index 10718a5..06252ec 100644 --- a/bindings/python/powerboxes/_boxes.py +++ b/bindings/python/powerboxes/_boxes.py @@ -10,24 +10,24 @@ box_areas_u16, box_areas_u32, box_areas_u64, - box_convert_f32, - box_convert_f64, - box_convert_i16, - box_convert_i32, - box_convert_i64, - box_convert_u8, - box_convert_u16, - box_convert_u32, - box_convert_u64, - remove_small_boxes_f32, - remove_small_boxes_f64, - remove_small_boxes_i16, - remove_small_boxes_i32, - remove_small_boxes_i64, - remove_small_boxes_u8, - remove_small_boxes_u16, - remove_small_boxes_u32, - remove_small_boxes_u64, + # box_convert_f32, + # box_convert_f64, + # box_convert_i16, + # box_convert_i32, + # box_convert_i64, + # box_convert_u8, + # box_convert_u16, + # box_convert_u32, + # box_convert_u64, + # remove_small_boxes_f32, + # remove_small_boxes_f64, + # remove_small_boxes_i16, + # remove_small_boxes_i32, + # remove_small_boxes_i64, + # remove_small_boxes_u8, + # remove_small_boxes_u16, + # remove_small_boxes_u32, + # remove_small_boxes_u64, ) _dtype_to_func_box_areas = { @@ -42,26 +42,26 @@ np.dtype("uint8"): box_areas_u8, } -_dtype_to_func_box_convert = { - np.dtype("float64"): box_convert_f64, - np.dtype("float32"): box_convert_f32, - np.dtype("int64"): box_convert_i64, - np.dtype("int32"): box_convert_i32, - np.dtype("int16"): box_convert_i16, - np.dtype("uint64"): box_convert_u64, - np.dtype("uint32"): box_convert_u32, - np.dtype("uint16"): box_convert_u16, - np.dtype("uint8"): box_convert_u8, -} +# _dtype_to_func_box_convert = { +# np.dtype("float64"): box_convert_f64, +# np.dtype("float32"): box_convert_f32, +# np.dtype("int64"): box_convert_i64, +# np.dtype("int32"): box_convert_i32, +# np.dtype("int16"): box_convert_i16, +# np.dtype("uint64"): box_convert_u64, +# np.dtype("uint32"): box_convert_u32, +# np.dtype("uint16"): box_convert_u16, +# np.dtype("uint8"): box_convert_u8, +# } -_dtype_to_func_remove_small_boxes = { - np.dtype("float64"): remove_small_boxes_f64, - np.dtype("float32"): remove_small_boxes_f32, - np.dtype("int64"): remove_small_boxes_i64, - np.dtype("int32"): remove_small_boxes_i32, - np.dtype("int16"): remove_small_boxes_i16, - np.dtype("uint64"): remove_small_boxes_u64, - np.dtype("uint32"): remove_small_boxes_u32, - np.dtype("uint16"): remove_small_boxes_u16, - np.dtype("uint8"): remove_small_boxes_u8, -} +# _dtype_to_func_remove_small_boxes = { +# np.dtype("float64"): remove_small_boxes_f64, +# np.dtype("float32"): remove_small_boxes_f32, +# np.dtype("int64"): remove_small_boxes_i64, +# np.dtype("int32"): remove_small_boxes_i32, +# np.dtype("int16"): remove_small_boxes_i16, +# np.dtype("uint64"): remove_small_boxes_u64, +# np.dtype("uint32"): remove_small_boxes_u32, +# np.dtype("uint16"): remove_small_boxes_u16, +# np.dtype("uint8"): remove_small_boxes_u8, +# } diff --git a/bindings/python/powerboxes/_diou.py b/bindings/python/powerboxes/_diou.py index dd46265..6a21a59 100644 --- a/bindings/python/powerboxes/_diou.py +++ b/bindings/python/powerboxes/_diou.py @@ -1,11 +1,11 @@ -import numpy as np +# import numpy as np -from ._powerboxes import ( - diou_distance_f32, - diou_distance_f64, -) +# from ._powerboxes import ( +# diou_distance_f32, +# diou_distance_f64, +# ) -_dtype_to_func_diou_distance = { - np.dtype("float64"): diou_distance_f64, - np.dtype("float32"): diou_distance_f32, -} +# _dtype_to_func_diou_distance = { +# np.dtype("float64"): diou_distance_f64, +# np.dtype("float32"): diou_distance_f32, +# } diff --git a/bindings/python/powerboxes/_giou.py b/bindings/python/powerboxes/_giou.py index 843b045..2bf9461 100644 --- a/bindings/python/powerboxes/_giou.py +++ b/bindings/python/powerboxes/_giou.py @@ -1,45 +1,45 @@ -import numpy as np +# import numpy as np -from ._powerboxes import ( - giou_distance_f32, - giou_distance_f64, - giou_distance_i16, - giou_distance_i32, - giou_distance_i64, - giou_distance_u8, - giou_distance_u16, - giou_distance_u32, - giou_distance_u64, - parallel_giou_distance_f32, - parallel_giou_distance_f64, - parallel_giou_distance_i16, - parallel_giou_distance_i32, - parallel_giou_distance_i64, - parallel_giou_distance_u8, - parallel_giou_distance_u16, - parallel_giou_distance_u32, - parallel_giou_distance_u64, -) +# from ._powerboxes import ( +# giou_distance_f32, +# giou_distance_f64, +# giou_distance_i16, +# giou_distance_i32, +# giou_distance_i64, +# giou_distance_u8, +# giou_distance_u16, +# giou_distance_u32, +# giou_distance_u64, +# parallel_giou_distance_f32, +# parallel_giou_distance_f64, +# parallel_giou_distance_i16, +# parallel_giou_distance_i32, +# parallel_giou_distance_i64, +# parallel_giou_distance_u8, +# parallel_giou_distance_u16, +# parallel_giou_distance_u32, +# parallel_giou_distance_u64, +# ) -_dtype_to_func_giou_distance = { - np.dtype("float64"): giou_distance_f64, - np.dtype("float32"): giou_distance_f32, - np.dtype("int64"): giou_distance_i64, - np.dtype("int32"): giou_distance_i32, - np.dtype("int16"): giou_distance_i16, - np.dtype("uint64"): giou_distance_u64, - np.dtype("uint32"): giou_distance_u32, - np.dtype("uint16"): giou_distance_u16, - np.dtype("uint8"): giou_distance_u8, -} -_dtype_to_func_parallel_giou_distance = { - np.dtype("float64"): parallel_giou_distance_f64, - np.dtype("float32"): parallel_giou_distance_f32, - np.dtype("int64"): parallel_giou_distance_i64, - np.dtype("int32"): parallel_giou_distance_i32, - np.dtype("int16"): parallel_giou_distance_i16, - np.dtype("uint64"): parallel_giou_distance_u64, - np.dtype("uint32"): parallel_giou_distance_u32, - np.dtype("uint16"): parallel_giou_distance_u16, - np.dtype("uint8"): parallel_giou_distance_u8, -} +# _dtype_to_func_giou_distance = { +# np.dtype("float64"): giou_distance_f64, +# np.dtype("float32"): giou_distance_f32, +# np.dtype("int64"): giou_distance_i64, +# np.dtype("int32"): giou_distance_i32, +# np.dtype("int16"): giou_distance_i16, +# np.dtype("uint64"): giou_distance_u64, +# np.dtype("uint32"): giou_distance_u32, +# np.dtype("uint16"): giou_distance_u16, +# np.dtype("uint8"): giou_distance_u8, +# } +# _dtype_to_func_parallel_giou_distance = { +# np.dtype("float64"): parallel_giou_distance_f64, +# np.dtype("float32"): parallel_giou_distance_f32, +# np.dtype("int64"): parallel_giou_distance_i64, +# np.dtype("int32"): parallel_giou_distance_i32, +# np.dtype("int16"): parallel_giou_distance_i16, +# np.dtype("uint64"): parallel_giou_distance_u64, +# np.dtype("uint32"): parallel_giou_distance_u32, +# np.dtype("uint16"): parallel_giou_distance_u16, +# np.dtype("uint8"): parallel_giou_distance_u8, +# } diff --git a/bindings/python/powerboxes/_iou.py b/bindings/python/powerboxes/_iou.py index 87e0017..bf2f5cf 100644 --- a/bindings/python/powerboxes/_iou.py +++ b/bindings/python/powerboxes/_iou.py @@ -1,45 +1,45 @@ -import numpy as np +# import numpy as np -from ._powerboxes import ( - iou_distance_f32, - iou_distance_f64, - iou_distance_i16, - iou_distance_i32, - iou_distance_i64, - iou_distance_u8, - iou_distance_u16, - iou_distance_u32, - iou_distance_u64, - parallel_iou_distance_f32, - parallel_iou_distance_f64, - parallel_iou_distance_i16, - parallel_iou_distance_i32, - parallel_iou_distance_i64, - parallel_iou_distance_u8, - parallel_iou_distance_u16, - parallel_iou_distance_u32, - parallel_iou_distance_u64, -) +# from ._powerboxes import ( +# iou_distance_f32, +# iou_distance_f64, +# iou_distance_i16, +# iou_distance_i32, +# iou_distance_i64, +# iou_distance_u8, +# iou_distance_u16, +# iou_distance_u32, +# iou_distance_u64, +# parallel_iou_distance_f32, +# parallel_iou_distance_f64, +# parallel_iou_distance_i16, +# parallel_iou_distance_i32, +# parallel_iou_distance_i64, +# parallel_iou_distance_u8, +# parallel_iou_distance_u16, +# parallel_iou_distance_u32, +# parallel_iou_distance_u64, +# ) -_dtype_to_func_parallel_iou_distance = { - np.dtype("float64"): parallel_iou_distance_f64, - np.dtype("float32"): parallel_iou_distance_f32, - np.dtype("int64"): parallel_iou_distance_i64, - np.dtype("int32"): parallel_iou_distance_i32, - np.dtype("int16"): parallel_iou_distance_i16, - np.dtype("uint64"): parallel_iou_distance_u64, - np.dtype("uint32"): parallel_iou_distance_u32, - np.dtype("uint16"): parallel_iou_distance_u16, - np.dtype("uint8"): parallel_iou_distance_u8, -} -_dtype_to_func_iou_distance = { - np.dtype("float64"): iou_distance_f64, - np.dtype("float32"): iou_distance_f32, - np.dtype("int64"): iou_distance_i64, - np.dtype("int32"): iou_distance_i32, - np.dtype("int16"): iou_distance_i16, - np.dtype("uint64"): iou_distance_u64, - np.dtype("uint32"): iou_distance_u32, - np.dtype("uint16"): iou_distance_u16, - np.dtype("uint8"): iou_distance_u8, -} +# _dtype_to_func_parallel_iou_distance = { +# np.dtype("float64"): parallel_iou_distance_f64, +# np.dtype("float32"): parallel_iou_distance_f32, +# np.dtype("int64"): parallel_iou_distance_i64, +# np.dtype("int32"): parallel_iou_distance_i32, +# np.dtype("int16"): parallel_iou_distance_i16, +# np.dtype("uint64"): parallel_iou_distance_u64, +# np.dtype("uint32"): parallel_iou_distance_u32, +# np.dtype("uint16"): parallel_iou_distance_u16, +# np.dtype("uint8"): parallel_iou_distance_u8, +# } +# _dtype_to_func_iou_distance = { +# np.dtype("float64"): iou_distance_f64, +# np.dtype("float32"): iou_distance_f32, +# np.dtype("int64"): iou_distance_i64, +# np.dtype("int32"): iou_distance_i32, +# np.dtype("int16"): iou_distance_i16, +# np.dtype("uint64"): iou_distance_u64, +# np.dtype("uint32"): iou_distance_u32, +# np.dtype("uint16"): iou_distance_u16, +# np.dtype("uint8"): iou_distance_u8, +# } diff --git a/bindings/python/powerboxes/_nms.py b/bindings/python/powerboxes/_nms.py index 2d1efac..5fced5f 100644 --- a/bindings/python/powerboxes/_nms.py +++ b/bindings/python/powerboxes/_nms.py @@ -1,38 +1,38 @@ -import numpy as np +# import numpy as np -from ._powerboxes import ( - nms_f32, - nms_f64, - nms_i16, - nms_i32, - nms_i64, - nms_u8, - nms_u16, - nms_u32, - nms_u64, - rtree_nms_f32, - rtree_nms_f64, - rtree_nms_i16, - rtree_nms_i32, - rtree_nms_i64, -) +# from ._powerboxes import ( +# nms_f32, +# nms_f64, +# nms_i16, +# nms_i32, +# nms_i64, +# nms_u8, +# nms_u16, +# nms_u32, +# nms_u64, +# rtree_nms_f32, +# rtree_nms_f64, +# rtree_nms_i16, +# rtree_nms_i32, +# rtree_nms_i64, +# ) -_dtype_to_func_nms = { - np.dtype("float64"): nms_f64, - np.dtype("float32"): nms_f32, - np.dtype("int64"): nms_i64, - np.dtype("int32"): nms_i32, - np.dtype("int16"): nms_i16, - np.dtype("uint64"): nms_u64, - np.dtype("uint32"): nms_u32, - np.dtype("uint16"): nms_u16, - np.dtype("uint8"): nms_u8, -} +# _dtype_to_func_nms = { +# np.dtype("float64"): nms_f64, +# np.dtype("float32"): nms_f32, +# np.dtype("int64"): nms_i64, +# np.dtype("int32"): nms_i32, +# np.dtype("int16"): nms_i16, +# np.dtype("uint64"): nms_u64, +# np.dtype("uint32"): nms_u32, +# np.dtype("uint16"): nms_u16, +# np.dtype("uint8"): nms_u8, +# } -_dtype_to_func_rtree_nms = { - np.dtype("float64"): rtree_nms_f64, - np.dtype("float32"): rtree_nms_f32, - np.dtype("int64"): rtree_nms_i64, - np.dtype("int32"): rtree_nms_i32, - np.dtype("int16"): rtree_nms_i16, -} +# _dtype_to_func_rtree_nms = { +# np.dtype("float64"): rtree_nms_f64, +# np.dtype("float32"): rtree_nms_f32, +# np.dtype("int64"): rtree_nms_i64, +# np.dtype("int32"): rtree_nms_i32, +# np.dtype("int16"): rtree_nms_i16, +# }