# default_exp datasets.generators_legacy
%load_ext autoreload
%autoreload 2
from nbdev import *
from typing import List, Tuple

Helpers for Dataset Generation

Use tmp dir

import tempfile
tmp_dir = tempfile.TemporaryDirectory()
tmp_dir.name
'/tmp/tmpdtgtmebx'
from pathlib import Path

f_path = Path(tmp_dir.name) / 'test.csv'
f_path
Path('/tmp/tmpdtgtmebx/test.csv')
import pandas as pd
from pandas import DataFrame

DataFrame({'a': [4], 'b': 5}).to_csv(f_path, index=False)
pd.read_csv(f_path)
a b
0 4 5

Create images

im = Image.new('RGB', (500, 300), (128, 128, 128))
draw = ImageDraw.Draw(im)

draw.ellipse((100, 100, 150, 200), fill=(255, 0, 0), outline=(0, 0, 0))
draw.rectangle((200, 100, 300, 200), fill=(4, 4, 200), outline=(255, 255, 255))
draw.line((350, 200, 450, 100), fill=(255, 255, 0), width=10)
im
../_images/13_datasets_legacy_11_0.png
def draw_grid(im=None, size=(100, 100), n_hlines=10, n_vlines=10, black=True):
    """
    size: (width, hight)
    black: bool
         draw grid and numbers in black or white
    """
    color = (0, 0, 0)
    if not black:
        color = (255, 255, 255)
    if im is None:
        im = Image.new('RGB', size, color=(211, 211, 211))
    width, hight = im.size
    draw = ImageDraw.Draw(im)
    ln_width = int((max(size) * 0.03) / max(n_hlines, n_vlines))

    for h in range(n_hlines):
        y = hight * h * (1 / n_hlines)
        draw.line((0, y, width, y), fill=color, width=ln_width)
        draw.text((width * 0.05, y), text=str((int(y))) + 'y',
                  fill=color)
        draw.text((width * 0.9, y), text=str((int(y))) + 'y', fill=color)

    for h in range(n_vlines):
        x = width * h * (1 / n_vlines)
        draw.line((x, 0, x, hight), fill=color, width=ln_width)
        draw.text((x, hight * 0.05), text=str((int(x))) + 'x', fill=color)
        draw.text((x, hight * 0.9), text=str((int(x))) + 'x', fill=color)
    return im


draw_grid(size=(200, 200), n_hlines=4, n_vlines=4)
../_images/13_datasets_legacy_12_0.png
img = Image.new('RGB', (300, 300), color='grey')
# draw_bbox((35, 50, 200, 250), im=img, black=False)
draw_bbox((200, 250, 35, 50), im=img, black=False, width=4)

draw_grid(img, n_hlines=5, n_vlines=5)
../_images/13_datasets_legacy_14_0.png
xyxy_to_xywh([50, 50, 150, 150])
[50, 50, 100, 100]
xywh_to_xyxy([50, 50, 100, 100])
[50, 50, 150, 150]

Overlap & Intersection over Union (IOU)

r1 = (10, 10, 110, 110)
r2 = (50, 50, 90, 90)
assert overlap(r1, r2) == 1
assert overlap(r2, r1) == 1
r1 = (0, 0, 100, 100)
r2 = (50, 50, 150, 150)
assert overlap(r1, r2) == 0.25
assert overlap(r2, r1) == 0.25
# export

def bb_intersection_over_union(boxA, boxB, verbose=False):

    interArea, boxAArea, boxBArea, _ = bbox_intersection(boxA, boxB)

    iou = interArea / float(boxAArea + boxBArea - interArea)
    if verbose:
        print(f"iou: {iou: .2f}, interArea: {interArea: .2f}"
              f", boxAArea {boxAArea: .2f}, box1Area {boxBArea: .2f}")
    return iou
r1 = (10, 10, 110, 110)
r2 = (80, 80, 180, 180)
img = Image.new('RGB', (300, 200), color='grey')
draw_bbox(r1, im=img, black=False, values=True)
draw_bbox(r2, im=img, black=False, values=True)


iou = bb_intersection_over_union(r1, r2, verbose=True)
# iou = bb_intersection_over_union(r1, r2, verbose=True)
_, _, _, union = bbox_intersection(r1, r2)
draw = ImageDraw.Draw(img)
draw.rectangle(union, fill='blue')
img
iou:  0.05, interArea:  900.00, boxAArea  10000.00, box1Area  10000.00
../_images/13_datasets_legacy_24_1.png
r1 = (10, 10, 110, 110)
r2 = (20, 20, 120, 120)
img = Image.new('RGB', (200, 150), color='grey')
draw_bbox(r1, im=img, black=False, values=True)
draw_bbox(r2, im=img, black=False, values=True)

