{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## Introduction\nIn this competition, due to the extremely large image size, \nan efficient way of removing background (=making tiles) is very important.\n\nThis implementation is base on [GM Iafoss](https://www.kaggle.com/iafoss)'s [notebook](https://www.kaggle.com/code/iafoss/panda-16x128x128-tiles) from PANDA competition.","metadata":{}},{"cell_type":"code","source":"from pathlib import Path\nimport numpy as np\nimport skimage.io as io\nimport cv2\nimport matplotlib.pyplot as plt\nfrom tqdm.notebook import tqdm","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-07-17T01:02:08.785386Z","iopub.execute_input":"2022-07-17T01:02:08.786516Z","iopub.status.idle":"2022-07-17T01:02:08.888654Z","shell.execute_reply.started":"2022-07-17T01:02:08.78647Z","shell.execute_reply":"2022-07-17T01:02:08.887652Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_paths = list(Path('../input/mayo-clinic-strip-ai/test/').glob('*.tif'))\nimage_paths","metadata":{"execution":{"iopub.status.busy":"2022-07-17T00:57:27.626112Z","iopub.execute_input":"2022-07-17T00:57:27.62655Z","iopub.status.idle":"2022-07-17T00:57:27.635062Z","shell.execute_reply.started":"2022-07-17T00:57:27.626516Z","shell.execute_reply":"2022-07-17T00:57:27.633633Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_image(img_path, resize_factor=16):\n    img = io.imread(img_path)\n    img = cv2.resize(img, dsize=None, fx=1/resize_factor, fy=1/resize_factor)\n    return img","metadata":{"execution":{"iopub.status.busy":"2022-07-17T00:57:29.104726Z","iopub.execute_input":"2022-07-17T00:57:29.105568Z","iopub.status.idle":"2022-07-17T00:57:29.112468Z","shell.execute_reply.started":"2022-07-17T00:57:29.105517Z","shell.execute_reply":"2022-07-17T00:57:29.11137Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def make_tiles(img, tile_size=256, num_tiles=4):\n    '''\n    img: np.ndarray with dtype np.uint8 and shape (width, height, channel)\n    '''\n    w, h, ch = img.shape\n    pad0, pad1 = (tile_size - w%tile_size) % tile_size, (tile_size - h%tile_size) % tile_size\n    padding = [[pad0//2, pad0-pad0//2], [pad1//2, pad1-pad1//2], [0, 0]]\n    img = np.pad(img, padding, mode='constant', constant_values=255)\n    img = img.reshape(img.shape[0]//tile_size, tile_size, img.shape[1]//tile_size, tile_size, ch)\n    img = img.transpose(0, 2, 1, 3, 4).reshape(-1, tile_size, tile_size, ch)\n    if len(img) < num_tiles: # pad images so that the output shape be the same\n        padding = [[0, num_tiles-len(img)], [0, 0], [0, 0], [0, 0]]\n        img = np.pad(img, padding, mode='constant', constant_values=255)\n    idxs = np.argsort(img.reshape(img.shape[0], -1).sum(-1))[:num_tiles] # pick up Top N dark tiles\n    img = img[idxs]\n    return img","metadata":{"execution":{"iopub.status.busy":"2022-07-17T00:59:55.409735Z","iopub.execute_input":"2022-07-17T00:59:55.410845Z","iopub.status.idle":"2022-07-17T00:59:55.419706Z","shell.execute_reply.started":"2022-07-17T00:59:55.410804Z","shell.execute_reply":"2022-07-17T00:59:55.418482Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image = load_image(image_paths[0])\nplt.imshow(image)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-17T00:59:17.687503Z","iopub.execute_input":"2022-07-17T00:59:17.687855Z","iopub.status.idle":"2022-07-17T00:59:45.536002Z","shell.execute_reply.started":"2022-07-17T00:59:17.687827Z","shell.execute_reply":"2022-07-17T00:59:45.534651Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tiles = make_tiles(image)\ntiles.shape","metadata":{"execution":{"iopub.status.busy":"2022-07-17T01:00:20.190437Z","iopub.execute_input":"2022-07-17T01:00:20.191446Z","iopub.status.idle":"2022-07-17T01:00:20.247198Z","shell.execute_reply.started":"2022-07-17T01:00:20.19138Z","shell.execute_reply":"2022-07-17T01:00:20.246434Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for tile in tiles:\n    plt.imshow(tile)\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-17T01:00:42.901012Z","iopub.execute_input":"2022-07-17T01:00:42.901489Z","iopub.status.idle":"2022-07-17T01:00:43.665233Z","shell.execute_reply.started":"2022-07-17T01:00:42.90145Z","shell.execute_reply":"2022-07-17T01:00:43.664352Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Benchmark\n**It takes only around 20s to process 500 images!**","metadata":{}},{"cell_type":"code","source":"%%time\nfor _ in tqdm(range(500)):\n    _ = make_tiles(image)","metadata":{"execution":{"iopub.status.busy":"2022-07-17T01:02:52.540684Z","iopub.execute_input":"2022-07-17T01:02:52.541617Z","iopub.status.idle":"2022-07-17T01:03:13.990191Z","shell.execute_reply.started":"2022-07-17T01:02:52.541576Z","shell.execute_reply":"2022-07-17T01:03:13.988908Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}