Helper methods
logger = logging.getLogger()

class TimerMutable[source]

TimerMutable(elapsed:Optional[timedelta]=None)

TimerMutable(elapsed:Union[datetime.timedelta, NoneType]=None)

measure_time[source]

measure_time()

with measure_time() as timer:
    time.sleep(0.2)
print(f"Elapsed {timer.elapsed}")
Elapsed 0:00:00.200235

log_elapsed_time[source]

log_elapsed_time(log_method)

@log_elapsed_time(lambda t: print(f'Elapsed: {t.elapsed}'))
def f():
    time.sleep(0.1)
f()
Elapsed: 0:00:00.100154

sort_dict[source]

sort_dict(D:Dict, sort_key='id')

s = sort_dict(
    {
        'images': [{'id': 3}, {'id': 1}, {'id': 2}],
        'annotations': [{'id': 11}, {'id': 12}, {'id': 13}],
        'categories': [{'id': 101}, {'id': 103}, {'id': 102}],
        'licenses': [{'id': 1002}, {'id': 1001}],
        'info': {'key': 'value'},
    }
)
display(s)
j = json.dumps(s)
assert j == (
    '{"annotations": [{"id": 11}, {"id": 12}, {"id": 13}], '
    '"categories": [{"id": 101}, {"id": 102}, {"id": 103}], '
    '"images": [{"id": 1}, {"id": 2}, {"id": 3}], '
    '"info": {"key": "value"}, '
    '"licenses": [{"id": 1001}, {"id": 1002}]}'
), j
OrderedDict([('annotations', [{'id': 11}, {'id': 12}, {'id': 13}]),
             ('categories', [{'id': 101}, {'id': 102}, {'id': 103}]),
             ('images', [{'id': 1}, {'id': 2}, {'id': 3}]),
             ('info', {'key': 'value'}),
             ('licenses', [{'id': 1001}, {'id': 1002}])])

sanitize_filename[source]

sanitize_filename(s:str, max_len=256)

sanitize_filename('a b «ccc ddd» Ef жиза, 3*50 г НОВИНКА!!!')
'a_b_ccc_ddd_Ef_жиза_350_г_НОВИНКА'

read_image[source]

read_image(image_path:Union[str, Path], download_url:Optional[str]=None)

Reads image :image_path: in RGB mode. If image file does not exist and :download_url: was specified, downloads the image first.

download_image[source]

download_image(image_path:Union[str, Path], download_url:str)

cut_bbox[source]

cut_bbox(image, bbox)

write_image[source]

write_image(image, image_path)

anns = !ls ../examples/coco_chunk/json_tree/annotations
for x in anns:
    print(repr(x))
"ls: cannot access '../examples/coco_chunk/json.tree/annotations': No such file or directory"
# import tempfile
# null = None

# BASE = Path('/home/ay/Downloads/outforz-lactalis/output/clean/2020-10-01_2020-11-01')
# ann = {"id": 2131512, "image_id": 102237, "category_id": "4 823 065 722 757", "bbox": [0.2347949080622348, 0.5921750663129973, 0.09335219236209336, 0.03183023872679047], "supercategory": null, "area": null, "iscrowd": null}
# img = json.loads((BASE/'json_tree/images/102237.json').read_text())
# print(img)
# tmp = Path(tempfile.mktemp())
# print(tmp)
# image = read_image(tmp, img['coco_url'])
# image_box = cut_bbox(image, ann['bbox'])
# draw_image(image_box, figsize=(8, 8))
import json
from pathlib import Path
import tempfile

JSON_TREE_PATH = '../examples/coco_chunk/json_tree/'
CROP_TREE_PATH = tempfile.mktemp()

ann_files = !ls {JSON_TREE_PATH}/annotations

for ann_file in ann_files:
    ANN = f'{JSON_TREE_PATH}/annotations/{ann_file}'
    #! cat {ANN}
    ann = json.loads(Path(ANN).read_text())
    box = ann['bbox']

    IMG = f'{JSON_TREE_PATH}/images/{ann["image_id"]}.json'
    #! cat {IMG}
    img = json.loads(Path(IMG).read_text())

    CAT = f'{JSON_TREE_PATH}/categories/{ann["category_id"]}.json'
    ! cat {CAT}
    cat = json.loads(Path(CAT).read_text())

    IMG_PATH = f'{CROP_TREE_PATH}/images/{img["file_name"]}'
    IMG_URL = img["coco_url"]

    image = read_image(IMG_PATH, IMG_URL)
    display(f'image: shape={image.shape} size={image.size}')

    image_box = cut_bbox(image, box)
    display(f'box: shape={image_box.shape} size={image_box.size}')

    draw_image(image_box, figsize=(8, 8))

    cat_dir_name = f'{sanitize_filename(cat["name"])}--{cat["id"]}'
    CROP_PATH = f'{CROP_TREE_PATH}/crops/{cat_dir_name}/{ann["id"]}.png'

    write_image(image_box, CROP_PATH)
    display(f'saved to {CROP_PATH}')
{
    "id": 2,
    "name": "bicycle",
    "supercategory": "vehicle"
}
'image: shape=(480, 640, 3) size=921600'
'box: shape=(113, 143, 3) size=48477'
'saved to /tmp/tmpgypin4da/crops/bicycle--2/124710.png'
{
    "id": 2,
    "name": "bicycle",
    "supercategory": "vehicle"
}
'image: shape=(427, 640, 3) size=819840'
'box: shape=(247, 264, 3) size=195624'
'saved to /tmp/tmpgypin4da/crops/bicycle--2/124713.png'
{
    "id": 3,
    "name": "car",
    "supercategory": "vehicle"
}
'image: shape=(427, 640, 3) size=819840'
'box: shape=(28, 50, 3) size=4200'
'saved to /tmp/tmpgypin4da/crops/car--3/131774.png'
{
    "id": 3,
    "name": "car",
    "supercategory": "vehicle"
}
'image: shape=(326, 500, 3) size=489000'
'box: shape=(89, 224, 3) size=59808'
'saved to /tmp/tmpgypin4da/crops/car--3/131812.png'
{
    "id": 1,
    "name": "person",
    "supercategory": "person"
}
'image: shape=(480, 640, 3) size=921600'
'box: shape=(320, 229, 3) size=219840'
'saved to /tmp/tmpgypin4da/crops/person--1/183020.png'
{
    "id": 1,
    "name": "person",
    "supercategory": "person"
}
'image: shape=(427, 640, 3) size=819840'
'box: shape=(408, 433, 3) size=529992'
'saved to /tmp/tmpgypin4da/crops/person--1/183030.png'