pybboxes


Namepybboxes JSON
Version 0.1.6 PyPI version JSON
download
home_pagehttps://github.com/devrimcavusoglu/pybboxes
SummaryLight Weight Toolkit for Bounding Boxes
upload_time2022-12-29 21:23:46
maintainer
docs_urlNone
authorDevrim Cavusoglu
requires_python>=3.7
licenseMIT
keywords machine-learning deep-learning image-processing pytorch tensorflow numpy bounding-box iou computer-vision cv
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            <h1 align="center">PyBboxes</h1>
<p align="center">
<a href="https://pypi.org/project/pybboxes"><img src="https://img.shields.io/pypi/v/pybboxes?color=blue" alt="Python versions"></a>
<a href="https://pepy.tech/project/pybboxes"><img src="https://pepy.tech/badge/pybboxes" alt="Total downloads"></a>
<a href="https://pypi.org/project/pybboxes"><img src="https://img.shields.io/pypi/dm/pybboxes?color=blue" alt="Monthly downloads"></a>
<br>
<a href="https://pypi.org/project/pybboxes"><img src="https://img.shields.io/pypi/pyversions/pybboxes" alt="Python versions"></a>
<a href="https://github.com/devrimcavusoglu/pybboxes/actions/workflows/ci.yml"><img src="https://img.shields.io/github/workflow/status/devrimcavusoglu/pybboxes/Tests" alt="DOI"></a>
<a href="https://github.com/devrimcavusoglu/pybboxes/blob/main/LICENSE"><img src="https://img.shields.io/github/license/devrimcavusoglu/pybboxes" alt="Python versions"></a>
</p>

Light weight toolkit for bounding boxes providing conversion between bounding box types and simple computations. Supported bounding box types (<ins>italicized text indicates normalized values</ins>):