iou = bb_intersection_over_union(r1, r2, verbose=True)
_, _, _, union = bbox_intersection(r1, r2)
draw = ImageDraw.Draw(img)
draw.rectangle(union, fill='blue')
img
iou:  0.68, interArea:  8100.00, boxAArea  10000.00, box1Area  10000.00
../_images/13_datasets_legacy_25_1.png
r1 = (10, 10, 110, 110)
img = Image.new('RGB', (200, 150), color='grey')
draw_bbox(r1, im=img, black=False, values=True)
draw_bbox(r1, im=img, black=False, values=True)

iou = bb_intersection_over_union(r1, r1, verbose=True)
_, _, _, union = bbox_intersection(r1, r2)
draw = ImageDraw.Draw(img)
draw.rectangle(union, fill='blue')
img
iou:  1.00, interArea:  10000.00, boxAArea  10000.00, box1Area  10000.00
../_images/13_datasets_legacy_26_1.png
r1 = (10, 10, 110, 110)
r2 = (20, 20, 90, 90)
img = Image.new('RGB', (200, 150), color='grey')
draw_bbox(r1, im=img, black=False, values=True)
draw_bbox(r2, im=img, black=False, values=True)

iou = bb_intersection_over_union(r1, r2, verbose=True)
_, _, _, union = bbox_intersection(r1, r2)
draw = ImageDraw.Draw(img)
draw.rectangle(union, fill='blue')
img
iou:  0.49, interArea:  4900.00, boxAArea  10000.00, box1Area  4900.00
../_images/13_datasets_legacy_27_1.png

Sample Random bbox

canvas_size = (300, 300)
img = Image.new('RGB', canvas_size, color='grey')

bboxs: List[Tuple[int, int, int, int]] = []
for i in range(10):
    bbox = sample_bbox(bboxs=bboxs, canvas_size=canvas_size, diag=(0.1, 0.3),
                       max_iou=0.3, max_overlap=0.5)
    bboxs.append(bbox)
    draw_bbox(bbox, im=img, black=False, values=False, width=3)
img
../_images/13_datasets_legacy_30_0.png

Draw Objects inside bbox

img = Image.new('RGB', (200, 100), color='grey')
bbox1 = (25, 25, 90, 75)
bbox2 = (125, 25, 190, 75)
draw_ellipse(img, bbox1, "blue")
draw_rectangle(img, bbox2, "red")
draw_bbox(bbox1, im=img, black=False, values=False)
draw_bbox(bbox2, im=img, black=False, values=False)
img
../_images/13_datasets_legacy_34_0.png

Create Object Detection Dataset

Generic Dataset

import tempfile
tmp_dir = tempfile.TemporaryDirectory()
path = Path(tmp_dir.name)
create_simple_object_detection_dataset(path=path, n_samples=5)
print(pd.read_json(path / 'annotations.json').T)

Image.open(list(path.glob('**/images/*'))[2])
                                                      labels  \
