Skip to content

Commit

Permalink
Merge branch 'feature/merger' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
acl21 committed Dec 30, 2021
2 parents b0802c7 + 8e5fca6 commit 6b05642
Show file tree
Hide file tree
Showing 15 changed files with 748 additions and 595 deletions.
199 changes: 5 additions & 194 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
[![PyPI version](https://badge.fury.io/py/image-bbox-slicer.svg)](https://badge.fury.io/py/image-bbox-slicer) [![](https://img.shields.io/github/license/mashape/apistatus.svg)](LICENSE)
# image_bbox_slicer
# Image and Bounding Box Slicer-Resizer (image_bbox_slicer)

This easy-to-use library is a data transformer sometimes useful in Object Detection tasks. It splits images and their bounding box annotations into tiles, both into specific sizes and into any arbitrary number of equal parts. It can also resize them, both by specific sizes and by a resizing/scaling factor. Of course it goes without saying that just image slicing could in Segmentation tasks (where input and labels both are images). Read the docs [here](https://image-bbox-slicer.readthedocs.io/en/latest/).

<div align="center">
<img src="imgs/ibs_demo.jpg" alt="Partial Labels Example" />
<img src="imgs/ibs_demo2.jpg" alt="Partial Labels Example" />
</div>

Currently, this library only supports bounding box annotations in [PASCAL VOC](http://host.robots.ox.ac.uk/pascal/VOC/) format. And as of now, there is **no command line execution support**. Please raise an issue if needed.
Expand All @@ -14,203 +14,14 @@ Currently, this library only supports bounding box annotations in [PASCAL VOC](h
$ pip install image_bbox_slicer
```

This tool was tested on both Windows and Linx. Works with Python 3.4 and higher versions and requires:
This tool was tested on both Windows and Linx. Works well with Python 3.8.
```python
Pillow
numpy
pascal-voc-writer
matplotlib
```

## Usage - A Quick Demo
_Note: This usage demo can be found in `demo.ipynb` in the repo._
## Slicing Demo: [Docs](https://image-bbox-slicer.readthedocs.io/en/latest/slicing-demo.html) and [Notebook](https://github.com/acl21/image_bbox_slicer/blob/master/Slicing_Demo.ipynb)

```python
import image_bbox_slicer as ibs
```

### Create And Configure `Slicer` Object

#### Setting Paths To Source And Destination Directories.
You must configure paths to source and destination directories like the following.

```python
im_src = './src/images'
an_src = './src/annotations'
im_dst = './dst/images'
an_dst = './dst/annotations'

slicer = ibs.Slicer()
slicer.config_dirs(img_src=im_src, ann_src=an_src,
img_dst=im_dst, ann_dst=an_dst)
```

#### Dealing With Partial Labels
<div align="center">
<img src="imgs/partial_labels.jpg" alt="Partial Labels Example" style="width: 850px;" />
</div>

The above images show the difference in slicing with and without partial labels. In the image on the left, all the box annotations masked in <span style="color:green">**green**</span> are called Partial Labels.

Configure your slicer to either ignore or consider them by setting `Slicer` object's `keep_partial_labels` instance variable to `True` or `False` respectively. By default it is set to `False`.


```python
slicer.keep_partial_labels = True
```

#### Dealing With Empty Tiles
<img src="imgs/empty_tiles.png" alt="Empty Tiles Example" style="width: 850px;"/>

An empty tile is a tile with no "labels" in it. The definition of "labels" here is tightly coupled with the user's preference of partial labels. If you choose to keep the partial labels (i.e. `keep_partial_labels = True`), a tile with a partial label is not treated as empty. If you choose to not keep the partial labels (i.e. `keep_partial_labels = False`), a tile with one or more partial labels is considered empty.

Configure your slicer to either ignore or consider empty tiles by setting `Slicer` object's `ignore_empty_tiles` instance variable to `True` or `False` respectively. By default it is set to `True`.


```python
slicer.ignore_empty_tiles = False
```

#### Before-After Mapping

You can choose to store the mapping between file names of the images before and after slicing by setting the `Slicer` object's `save_before_after_map` instance variable to `True`. By default it is set to `False`.

Typically, `mapper.csv` looks like the following:
```
| old_name | new_names |
|------------|---------------------------------|
| 2102 | 000001, 000002, 000003, 000004 |
| 3931 | 000005, 000005, 000007, 000008 |
| test_image | 000009, 000010, 000011, 000012 |
| ... | ... |
```


```python
slicer.save_before_after_map = True
```

### Slicing

#### Images and Bounding Box Annotations Simultaneously

#### By Number Of Tiles


```python
slicer.slice_by_number(number_tiles=4)
slicer.visualize_sliced_random()
```

<div align="center">
<img src="imgs/output_10_1.png" alt="Output1" style="width: 200px;" />

<img src="imgs/output_10_2.png" alt="Output2" style="width: 200px;" />
</div>


#### By Specific Size

```python
slicer.slice_by_size(tile_size=(418,279), tile_overlap=0)
slicer.visualize_sliced_random()
```


<div align="center">
<img src="imgs/output_12_1.png" alt="Output3" style="width: 200px;" />

<img src="imgs/output_12_2.png" alt="Output4" style="width: 200px;" />
</div>

*Note: `visualize_sliced_random()` randomly picks a recently sliced image from the directory for plotting.*

### Other Slicing Functions

#### By Number Of Tiles
```python
slicer.slice_images_by_number(number_tiles=4)
```

#### By Specific Size
```python
slicer.slice_images_by_size(tile_size=(418,279), tile_overlap=0)
```

#### Slicing Only Bounding Box Annotations
#### By Number Of Tiles
```python
slicer.slice_bboxes_by_number(number_tiles=4)
```

#### By Specifc Size
```python
slicer.slice_bboxes_by_size(tile_size=(418,279), tile_overlap=0)
```

### Resizing
![png](imgs/resize_demo.png)

#### Images and Bounding Box Annotations Simultaneously
#### By Specific Size


```python
slicer.resize_by_size(new_size=(500,200))
slicer.visualize_resized_random()
```


![png](imgs/output_18_0.png)


![png](imgs/output_18_1.png)


#### By A Resize Factor


```python
slicer.resize_by_factor(resize_factor=0.05)
slicer.visualize_resized_random()
```

![png](imgs/output_20_0.png)


![png](imgs/output_20_1.png)

_Note:_

*`visualize_resized_random()` randomly picks a recently resized image from the destination directory for plotting.*


### Other Resizing Functions

#### Resizing Separately

#### Only Images

* #### By Specific Size

```python
slicer.resize_images_by_size(new_size=(500,200))
```

* #### By Resize Factor

```python
slicer.resize_images_by_factor(resize_factor=0.05)
```

#### Only Bounding Box Annotations

* #### By Specific Size
```python
slicer.resize_bboxes_by_size(new_size=(500,200))
```

* #### By Resize Factor
```python
slicer.resize_bboxes_by_factor(resize_factor=0.05)
```
## Resizing Demo: [Docs](https://image-bbox-slicer.readthedocs.io/en/latest/resizing-demo.html) and [Notebook](https://github.com/acl21/image_bbox_slicer/blob/master/Resizing_Demo.ipynb)
217 changes: 217 additions & 0 deletions Resizing_Demo.ipynb

Large diffs are not rendered by default.

154 changes: 26 additions & 128 deletions demo.ipynb → Slicing_Demo.ipynb

Large diffs are not rendered by default.

Binary file modified docs/img/ibs_demo.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Image and Box Annotation Slicer
# Image and Box Annotation Slicer-Resizer

This easy-to-use library is a data transformer sometimes useful in Object Detection tasks. It splits images and its bounding box annotations into tiles, both into specific sizes and into any arbitrary number of equal parts. It can also resize them, both by specific sizes and by a resizing/scaling factor.

<div align="center">
<img src="img/ibs_demo.jpg" alt="Overview" />
<img src="img/ibs_demo.jpg" alt="Overview" width="650" height="1200"/>
</div>
<br>
Currently, this library only supports bounding box annotations in [PASCAL VOC](http://host.robots.ox.ac.uk/pascal/VOC/) format. And as of now, there is **no command line execution support**.
Expand Down
59 changes: 59 additions & 0 deletions docs/resizing-demo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
## Create And Configure `Resizer` Object
_Note: This usage demo can be found in `Resizing_Demo.ipynb` in the project's [repo](https://github.com/acl21/image_bbox_slicer)._

### Setting Paths To Source And Destination Directories
You must configure paths to source and destination directories like the following.
By default it takes the current working directory as the source folder for both images and annotations and also creates new folders:

* `/resized_images` and
* `/resized_annotation`

in the current working directory.

```python
import image_bbox_slicer as ibs

im_src = './src/images'
an_src = './src/annotations'
im_dst = './dst/images'
an_dst = './dst/annotations'

resizer = ibs.Resizer()
resizer.config_dirs(img_src=im_src, ann_src=an_src,
img_dst=im_dst, ann_dst=an_dst)
```

### Images and Bounding Box Annotations Simultaneously

** By Specific Size **


```python
resizer.resize_by_size(new_size=(500,200))
resizer.visualize_resized_random()
```


![png](img/output_18_0.png)


![png](img/output_18_1.png)


** By A Resize Factor **


```python
resizer.resize_by_factor(resize_factor=0.05)
resizer.visualize_resized_random()
```

![png](img/output_20_0.png)


![png](img/output_20_1.png)

_Note:_
*`visualize_resized_random()` randomly picks a recently resized image from the destination directory for plotting.*


59 changes: 12 additions & 47 deletions docs/quick-demo.md → docs/slicing-demo.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
## Create And Configure `Slicer` Object
_Note: This usage demo can be found in `demo.ipynb` in the project's [repo](https://github.com/akshaychandra21/image_bbox_slicer)._
_Note: This usage demo can be found in `Slicing_Demo.ipynb` in the project's [repo](https://github.com/acl21/image_bbox_slicer)._

Setting Paths To Source And Destination Directories
You must configure paths to source and destination directories like the following.
### Setting Paths To Source And Destination Directories
You must configure paths to source and destination directories like the following. By default it takes the current working directory as the source folder for both images and annotations and also creates new folders:

* `/sliced_images` and
* `/sliced_annotation`

in the current working directory.

```python
import image_bbox_slicer as ibs
Expand All @@ -17,7 +22,7 @@ slicer.config_dirs(img_src=im_src, ann_src=an_src,
img_dst=im_dst, ann_dst=an_dst)
```

## Partial Labels
### Partial Labels

![partial](img/partial_labels.jpg)

Expand All @@ -29,7 +34,7 @@ Configure your slicer to either ignore or consider them by setting `Slicer` obje
slicer.keep_partial_labels = True
```

## Empty Tiles
### Empty Tiles
![empty](img/empty_tiles.png)

An empty tile is a tile with no "labels" in it. The definition of "labels" here is tightly coupled with the user's preference of partial labels. If you choose to keep the partial labels (i.e. `keep_partial_labels = True`), a tile with a partial label is not treated as empty. If you choose to not keep the partial labels (i.e. `keep_partial_labels = False`), a tile with one or more partial labels is considered empty.
Expand All @@ -40,7 +45,7 @@ Configure your slicer to either ignore or consider empty tiles by setting `Slice
slicer.ignore_empty_tiles = False
```

## Before-After Mapping
### Before-After Mapping

You can choose to store the mapping between file names of the images before and after slicing by setting the `Slicer` object's `save_before_after_map` instance variable to `True`. By default it is set to `False`.

Expand All @@ -59,9 +64,7 @@ Typically, `mapper.csv` looks like the following:
slicer.save_before_after_map = True
```

## Slicing

Slicing both images and box annotations at the same time.
### Slicing both images and box annotations at the same time.

** By Number Of Tiles **

Expand All @@ -86,41 +89,3 @@ slicer.visualize_random()
![output-4](img/output_12_2.png)

*Note: `visualize_sliced_random()` randomly picks a recently sliced image from the directory for plotting.*

## Resizing
![png](img/resize_demo.png)

Images and Bounding Box Annotations Simultaneously

** By Specific Size **


```python
slicer.resize_by_size(new_size=(500,200))
slicer.visualize_resized_random()
```


![png](img/output_18_0.png)


![png](img/output_18_1.png)


** By A Resize Factor **


```python
slicer.resize_by_factor(resize_factor=0.05)
slicer.visualize_resized_random()
```

![png](img/output_20_0.png)


![png](img/output_20_1.png)

_Note:_
*`visualize_resized_random()` randomly picks a recently resized image from the destination directory for plotting.*


Loading

0 comments on commit 6b05642

Please sign in to comment.