- **albumentations** : [Albumentations Format](https://albumentations.ai/docs/getting_started/bounding_boxes_augmentation/#albumentations)
  - **_[x-tl, y-tl, x-br, y-br]_** (Normalized VOC Format) Top-left coordinates & Bottom-right coordinates
- **coco** : [COCO (Common Objects in Context)](http://cocodataset.org/)
  - **[x-tl, y-tl, w, h]** Top-left corner & width & height
- **fiftyone** : [FiftyOne](https://github.com/voxel51/fiftyone)
  - **_[x-tl, y-tl, w, h]_** (Normalized COCO Format) Top-left coordinates & width & height
- **voc** : [Pascal VOC](http://host.robots.ox.ac.uk/pascal/VOC/)
  - **[x-tl, y-tl, x-br, y-br]** Top-left coordinates & Bottom-right coordinates
- **yolo** : [YOLO](https://github.com/ultralytics/yolov5)
  - **_[x-c, y-c, w, h]_** Center coordinates & width & height

**Glossary**

- **tl:** top-left
- **br:** bottom-right
- **h:** height
- **w:** width
- **c:** center

### Important Notice
Support for Python<3.8 will be dropped starting version `0.2` though the development for Python3.6 and Python3.7 may 
continue where it will be developed under version `0.1.x` for future versions. This may introduce; however, certain 
discrepancies and/or unsupported operations in the `0.1.x` versions. To fully utilize and benefit from the entire 
package, we recommend using Python3.8 at minimum (`Python>=3.8`).

## Installation

Through pip (recommended),

    pip install pybboxes

or build from source,

    git clone https://github.com/devrimcavusoglu/pybboxes.git
    cd pybboxes
    python setup.py install

## Bounding Boxes

You can easily create bounding box as easy as

```python
from pybboxes import BoundingBox

my_coco_box = [98, 345, 322, 117]
coco_bbox = BoundingBox.from_coco(*my_coco_box)  # <[98 345 322 117] (322x117) | Image: (?x?)>
# or alternatively
# coco_bbox = BoundingBox.from_array(my_coco_box)
```

### Out of Bounds Boxes
Pybboxes supports OOB boxes, there exists a keyword `strict` in both Box classes (construction) and in functional 
modules. When `strict=True`, it does not allow out-of-bounds boxes to be constructed and raises an exception, while 
it does allow out-of-bounds boxes to be constructed and used when `strict=False`. Also, there is a property `is_oob` 
that indicates whether a particular bouding box is OOB or not. 

**Important** Note that, if the return value for `is_oob` is `None`, then it indicates that OOB status is unknown 
(e.g. image size required to determine, but not given). Thus, values `None` and `False` indicates different information.

```python
from pybboxes import BoundingBox

image_size = (640, 480)
my_coco_box = [98, 345, 580, 245]  # OOB box for 640x480
coco_bbox = BoundingBox.from_coco(*my_coco_box, image_size=image_size)  # Exception
# ValueError: Given bounding box values is out of bounds. To silently skip out of bounds cases pass 'strict=False'.

coco_bbox = BoundingBox.from_coco(*my_coco_box, image_size=image_size, strict=False)  # No Exception
coco_bbox.is_oob  # True
```

If you want to allow OOB, but still check OOB status, you should use `strict=False` and `is_oob` where needed.

### Conversion

With the `BoundingBox` class the conversion is as easy as one method call.

```python
from pybboxes import BoundingBox

my_coco_box = [98, 345, 322, 117]
coco_bbox = BoundingBox.from_coco(*my_coco_box)  # <[98 345 322 117] (322x117) | Image: (?x?)>
voc_bbox = coco_bbox.to_voc()  # <[98 345 420 462] (322x117) | Image: (?x?)>
voc_bbox_values = coco_bbox.to_voc(return_values=True)  # (98, 345, 420, 462)
```

However, if you try to make conversion between two bounding boxes that require scaling/normalization it'll give an error

```python
from pybboxes import BoundingBox

my_coco_box = [98, 345, 322, 117]
coco_bbox = BoundingBox.from_coco(*my_coco_box)  # <[98 345 322 117] (322x117) | Image: (?x?)>
# yolo_bbox = coco_bbox.to_yolo()  # this will raise an exception

# You need to set image_size for coco_bbox and then you're good to go
coco_bbox.image_size = (640, 480)
yolo_bbox = coco_bbox.to_yolo()  # <[0.4047 0.8406 0.5031 0.2437] (322x117) | Image: (640x480)>
```

Image size associated with the bounding box can be given at the instantiation or while using classmethods e.g 
`from_coco()`.

```python
from pybboxes import BoundingBox

my_coco_box = [98, 345, 322, 117]
coco_bbox = BoundingBox.from_coco(*my_coco_box, image_size=(640, 480))  # <[98 345 322 117] (322x117) | Image: (640x480)>
# no longer raises exception
yolo_bbox = coco_bbox.to_yolo()  # <[0.4047 0.8406 0.5031 0.2437] (322x117) | Image: (640x480)> 
```

### Box operations

Box operations now available as of `v0.1.0`.

```python
from pybboxes import BoundingBox

my_coco_box = [98, 345, 322, 117]
my_coco_box2 = [90, 350, 310, 122]
coco_bbox = BoundingBox.from_coco(*my_coco_box, image_size=(640, 480))
coco_bbox2 = BoundingBox.from_coco(*my_coco_box2, image_size=(640, 480))

iou = coco_bbox.iou(coco_bbox2)  # 0.8117110631149508
area_union = coco_bbox + coco_bbox2  # 41670 | alternative way: coco_bbox.union(coco_bbox2)
total_area = coco_bbox.area + coco_bbox2.area  # 75494  (not union)
intersection_area = coco_bbox * coco_bbox2  # 33824 | alternative way: coco_bbox.intersection(coco_bbox2)
first_bbox_diff = coco_bbox - coco_bbox2  # 3850
second_bbox_diff = coco_bbox2 - coco_bbox  # 3996
bbox_ratio = coco_bbox / coco_bbox2 # 0.9961396086726599 (not IOU)
```

## Functional

**Note**: functional computations are moved under `pybboxes.functional` starting with the version `0.1.0`. The only 
exception is that  `convert_bbox()` which still can be used by importing `pybboxes` only (for backward compatibility).

### Conversion
You are able to convert from any bounding box type to another.

```python
import pybboxes as pbx

coco_bbox = (1,2,3,4)  # COCO Format bbox as (x-tl,y-tl,w,h)
voc_bbox = (1,2,3,4)  # Pascal VOC Format bbox as (x-tl,y-tl,x-br,y-br)
pbx.convert_bbox(coco_bbox, from_type="coco", to_type="voc")  # (1, 2, 4, 6)
pbx.convert_bbox(voc_bbox, from_type="voc", to_type="coco")  # (1, 2, 2, 2)
```

Some formats require image width and height information for scaling, e.g. YOLO bbox (resulting coordinates 
are rounded to 2 decimals to ease reading).

```python
import pybboxes as pbx

voc_bbox = (1,2,3,4)  # Pascal VOC Format bbox as (x-tl,y-tl,x-br,y-br)
pbx.convert_bbox(voc_bbox, from_type="voc", to_type="yolo", image_size=(28, 28))  # (0.07, 0.11, 0.07, 0.07)
```

### Computation
You can also make computations on supported bounding box formats.

```python
import pybboxes.functional as pbf

coco_bbox = (1,2,3,4)  # COCO Format bbox as (x-tl,y-tl,w,h)
voc_bbox = (1,2,3,4)  # Pascal VOC Format bbox as (x-tl,y-tl,x-br,y-br)
pbf.compute_area(coco_bbox, bbox_type="coco")  # 12
pbf.compute_area(voc_bbox, bbox_type="voc")  # 4
```

## Contributing

### Installation

Install the package as follows, which will set you ready for the development mode.

```shell
pip install -e .[dev]
```

### Tests

To tests simply run.

    python tests/run_tests.py

### Code Style

To check code style,

    python tests/run_code_style.py check

To format codebase,

    python tests/run_code_style.py format

## License

Licensed under the [MIT](LICENSE) License.

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/devrimcavusoglu/pybboxes",
    "name": "pybboxes",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": "",
    "keywords": "machine-learning,deep-learning,image-processing,pytorch,tensorflow,numpy,bounding-box,iou,computer-vision,cv",
    "author": "Devrim Cavusoglu",
    "author_email": "",
    "download_url": "https://files.pythonhosted.org/packages/ab/93/5556dbd5a2f1c83e5c912b2a38ba81dd0b3961a0618b974ecfdb36b65701/pybboxes-0.1.6.tar.gz",
    "platform": null,
    "description": "<h1 align=\"center\">PyBboxes</h1>\n<p align=\"center\">\n<a href=\"https://pypi.org/project/pybboxes\"><img src=\"https://img.shields.io/pypi/v/pybboxes?color=blue\" alt=\"Python versions\"></a>\n<a href=\"https://pepy.tech/project/pybboxes\"><img src=\"https://pepy.tech/badge/pybboxes\" alt=\"Total downloads\"></a>\n<a href=\"https://pypi.org/project/pybboxes\"><img src=\"https://img.shields.io/pypi/dm/pybboxes?color=blue\" alt=\"Monthly downloads\"></a>\n<br>\n<a href=\"https://pypi.org/project/pybboxes\"><img src=\"https://img.shields.io/pypi/pyversions/pybboxes\" alt=\"Python versions\"></a>\n<a href=\"https://github.com/devrimcavusoglu/pybboxes/actions/workflows/ci.yml\"><img src=\"https://img.shields.io/github/workflow/status/devrimcavusoglu/pybboxes/Tests\" alt=\"DOI\"></a>\n<a href=\"https://github.com/devrimcavusoglu/pybboxes/blob/main/LICENSE\"><img src=\"https://img.shields.io/github/license/devrimcavusoglu/pybboxes\" alt=\"Python versions\"></a>\n</p>\n\nLight weight toolkit for bounding boxes providing conversion between bounding box types and simple computations. Supported bounding box types (<ins>italicized text indicates normalized values</ins>):\n\n- **albumentations** : [Albumentations Format](https://albumentations.ai/docs/getting_started/bounding_boxes_augmentation/#albumentations)\n  - **_[x-tl, y-tl, x-br, y-br]_** (Normalized VOC Format) Top-left coordinates & Bottom-right coordinates\n- **coco** : [COCO (Common Objects in Context)](http://cocodataset.org/)\n  - **[x-tl, y-tl, w, h]** Top-left corner & width & height\n- **fiftyone** : [FiftyOne](https://github.com/voxel51/fiftyone)\n  - **_[x-tl, y-tl, w, h]_** (Normalized COCO Format) Top-left coordinates & width & height\n- **voc** : [Pascal VOC](http://host.robots.ox.ac.uk/pascal/VOC/)\n  - **[x-tl, y-tl, x-br, y-br]** Top-left coordinates & Bottom-right coordinates\n- **yolo** : [YOLO](https://github.com/ultralytics/yolov5)\n  - **_[x-c, y-c, w, h]_** Center coordinates & width & height\n\n**Glossary**\n\n- **tl:** top-left\n- **br:** bottom-right\n- **h:** height\n- **w:** width\n- **c:** center\n\n### Important Notice\nSupport for Python<3.8 will be dropped starting version `0.2` though the development for Python3.6 and Python3.7 may \ncontinue where it will be developed under version `0.1.x` for future versions. This may introduce; however, certain \ndiscrepancies and/or unsupported operations in the `0.1.x` versions. To fully utilize and benefit from the entire \npackage, we recommend using Python3.8 at minimum (`Python>=3.8`).\n\n## Installation\n\nThrough pip (recommended),\n\n    pip install pybboxes\n\nor build from source,\n\n    git clone https://github.com/devrimcavusoglu/pybboxes.git\n    cd pybboxes\n    python setup.py install\n\n## Bounding Boxes\n\nYou can easily create bounding box as easy as\n\n```python\nfrom pybboxes import BoundingBox\n\nmy_coco_box = [98, 345, 322, 117]\ncoco_bbox = BoundingBox.from_coco(*my_coco_box)  # <[98 345 322 117] (322x117) | Image: (?x?)>\n# or alternatively\n# coco_bbox = BoundingBox.from_array(my_coco_box)\n```\n\n### Out of Bounds Boxes\nPybboxes supports OOB boxes, there exists a keyword `strict` in both Box classes (construction) and in functional \nmodules. When `strict=True`, it does not allow out-of-bounds boxes to be constructed and raises an exception, while \nit does allow out-of-bounds boxes to be constructed and used when `strict=False`. Also, there is a property `is_oob` \nthat indicates whether a particular bouding box is OOB or not. \n\n**Important** Note that, if the return value for `is_oob` is `None`, then it indicates that OOB status is unknown \n(e.g. image size required to determine, but not given). Thus, values `None` and `False` indicates different information.\n\n```python\nfrom pybboxes import BoundingBox\n\nimage_size = (640, 480)\nmy_coco_box = [98, 345, 580, 245]  # OOB box for 640x480\ncoco_bbox = BoundingBox.from_coco(*my_coco_box, image_size=image_size)  # Exception\n# ValueError: Given bounding box values is out of bounds. To silently skip out of bounds cases pass 'strict=False'.\n\ncoco_bbox = BoundingBox.from_coco(*my_coco_box, image_size=image_size, strict=False)  # No Exception\ncoco_bbox.is_oob  # True\n```\n\nIf you want to allow OOB, but still check OOB status, you should use `strict=False` and `is_oob` where needed.\n\n### Conversion\n\nWith the `BoundingBox` class the conversion is as easy as one method call.\n\n```python\nfrom pybboxes import BoundingBox\n\nmy_coco_box = [98, 345, 322, 117]\ncoco_bbox = BoundingBox.from_coco(*my_coco_box)  # <[98 345 322 117] (322x117) | Image: (?x?)>\nvoc_bbox = coco_bbox.to_voc()  # <[98 345 420 462] (322x117) | Image: (?x?)>\nvoc_bbox_values = coco_bbox.to_voc(return_values=True)  # (98, 345, 420, 462)\n```\n\nHowever, if you try to make conversion between two bounding boxes that require scaling/normalization it'll give an error\n\n```python\nfrom pybboxes import BoundingBox\n\nmy_coco_box = [98, 345, 322, 117]\ncoco_bbox = BoundingBox.from_coco(*my_coco_box)  # <[98 345 322 117] (322x117) | Image: (?x?)>\n# yolo_bbox = coco_bbox.to_yolo()  # this will raise an exception\n\n# You need to set image_size for coco_bbox and then you're good to go\ncoco_bbox.image_size = (640, 480)\nyolo_bbox = coco_bbox.to_yolo()  # <[0.4047 0.8406 0.5031 0.2437] (322x117) | Image: (640x480)>\n```\n\nImage size associated with the bounding box can be given at the instantiation or while using classmethods e.g \n`from_coco()`.\n\n```python\nfrom pybboxes import BoundingBox\n\nmy_coco_box = [98, 345, 322, 117]\ncoco_bbox = BoundingBox.from_coco(*my_coco_box, image_size=(640, 480))  # <[98 345 322 117] (322x117) | Image: (640x480)>\n# no longer raises exception\nyolo_bbox = coco_bbox.to_yolo()  # <[0.4047 0.8406 0.5031 0.2437] (322x117) | Image: (640x480)> \n```\n\n### Box operations\n\nBox operations now available as of `v0.1.0`.\n\n```python\nfrom pybboxes import BoundingBox\n\nmy_coco_box = [98, 345, 322, 117]\nmy_coco_box2 = [90, 350, 310, 122]\ncoco_bbox = BoundingBox.from_coco(*my_coco_box, image_size=(640, 480))\ncoco_bbox2 = BoundingBox.from_coco(*my_coco_box2, image_size=(640, 480))\n\niou = coco_bbox.iou(coco_bbox2)  # 0.8117110631149508\narea_union = coco_bbox + coco_bbox2  # 41670 | alternative way: coco_bbox.union(coco_bbox2)\ntotal_area = coco_bbox.area + coco_bbox2.area  # 75494  (not union)\nintersection_area = coco_bbox * coco_bbox2  # 33824 | alternative way: coco_bbox.intersection(coco_bbox2)\nfirst_bbox_diff = coco_bbox - coco_bbox2  # 3850\nsecond_bbox_diff = coco_bbox2 - coco_bbox  # 3996\nbbox_ratio = coco_bbox / coco_bbox2 # 0.9961396086726599 (not IOU)\n```\n\n## Functional\n\n**Note**: functional computations are moved under `pybboxes.functional` starting with the version `0.1.0`. The only \nexception is that  `convert_bbox()` which still can be used by importing `pybboxes` only (for backward compatibility).\n\n### Conversion\nYou are able to convert from any bounding box type to another.\n\n```python\nimport pybboxes as pbx\n\ncoco_bbox = (1,2,3,4)  # COCO Format bbox as (x-tl,y-tl,w,h)\nvoc_bbox = (1,2,3,4)  # Pascal VOC Format bbox as (x-tl,y-tl,x-br,y-br)\npbx.convert_bbox(coco_bbox, from_type=\"coco\", to_type=\"voc\")  # (1, 2, 4, 6)\npbx.convert_bbox(voc_bbox, from_type=\"voc\", to_type=\"coco\")  # (1, 2, 2, 2)\n```\n\nSome formats require image width and height information for scaling, e.g. YOLO bbox (resulting coordinates \nare rounded to 2 decimals to ease reading).\n\n```python\nimport pybboxes as pbx\n\nvoc_bbox = (1,2,3,4)  # Pascal VOC Format bbox as (x-tl,y-tl,x-br,y-br)\npbx.convert_bbox(voc_bbox, from_type=\"voc\", to_type=\"yolo\", image_size=(28, 28))  # (0.07, 0.11, 0.07, 0.07)\n```\n\n### Computation\nYou can also make computations on supported bounding box formats.\n\n```python\nimport pybboxes.functional as pbf\n\ncoco_bbox = (1,2,3,4)  # COCO Format bbox as (x-tl,y-tl,w,h)\nvoc_bbox = (1,2,3,4)  # Pascal VOC Format bbox as (x-tl,y-tl,x-br,y-br)\npbf.compute_area(coco_bbox, bbox_type=\"coco\")  # 12\npbf.compute_area(voc_bbox, bbox_type=\"voc\")  # 4\n```\n\n## Contributing\n\n### Installation\n\nInstall the package as follows, which will set you ready for the development mode.\n\n```shell\npip install -e .[dev]\n```\n\n### Tests\n\nTo tests simply run.\n\n    python tests/run_tests.py\n\n### Code Style\n\nTo check code style,\n\n    python tests/run_code_style.py check\n\nTo format codebase,\n\n    python tests/run_code_style.py format\n\n## License\n\nLicensed under the [MIT](LICENSE) License.\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Light Weight Toolkit for Bounding Boxes",
    "version": "0.1.6",
    "split_keywords": [
        "machine-learning",
        "deep-learning",
        "image-processing",
        "pytorch",
        "tensorflow",
        "numpy",
        "bounding-box",
        "iou",
        "computer-vision",
        "cv"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "md5": "8939aca30f843f7a5c17109bc10d32f7",
                "sha256": "e6f7ca43a38bfe2c6ec5b67c6f6e95790e5d9c8c41d84ef11ba896fe181816d5"
            },
            "downloads": -1,
            "filename": "pybboxes-0.1.6-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "8939aca30f843f7a5c17109bc10d32f7",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 24858,
            "upload_time": "2022-12-29T21:23:44",
            "upload_time_iso_8601": "2022-12-29T21:23:44.654369Z",
            "url": "https://files.pythonhosted.org/packages/3c/3f/46f6613b41a3c2b4f7af3b526035771ca5bb12d6fdf3b23145899f785e36/pybboxes-0.1.6-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "md5": "fe9ab647fc49401b881431ab2c9bfd2b",
                "sha256": "558bfd2a7ca37def07ac95108f3b6504d728332b0c5b871df1017de5c7c1f68d"
            },
            "downloads": -1,
            "filename": "pybboxes-0.1.6.tar.gz",
            "has_sig": false,
            "md5_digest": "fe9ab647fc49401b881431ab2c9bfd2b",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 19019,
            "upload_time": "2022-12-29T21:23:46",
            "upload_time_iso_8601": "2022-12-29T21:23:46.008594Z",
            "url": "https://files.pythonhosted.org/packages/ab/93/5556dbd5a2f1c83e5c912b2a38ba81dd0b3961a0618b974ecfdb36b65701/pybboxes-0.1.6.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2022-12-29 21:23:46",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "github_user": "devrimcavusoglu",
    "github_project": "pybboxes",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [],
    "lcname": "pybboxes"
}
        
Elapsed time: 0.02204s