img_0.jpg           [[blue, rectangle], [yellow, rectangle]]   
img_1.jpg                                 [[red, rectangle]]   
img_2.jpg  [[blue, ellipse], [blue, rectangle], [blue, re...   
img_3.jpg                              [[yellow, rectangle]]   
img_4.jpg           [[yellow, rectangle], [blue, rectangle]]   

                                                       bboxs  
img_0.jpg               [[56, 51, 87, 90], [69, 5, 108, 34]]  
img_1.jpg                                 [[56, 8, 121, 57]]  
img_2.jpg  [[30, 19, 75, 44], [4, 62, 47, 133], [65, 87, ...  
img_3.jpg                                 [[49, 4, 138, 59]]  
img_4.jpg             [[61, 3, 134, 50], [75, 87, 108, 146]]  
../_images/13_datasets_legacy_38_1.png

Specific Tasks

#export
def create_color_classification(path, n_samples=10, n_colors=3, size=(150, 150)):
    create_simple_object_detection_dataset(path=path, n_objects=(1, 1), n_samples=n_samples,
                                           n_colors=n_colors, size=size)
    with open(path / 'annotations.json', 'r') as f:
        annotations = json.load(f)
    # simplify by dropping mutli-label and bbox
    annotations = {k: {'labels': v['labels'][0][0]} for k, v in annotations.items()}
    with open(path / 'annotations.json', 'w') as f:
        json.dump(annotations, f)
import tempfile
tmp_dir = tempfile.TemporaryDirectory()
path = Path(tmp_dir.name)
create_color_classification(path, size=(100, 100))
print(pd.read_json(path / 'annotations.json').T)
Image.open(list(path.glob('**/images/*'))[2])
           labels
img_0.jpg  yellow
img_1.jpg    blue
img_2.jpg  yellow
img_3.jpg     red
img_4.jpg  yellow
img_5.jpg    blue
img_6.jpg  yellow
img_7.jpg    blue
img_8.jpg     red
img_9.jpg    blue
../_images/13_datasets_legacy_41_1.png
#export
def create_shape_color_classification(path, n_samples=10, n_colors=3, size=(150, 150)):
    create_simple_object_detection_dataset(path=path, n_objects=(1, 1), n_samples=n_samples,
                                           n_colors=n_colors, size=size)
    with open(path / 'annotations.json', 'r') as f:
        annotations = json.load(f)
    # simplify by dropping mutli-label and bbox
    annotations = {k: {'labels': v['labels'][0]} for k, v in annotations.items()}
    with open(path / 'annotations.json', 'w') as f:
        json.dump(annotations, f)
import tempfile
tmp_dir = tempfile.TemporaryDirectory()
path = Path(tmp_dir.name)
create_shape_color_classification(path, size=(100, 100))
print(pd.read_json(path / 'annotations.json').T)
Image.open(list(path.glob('**/images/*'))[2])
                        labels
img_0.jpg    [blue, rectangle]
img_1.jpg  [yellow, rectangle]
img_2.jpg    [blue, rectangle]
img_3.jpg    [yellow, ellipse]
img_4.jpg      [blue, ellipse]
img_5.jpg  [yellow, rectangle]
img_6.jpg      [blue, ellipse]
img_7.jpg       [red, ellipse]
img_8.jpg  [yellow, rectangle]
img_9.jpg      [blue, ellipse]
../_images/13_datasets_legacy_43_1.png
#export
def create_object_detection(path, n_samples=10, n_objects=(1, 1), n_colors=3,
                            size=(150, 150), multilabel=False):
    create_simple_object_detection_dataset(path=path, n_objects=n_objects, n_samples=n_samples,
                                           n_colors=n_colors, size=size)
    with open(path / 'annotations.json', 'r') as f:
        annotations = json.load(f)

    # simplify by dropping mutli-label and bbox
    if max(n_objects) == 1:
        annotations = {k: {
            'labels': v['labels'][0], 'bbox': v['bboxs'][0]} for k, v in annotations.items()}
        if not multilabel:
            for k, v in annotations.items():
                v['labels'] = v['labels'][0]
    else:
        if not multilabel:
            for k, v in annotations.items():
                v['labels'] = v['labels'] = [label[0] for label in v['labels']]
    with open(path / 'annotations.json', 'w') as f:
        json.dump(annotations, f)
import tempfile
tmp_dir = tempfile.TemporaryDirectory()
path = Path(tmp_dir.name)
create_object_detection(path, size=(100, 100), n_objects=(1, 5), multilabel=True)
print(pd.read_json(path / 'annotations.json').T)
Image.open(list(path.glob('**/images/*'))[2])
                                                      labels  \
img_0.jpg           [[yellow, rectangle], [blue, rectangle]]   
img_1.jpg  [[red, ellipse], [blue, ellipse], [red, rectan...   
img_2.jpg                 [[red, ellipse], [red, rectangle]]   
img_3.jpg  [[blue, ellipse], [red, ellipse], [blue, recta...   
img_4.jpg  [[yellow, rectangle], [red, ellipse], [blue, r...   
img_5.jpg  [[blue, rectangle], [red, ellipse], [red, elli...   
img_6.jpg  [[yellow, rectangle], [red, rectangle], [yello...   
img_7.jpg              [[blue, rectangle], [red, rectangle]]   
img_8.jpg  [[red, rectangle], [red, rectangle], [yellow, ...   
img_9.jpg                                 [[red, rectangle]]   

                                                       bboxs  
img_0.jpg                [[9, 22, 44, 77], [58, 30, 93, 47]]  
img_1.jpg  [[22, 20, 39, 45], [43, 34, 78, 81], [2, 52, 2...  
img_2.jpg               [[77, 20, 98, 43], [53, 34, 76, 65]]  
img_3.jpg  [[11, 21, 46, 40], [52, 29, 85, 52], [4, 66, 1...  
img_4.jpg  [[3, 23, 34, 56], [35, 22, 72, 51], [68, 76, 9...  
img_5.jpg  [[68, 57, 93, 76], [23, 0, 82, 38], [22, 52, 5...  
img_6.jpg  [[3, 10, 46, 63], [63, 3, 82, 30], [49, 70, 88...  
img_7.jpg                [[18, 47, 47, 64], [21, 6, 62, 29]]  
img_8.jpg  [[1, 4, 34, 29], [43, 47, 70, 70], [38, 8, 63,...  
img_9.jpg                                 [[58, 14, 91, 37]]  
../_images/13_datasets_legacy_45_1.png