{"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":"code","source":"!mkdir conda-pkgs\n # Set the location where conda package will be downloaded\n!conda config --add pkgs_dirs ./conda-pkgs\n # Download pyvips and dependencies\n!conda install --download-only -y \"pyvips>=2.2.0\"\n!rm -rf ./conda-pkgs/cache\n!conda install ./conda-pkgs/*.tar.bz2 --offline","metadata":{"execution":{"iopub.status.busy":"2022-08-12T19:25:08.092392Z","iopub.execute_input":"2022-08-12T19:25:08.092849Z","iopub.status.idle":"2022-08-12T19:27:54.122897Z","shell.execute_reply.started":"2022-08-12T19:25:08.092811Z","shell.execute_reply":"2022-08-12T19:27:54.120246Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install git+https://github.com/yu4u/seam-carving.git","metadata":{"execution":{"iopub.status.busy":"2022-08-12T19:27:54.129136Z","iopub.execute_input":"2022-08-12T19:27:54.129687Z","iopub.status.idle":"2022-08-12T19:28:09.65844Z","shell.execute_reply.started":"2022-08-12T19:27:54.129643Z","shell.execute_reply":"2022-08-12T19:28:09.65686Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport gc\nimport cv2\nimport pyvips\nimport seam_carving\nseam_carving.carve.MAX_MEAN_ENERGY = 10.0\n\nfrom numba import njit\nimport numpy as np\nimport pandas as pd\nfrom tqdm import tqdm\nimport seaborn as sns\nimport matplotlib.pyplot as plt\n\nimport skimage\nfrom skimage.filters import sobel\nfrom skimage import segmentation\nfrom skimage.color import label2rgb\nfrom skimage.color import rgb2hed, hed2rgb\nfrom skimage.exposure import rescale_intensity\nimport tifffile as tifi\n\nfrom PIL import Image, ImageOps, ImageFilter\nImage.MAX_IMAGE_PIXELS = None","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-08-12T19:28:09.660333Z","iopub.execute_input":"2022-08-12T19:28:09.660726Z","iopub.status.idle":"2022-08-12T19:28:12.296043Z","shell.execute_reply.started":"2022-08-12T19:28:09.660691Z","shell.execute_reply":"2022-08-12T19:28:12.294737Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path = '../input/mayo-clinic-strip-ai/'","metadata":{"execution":{"iopub.status.busy":"2022-08-12T19:28:12.299071Z","iopub.execute_input":"2022-08-12T19:28:12.299487Z","iopub.status.idle":"2022-08-12T19:28:12.304809Z","shell.execute_reply.started":"2022-08-12T19:28:12.299435Z","shell.execute_reply":"2022-08-12T19:28:12.303661Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = pd.read_csv('{}/train.csv'.format(path))\ndf['path'] = path + 'train/' + df['image_id'] + '.tif'\ndf['target'] = df['label'].map({'CE': 0, 'LAA': 1})","metadata":{"execution":{"iopub.status.busy":"2022-08-12T19:28:12.306238Z","iopub.execute_input":"2022-08-12T19:28:12.307114Z","iopub.status.idle":"2022-08-12T19:28:12.360063Z","shell.execute_reply.started":"2022-08-12T19:28:12.307079Z","shell.execute_reply":"2022-08-12T19:28:12.3591Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df['shape'] = df['path'].map(lambda x: Image.open(x).size)\ndf[['width', 'height']] = pd.DataFrame(df['shape'].tolist(), columns=['width', 'height'])\ndf['area'] = df['width'] * df['height']","metadata":{"execution":{"iopub.status.busy":"2022-08-12T19:28:12.361551Z","iopub.execute_input":"2022-08-12T19:28:12.362169Z","iopub.status.idle":"2022-08-12T19:28:31.587177Z","shell.execute_reply.started":"2022-08-12T19:28:12.362133Z","shell.execute_reply":"2022-08-12T19:28:31.586051Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.head()","metadata":{"execution":{"iopub.status.busy":"2022-08-12T19:28:31.588799Z","iopub.execute_input":"2022-08-12T19:28:31.589203Z","iopub.status.idle":"2022-08-12T19:28:31.616289Z","shell.execute_reply.started":"2022-08-12T19:28:31.589108Z","shell.execute_reply":"2022-08-12T19:28:31.615231Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df['area'].describe()","metadata":{"execution":{"iopub.status.busy":"2022-08-12T19:28:31.617948Z","iopub.execute_input":"2022-08-12T19:28:31.619138Z","iopub.status.idle":"2022-08-12T19:28:31.634114Z","shell.execute_reply.started":"2022-08-12T19:28:31.619092Z","shell.execute_reply":"2022-08-12T19:28:31.632842Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df['area'].plot(kind='hist', grid=True)","metadata":{"execution":{"iopub.status.busy":"2022-08-12T19:28:31.636049Z","iopub.execute_input":"2022-08-12T19:28:31.636836Z","iopub.status.idle":"2022-08-12T19:28:31.893774Z","shell.execute_reply.started":"2022-08-12T19:28:31.636793Z","shell.execute_reply":"2022-08-12T19:28:31.892541Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sns.scatterplot(x='width', y='height', hue='label', data=df)","metadata":{"execution":{"iopub.status.busy":"2022-08-12T19:28:31.897592Z","iopub.execute_input":"2022-08-12T19:28:31.898749Z","iopub.status.idle":"2022-08-12T19:28:32.162955Z","shell.execute_reply.started":"2022-08-12T19:28:31.898706Z","shell.execute_reply":"2022-08-12T19:28:32.161524Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#img_path = df[df['width'].gt(df['height'])].iloc[9]['path']\n#img_path = df[df['width'].gt(df['height'])].sample(1).iloc[0]['path']\nimg_path = df[df['image_id'].eq('3982bf_0')].iloc[0]['path']\nimg = pyvips.Image.thumbnail(img_path, 4096).numpy()\nplt.imshow(img)","metadata":{"execution":{"iopub.status.busy":"2022-08-12T19:34:50.967831Z","iopub.execute_input":"2022-08-12T19:34:50.968618Z","iopub.status.idle":"2022-08-12T19:37:46.359146Z","shell.execute_reply.started":"2022-08-12T19:34:50.968567Z","shell.execute_reply":"2022-08-12T19:37:46.357883Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"carve_img = seam_carving.resize(img, (100, 100))","metadata":{"execution":{"iopub.status.busy":"2022-08-12T19:37:46.361472Z","iopub.execute_input":"2022-08-12T19:37:46.36251Z","iopub.status.idle":"2022-08-12T19:46:53.034689Z","shell.execute_reply.started":"2022-08-12T19:37:46.36247Z","shell.execute_reply":"2022-08-12T19:46:53.033518Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots(1, 2)\nax[0].imshow(img)\nax[1].imshow(carve_img)","metadata":{"execution":{"iopub.status.busy":"2022-08-12T19:46:53.036696Z","iopub.execute_input":"2022-08-12T19:46:53.037057Z","iopub.status.idle":"2022-08-12T19:46:54.094298Z","shell.execute_reply.started":"2022-08-12T19:46:53.037024Z","shell.execute_reply":"2022-08-12T19:46:54.093062Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def tile(img, sz=1024):\n    # 41b4ea_1 > img_mean\n    shape = img.shape\n    img_mean = img.mean()\n    pad0,pad1 = (sz - shape[0]%sz)%sz, (sz - shape[1]%sz)%sz\n    img = np.pad(img,[[pad0//2,pad0-pad0//2],[pad1//2,pad1-pad1//2],[0,0]],constant_values=255)\n    img = img.reshape(img.shape[0]//sz,sz,img.shape[1]//sz,sz,3)\n    img = img.transpose(0,2,1,3,4).reshape(-1,sz,sz,3)\n    idxs = [i.mean() < img_mean for i in img]\n    img = img[idxs]\n    return img","metadata":{"execution":{"iopub.status.busy":"2022-08-08T20:43:03.885184Z","iopub.execute_input":"2022-08-08T20:43:03.885716Z","iopub.status.idle":"2022-08-08T20:43:03.894997Z","shell.execute_reply.started":"2022-08-08T20:43:03.885681Z","shell.execute_reply":"2022-08-08T20:43:03.893754Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_tile():\n    nimg = tile(img, sz=2048)\n    row = min(int(nimg.shape[0]**0.5)+1, 12)\n    col = row\n\n    fig, axes = plt.subplots(row, col, figsize=(18, 12))\n    for idx, ax in enumerate(axes.flatten()):\n        try:\n            ax.imshow(nimg[idx])\n            ax.set_title('Good')\n            ax.set(xticklabels=[], yticklabels=[], xticks=[], yticks=[])\n        except:\n            ax.imshow(np.ones((1024, 1024, 3)))\n    plt.tight_layout()","metadata":{"execution":{"iopub.status.busy":"2022-08-12T19:51:15.705129Z","iopub.execute_input":"2022-08-12T19:51:15.706288Z","iopub.status.idle":"2022-08-12T19:51:15.714656Z","shell.execute_reply.started":"2022-08-12T19:51:15.706237Z","shell.execute_reply":"2022-08-12T19:51:15.713314Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# look into numba\ndef prune_image_rows_cols(im, mask, thr=0.990):\n    # delete empty columns\n    for l in range(im.shape[1]):\n        if (np.sum(mask[:, l]) / float(mask.shape[0])) > thr:\n            im = np.delete(im, l, 1)\n    # delete empty rows\n    for l in reversed(range(im.shape[0])):\n        if (np.sum(mask[l, :]) / float(mask.shape[1])) > thr:\n            im = np.delete(im, l, 0)\n    return im\n\ndef mask_median(im, val=255):\n    masks = [None] * 3\n    for c in range(3):\n        masks[c] = im[..., c] >= np.median(im[:, :, c]) - 5\n    mask = np.logical_and(*masks)\n    im[mask, :] = val\n    return im, mask\n\n#fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(14, 10))\n#img_path = df.iloc[df[\"area\"].idxmax(),:]['path']\n#img_path = df.sample(1)['path'].iloc[0]\n#img_path = df[df['image_id'].eq(filename)]['path'].iloc[0]\n#img = pyvips.Image.thumbnail(img_path, 20000).numpy()\n#if img.shape[0] > img.shape[1]:\n    #img = np.rollaxis(img, 0, 2)\n#axes[0].imshow(img)\n\n#img, mask = mask_median(np.array(img))\n#img = prune_image_rows_cols(img, mask)\n#axes[1].imshow(img)","metadata":{"execution":{"iopub.status.busy":"2022-08-05T01:07:34.529825Z","iopub.execute_input":"2022-08-05T01:07:34.530388Z","iopub.status.idle":"2022-08-05T01:07:34.541793Z","shell.execute_reply.started":"2022-08-05T01:07:34.530348Z","shell.execute_reply":"2022-08-05T01:07:34.540745Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!mkdir /kaggle/working/carved_img/","metadata":{"execution":{"iopub.status.busy":"2022-08-05T00:57:01.124984Z","iopub.execute_input":"2022-08-05T00:57:01.125449Z","iopub.status.idle":"2022-08-05T00:57:02.407105Z","shell.execute_reply.started":"2022-08-05T00:57:01.125412Z","shell.execute_reply":"2022-08-05T00:57:02.405471Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def clip_and_save(x):\n    image_id, img_path = x['image_id'], x['path']\n    img = pyvips.Image.thumbnail(img_path, 20000).numpy()\n    if img.shape[0] > img.shape[1]:\n        img = np.rollaxis(img, 0, 2)\n\n    img, mask = mask_median(np.array(img))\n    img = prune_image_rows_cols(img, mask)\n    img = Image.fromarray(img)\n    print('Completed: {}'.format(img_path))\n    img.save('/kaggle/working/train_patches/{}.png'.format(image_id))","metadata":{"execution":{"iopub.status.busy":"2022-07-29T22:40:14.267903Z","iopub.execute_input":"2022-07-29T22:40:14.268395Z","iopub.status.idle":"2022-07-29T22:40:14.27765Z","shell.execute_reply.started":"2022-07-29T22:40:14.268353Z","shell.execute_reply":"2022-07-29T22:40:14.27636Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def tile_and_save(x):\n    image_id, img_path = x['image_id'], x['path']\n    img = pyvips.Image.thumbnail(img_path, 20000).numpy()\n    images = tile(img, sz=2048)\n    for idx, img in enumerate(images):\n        img = Image.fromarray(img)\n        img.save('/kaggle/working/train_patches/{}_{}.jpeg'.format(image_id, idx))\n\n    print('Completed: {}'.format(img_path))\n    del img, images; gc.collect()","metadata":{"execution":{"iopub.status.busy":"2022-08-05T01:10:19.454008Z","iopub.execute_input":"2022-08-05T01:10:19.454593Z","iopub.status.idle":"2022-08-05T01:10:19.464247Z","shell.execute_reply.started":"2022-08-05T01:10:19.454546Z","shell.execute_reply":"2022-08-05T01:10:19.463057Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def carve_img(x):\n    image_id, img_path = x['image_id'], x['path']\n    img = pyvips.Image.thumbnail(img_path, 1024).numpy()\n    img = seam_carving.resize(img, (100, 100))\n    img = Image.fromarray(img)\n    print('Completed: {}'.format(img_path))\n    img.save('/kaggle/working/carved_img/{}.png'.format(image_id))","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.apply(carve_img, axis=1)","metadata":{"execution":{"iopub.status.busy":"2022-08-05T01:09:01.374641Z","iopub.execute_input":"2022-08-05T01:09:01.375188Z","iopub.status.idle":"2022-08-05T01:09:48.665662Z","shell.execute_reply.started":"2022-08-05T01:09:01.375139Z","shell.execute_reply":"2022-08-05T01:09:48.6643Z"},"trusted":true},"execution_count":null,"outputs":[]}]}