# roi2bb
### "3D Slicer ROI" to "YOLO Bounding Box" Coordinates Converter for Medical Imaging
This repository provides a Python class, `roi2bb`, bridging the gap between ground truth preparation and model training for 3D volumetric medical imaging, by converting Regions of Interest (ROI) bounding boxes stored in 3D Slicer JSON format into YOLO models input format.
When it comes to volumetric medical imaging data, there are few tools (if any) available for 3D bounding box annotation. 3D Slicer is a robust open-source tool for all types of data visualization, processing and annotation. 3D Slicer's **ROI** function of [**markups** module](https://slicer.readthedocs.io/en/latest/user_guide/modules/markups.html), offers a user-friendly interface to generate 3D bounding boxes around the object/region of interest, edit and rotate them in axial, coronal and sagittal planes for object-oriented tasks and visualize them in 3D view. The central coordinates and the dimensions of these ROI boxes can be extracted as a JSON file, but the output is not compatible with the "Image coordinates System", which is the format compatible with the well-known YOLO family of deep learning models.
These two [coordinate systems](https://slicer.readthedocs.io/en/latest/user_guide/coordinate_systems.html) have 3 main differences that should be addressed while converting:
1. The Slicer output follows the **"Patient coordinate system"**, in which its origin is located at an anatomical landmark not necessarily in the image boundaries, while the YOLO-compatible input format is based on the **"Image coordinate system"**, in which its origin is located at the upper-left corner of the image. Also, the axis directions are not the same in different coordinate systems, changing the point coordinate values.
2. The Slicer format dimensions are the actual ROI dimensions, while the Yolo format dimensions are a ratio of ROI dimension to image dimensions.
3. The Slicer output is in JSON format with the ROI 'center' coordinates (x,y,z) and ROI dimensions 'size' (x_length, y_length,z_length) reported under 'markups' tag, while YOLO-compatible input is a text file with each line presenting one ROI containing:
```"class center_z center_x center_y width height depth"```
The Slicer gives a separate JSON file for each ROI, while a single YOLO text file contains multiple ROIs for multiple classes, each class defined by a unique index and each ROI reported in a separate line.
roi2bb offers CLI support for single annotations and python API for several images and multi-class annotations.
## Table of Contents:
- [Requirements](#requirements)
- [Installation](#installation)
- [Directory Structure](#directory-structure)
- [Class Index Mapping](#class-index-mapping)
- [Example Usage](#usage)
- [License](#license)
- [Useful Links](#Useful-Links)
## Requirements:
- Python 3.x
- os
- glob
- numpy
- json
- argparse
- nibabel/pydicom/PIL/cv2/SimpleITK #depending on your images format
## Installation
```bash
pip install roi2bb
```
or
Simply download the `roi2bb` repository from the upper-right "Code" button dropdown menu, navigate to the roi2bb folder, organize your data to be compatible with the tool (see [Directory Structure](#directory-structure)).
Here is a stepwise guide to use `roi2bb`:
### Directory Structure:
Since, yolo text format contains all classes and all labels per class in a single file, roi2bb has to process the whole directory of all annotations at once.
roi2bb expects the below structure for images and labels. It automatically defines unique class IDs (1,2,3) by mapping the unique classes detected in JSON file names. You can also define your desired mapping using the Python API.
```
project_directory/
├── images/
│ ├── Patient_001.nii or .nii.gz
│ ├── Patient_002.nii
│ │──...
├── labels/
│ ├── Patient_001/
│ │ ├── left_atrium.json
│ │ ├── lymph_node_1.json
│ │ ├── lymph_node_2.json
│ │ ├── lymph_node_3.json
│ │ └── trachea.json
│ ├── Patient_002/
│ │ ├── left_atrium.json
│ │ ├── lymph_node.json
│ │ └── trachea.json
│ │── ...
| └── Patient_n
└── output/
│── Patient_001.txt
│── Patient_002.txt
|── ...
└── Patient_n
```
### Class Index Mapping:
converter = roi2bb("path_to_image_file.nii", "path_to_json_folder", "output_yolo_format.txt", class_map:dic = class_map)
```bash
class_map = {
"left_atrium": 1,
"lymph_node": 2,
"trachea": 3,
...
}
```
### Example Usage:
Now that you downloaded the repository, organized your data and customized your labels, you can use the following commands in a command line interface (CLI) or the next one in a Python interface to convert ROIs to YOLO format by `roi2bb`:
**CLI**
```bash
roi2bb example.nii.gz annotations/ output.txt
```
**Python API**
```bash
from roi2bb.converter import Converter
image_files_list = Path to the medical images
json_folders_list = Folders containing the 3D Slicer JSON annotation files corresponding to ptient_n
output_files_list = Path to save the .txt outputs containing YOLO format annotations
for image_file_path, json_folder_path, output_file_path in zip(image_files_list, json_folders_list, output_files_list)
converter = Converter(image_file_path, json_folder_path, output_file_path)
converter.run()
```
### Example Output:
```bash
0 0.523 0.312 0.532 0.128 0.276 0.345 # left_atrium
1 0.734 0.512 0.723 0.132 0.254 0.367 # lymph_node_1
1 0.834 0.612 0.823 0.152 0.274 0.447 # lymph_node_2
2 0.634 0.412 0.623 0.112 0.234 0.287 # trachea
```
### License:
```roi2bb``` is released under the MIT License. See the [LICENSE](LICENSE) file for more details.
### Useful Links
[3D Slicer web page](https://www.slicer.org/) for volumetric medical imaging annotation
[Learn more about the coordinates systems](https://slicer.readthedocs.io/en/latest/user_guide/coordinate_systems.html)
### Contact:
Developer: Elham Mahmoudi
Email: mahmoudi.elham91@gmail.com
GitHub: [https://github.com/elimah91/roi2bb](https://github.com/elimah91/roi2bb)
Raw data
{
"_id": null,
"home_page": null,
"name": "roi2bb",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": "Elham Mahmoudi <mahmoudi.elham91@gmail.com>",
"keywords": "medical-imaging, 3d-slicer, yolo, bounding-box, roi, deep-learning, computer-vision",
"author": null,
"author_email": "Elham Mahmoudi <mahmoudi.elham91@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/ca/ca/0d2112f90b2b5f641c41e964b8245c213fa30df069fc3f24cb7209cc4920/roi2bb-0.1.0.tar.gz",
"platform": null,
"description": "# roi2bb\n### \"3D Slicer ROI\" to \"YOLO Bounding Box\" Coordinates Converter for Medical Imaging\nThis repository provides a Python class, `roi2bb`, bridging the gap between ground truth preparation and model training for 3D volumetric medical imaging, by converting Regions of Interest (ROI) bounding boxes stored in 3D Slicer JSON format into YOLO models input format. \n\nWhen it comes to volumetric medical imaging data, there are few tools (if any) available for 3D bounding box annotation. 3D Slicer is a robust open-source tool for all types of data visualization, processing and annotation. 3D Slicer's **ROI** function of [**markups** module](https://slicer.readthedocs.io/en/latest/user_guide/modules/markups.html), offers a user-friendly interface to generate 3D bounding boxes around the object/region of interest, edit and rotate them in axial, coronal and sagittal planes for object-oriented tasks and visualize them in 3D view. The central coordinates and the dimensions of these ROI boxes can be extracted as a JSON file, but the output is not compatible with the \"Image coordinates System\", which is the format compatible with the well-known YOLO family of deep learning models. \n\nThese two [coordinate systems](https://slicer.readthedocs.io/en/latest/user_guide/coordinate_systems.html) have 3 main differences that should be addressed while converting:\n\n1. The Slicer output follows the **\"Patient coordinate system\"**, in which its origin is located at an anatomical landmark not necessarily in the image boundaries, while the YOLO-compatible input format is based on the **\"Image coordinate system\"**, in which its origin is located at the upper-left corner of the image. Also, the axis directions are not the same in different coordinate systems, changing the point coordinate values.\n \n2. The Slicer format dimensions are the actual ROI dimensions, while the Yolo format dimensions are a ratio of ROI dimension to image dimensions. \n\n3. The Slicer output is in JSON format with the ROI 'center' coordinates (x,y,z) and ROI dimensions 'size' (x_length, y_length,z_length) reported under 'markups' tag, while YOLO-compatible input is a text file with each line presenting one ROI containing: \n\n ```\"class center_z center_x center_y width height depth\"```\n\n The Slicer gives a separate JSON file for each ROI, while a single YOLO text file contains multiple ROIs for multiple classes, each class defined by a unique index and each ROI reported in a separate line.\n \nroi2bb offers CLI support for single annotations and python API for several images and multi-class annotations. \n\n## Table of Contents:\n\n- [Requirements](#requirements)\n- [Installation](#installation)\n - [Directory Structure](#directory-structure)\n - [Class Index Mapping](#class-index-mapping)\n - [Example Usage](#usage)\n- [License](#license)\n- [Useful Links](#Useful-Links)\n\n## Requirements:\n\n- Python 3.x\n- os\n- glob\n- numpy\n- json\n- argparse\n- nibabel/pydicom/PIL/cv2/SimpleITK #depending on your images format\n\n## Installation\n```bash\npip install roi2bb\n```\nor\n\nSimply download the `roi2bb` repository from the upper-right \"Code\" button dropdown menu, navigate to the roi2bb folder, organize your data to be compatible with the tool (see [Directory Structure](#directory-structure)).\n\nHere is a stepwise guide to use `roi2bb`:\n\n### Directory Structure:\nSince, yolo text format contains all classes and all labels per class in a single file, roi2bb has to process the whole directory of all annotations at once.\nroi2bb expects the below structure for images and labels. It automatically defines unique class IDs (1,2,3) by mapping the unique classes detected in JSON file names. You can also define your desired mapping using the Python API.\n\n```\nproject_directory/\n\u251c\u2500\u2500 images/\n\u2502 \u251c\u2500\u2500 Patient_001.nii or .nii.gz\n\u2502 \u251c\u2500\u2500 Patient_002.nii\n\u2502 \u2502\u2500\u2500...\n\u251c\u2500\u2500 labels/\n\u2502 \u251c\u2500\u2500 Patient_001/\n\u2502 \u2502 \u251c\u2500\u2500 left_atrium.json\n\u2502 \u2502 \u251c\u2500\u2500 lymph_node_1.json\n\u2502 \u2502 \u251c\u2500\u2500 lymph_node_2.json\n\u2502 \u2502 \u251c\u2500\u2500 lymph_node_3.json\n\u2502 \u2502 \u2514\u2500\u2500 trachea.json\n\u2502 \u251c\u2500\u2500 Patient_002/\n\u2502 \u2502 \u251c\u2500\u2500 left_atrium.json\n\u2502 \u2502 \u251c\u2500\u2500 lymph_node.json\n\u2502 \u2502 \u2514\u2500\u2500 trachea.json\n\u2502 \u2502\u2500\u2500 ...\n| \u2514\u2500\u2500 Patient_n\n\u2514\u2500\u2500 output/\n \u2502\u2500\u2500 Patient_001.txt\n \u2502\u2500\u2500 Patient_002.txt\n |\u2500\u2500 ...\n \u2514\u2500\u2500 Patient_n\n```\n### Class Index Mapping:\n\nconverter = roi2bb(\"path_to_image_file.nii\", \"path_to_json_folder\", \"output_yolo_format.txt\", class_map:dic = class_map)\n\n```bash\nclass_map = {\n \"left_atrium\": 1,\n \"lymph_node\": 2,\n \"trachea\": 3,\n ...\n }\n```\n### Example Usage:\n\n\nNow that you downloaded the repository, organized your data and customized your labels, you can use the following commands in a command line interface (CLI) or the next one in a Python interface to convert ROIs to YOLO format by `roi2bb`:\n\n**CLI**\n```bash\nroi2bb example.nii.gz annotations/ output.txt\n```\n**Python API**\n```bash\nfrom roi2bb.converter import Converter\n\nimage_files_list = Path to the medical images\njson_folders_list = Folders containing the 3D Slicer JSON annotation files corresponding to ptient_n\noutput_files_list = Path to save the .txt outputs containing YOLO format annotations\n\nfor image_file_path, json_folder_path, output_file_path in zip(image_files_list, json_folders_list, output_files_list)\n converter = Converter(image_file_path, json_folder_path, output_file_path)\n converter.run()\n```\n\n### Example Output:\n```bash\n0 0.523 0.312 0.532 0.128 0.276 0.345 # left_atrium\n1 0.734 0.512 0.723 0.132 0.254 0.367 # lymph_node_1\n1 0.834 0.612 0.823 0.152 0.274 0.447 # lymph_node_2\n2 0.634 0.412 0.623 0.112 0.234 0.287 # trachea\n```\n### License:\n\n```roi2bb``` is released under the MIT License. See the [LICENSE](LICENSE) file for more details.\n\n### Useful Links\n\n[3D Slicer web page](https://www.slicer.org/) for volumetric medical imaging annotation\n\n[Learn more about the coordinates systems](https://slicer.readthedocs.io/en/latest/user_guide/coordinate_systems.html)\n\n\n### Contact:\n\nDeveloper: Elham Mahmoudi\n\nEmail: mahmoudi.elham91@gmail.com\n\nGitHub: [https://github.com/elimah91/roi2bb](https://github.com/elimah91/roi2bb)\n\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "3D Slicer ROI to YOLO Bounding Box Coordinates Converter for Medical Imaging",
"version": "0.1.0",
"project_urls": {
"Documentation": "https://github.com/elimah91/roi2bb#readme",
"Homepage": "https://github.com/elimah91/roi2bb",
"Issues": "https://github.com/elimah91/roi2bb/issues",
"Repository": "https://github.com/elimah91/roi2bb.git"
},
"split_keywords": [
"medical-imaging",
" 3d-slicer",
" yolo",
" bounding-box",
" roi",
" deep-learning",
" computer-vision"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "fb21621ac1d958d6e39c498fd469157307f8226b4e45792064b9e212152861dc",
"md5": "b480ac51bac4e1c29970c1cfe626b074",
"sha256": "e81e2e8cef59b95c37996504c2df36336397cd025a2844b44c45cd674a2f6ed1"
},
"downloads": -1,
"filename": "roi2bb-0.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "b480ac51bac4e1c29970c1cfe626b074",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 10136,
"upload_time": "2025-09-02T03:58:54",
"upload_time_iso_8601": "2025-09-02T03:58:54.261075Z",
"url": "https://files.pythonhosted.org/packages/fb/21/621ac1d958d6e39c498fd469157307f8226b4e45792064b9e212152861dc/roi2bb-0.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "caca0d2112f90b2b5f641c41e964b8245c213fa30df069fc3f24cb7209cc4920",
"md5": "1bb6f1a0b5d04d4fa03d207d6addd0ef",
"sha256": "5f08f07eaba354a7e84125e4f6363abdf6b4e09466a15c9b1c89e8d33aab4ad0"
},
"downloads": -1,
"filename": "roi2bb-0.1.0.tar.gz",
"has_sig": false,
"md5_digest": "1bb6f1a0b5d04d4fa03d207d6addd0ef",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 14753,
"upload_time": "2025-09-02T03:58:55",
"upload_time_iso_8601": "2025-09-02T03:58:55.652782Z",
"url": "https://files.pythonhosted.org/packages/ca/ca/0d2112f90b2b5f641c41e964b8245c213fa30df069fc3f24cb7209cc4920/roi2bb-0.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-09-02 03:58:55",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "elimah91",
"github_project": "roi2bb#readme",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "json",
"specs": []
},
{
"name": "os",
"specs": []
},
{
"name": "glob",
"specs": []
},
{
"name": "numpy",
"specs": []
},
{
"name": "argparse",
"specs": []
},
{
"name": "nibabel",
"specs": []
},
{
"name": "pydicom",
"specs": []
},
{
"name": "PIL",
"specs": []
},
{
"name": "cv2",
"specs": []
},
{
"name": "SimpleITK",
"specs": []
}
],
"lcname": "roi2bb"
}