{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"%reload_ext autoreload\n%autoreload 2\n%matplotlib inline\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport pydicom\nimport os\nimport albumentations as A\nimport torch\ntrain = pd.read_csv('../input/osic-pulmonary-fibrosis-progression/train.csv')\ngpu = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\ngpu","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# OSIC: augmentations tutorial w/ albumentations \n\nIn any good deep learning model pipeline, it is **always** essential to be able to augment data, as it gives you the advantage of your model generalizing well. As such, here is a tutorial on data augmentations (especially those for images) with the library albumentations developed by notable Kagglers such as Dr. Vladimir Iglovikov and Eugene Khvedchenya.\n\nAlbumentations themselves quote:\n> Image augmentation is a process of creating new training examples from the existing ones. To make a new sample, you slightly change the original image. For instance, you could make a new image a little brighter; you could cut a piece from the original image; you could make a new image by mirroring the original one, etc.\n\n\n\n<hr>\n\n### TOC:\n\n+ <a href=\"#blur\">Blur-based Augmentations </a><br>\n+ <a href=\"#dropout\">Dropout Augmentations </a><br>\n+ <a href=\"#cbt\">Crop-based Augmentations </a><br>\n+ <a href=\"#rt\">Rotation-based Augmentations</a><br>\n+ <a href=\"#snbt\">Scaling and normalization-based transforms</a>\n+ <a href=\"#ns\">Noise-based transforms</a>","execution_count":null},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"def show_images(images, read_region=(1780,1950)):\n    f, ax = plt.subplots(3,3, figsize=(16,18))\n    \n    for i, image in enumerate(images):\n        image_path = os.path.join('../input/osic-pulmonary-fibrosis-progression',\"train/ID00007637202177411956430\",image+'.dcm')\n        image = pydicom.dcmread(image_path)\n        ax[i//3, i%3].imshow(image.pixel_array) \n        ax[i//3, i%3].axis('off')\n\n    plt.show()\nimages = [\n    '1', '2', '3',\n    '4', '5', '6',\n    '7', '8', '9']   \nshow_images(images)\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"These are a few of our sample images present in the dataset. Let us now commence our albumentations tutorial, with simple blur-based augmentations.","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"<h1 id=\"blur\">Blur-based augs</h1>","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"This is a simple set of:\n+ Blur\n+ GaussianBlur\n+ MedianBlur\n+ MotionBlur","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"import cv2\ndef show_images(images, aug_dict, read_region=(1780,1950)):\n    f, axes = plt.subplots(len(augs),6, figsize=(20, 2 * len(augs)), squeeze=False);\n    \n    for i, im in enumerate(images):\n        \n        for i, (key, aug) in enumerate(aug_dict.items()):\n            for j in range(6):\n                ax = axes[i, j]\n                if j == 0:\n                    ax.text(0.5, 0.5, key, horizontalalignment='center', verticalalignment='center', fontsize=15)\n                    ax.get_xaxis().set_visible(False);\n                    ax.get_yaxis().set_visible(False);\n                    ax.axis('off')\n                else:\n                    image_path = '../input/osic-pulmonary-fibrosis-progression/' + \"train/ID00007637202177411956430/\" + str(j) +'.dcm'\n                    image = pydicom.dcmread(image_path).pixel_array\n                    if aug is not None:\n                        image = aug(image=image)['image']\n                    ax.imshow(image, cmap='bone');\n        plt.tight_layout()\n        plt.show();\n        plt.close()\n\n    plt.show();\nimages = [\n    '1', '19', '13',\n    '11', '5']   \naugs = {'Original': None,\n             'Blur': A.Blur(p=1.0),\n             'MedianBlur': A.MedianBlur(blur_limit=5, p=1.0),\n             'GaussianBlur': A.GaussianBlur(p=1.0),\n             'MotionBlur': A.MotionBlur(p=1.0)\n       }\nshow_images(images, augs)\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h1 id=\"dropout\">Dropout augmentations</h1>","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"Dropout augmentations we're going to be applying here (with their description from the [albumentations docs](https://albumentations.readthedocs.io/en/latest/api/augmentations.html)) are:\n\n+ GridDropout\n> GridDropout, drops out rectangular regions of an image and the corresponding mask in a grid fashion.\n+ ChannelDropout\n> Randomly Drop Channels in the input Image.\n","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"augs = {'Original': None,\n             'GridDropout': A.GridDropout(p=1.0),\n        #     'ChannelDropout': A.ChannelDropout(p=1.0)\n       }\nshow_images(images, augs)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h1 id=\"cbt\">Crop-based augmentations</h1>\n\nThis kind of augmentations are primarily oriented towards croppnig an image in its many forms and sizes.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"augs = {'Original': None,\n             'RandomCrop': A.RandomCrop(height=64, width=64, p=1.0),\n         'CenterCrop': A.CenterCrop(height=64, width=64, p=1.0),\n        'RandomSizedCrop': A.RandomSizedCrop((90, 100), 64, 64)\n       }\nshow_images(images, augs)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h1 id=\"rt\">Rotation-based transforms</h1>\n\nThese are primarily oriented towards rotation of the image.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"augs = {'Original': None,\n             'RandomRotate90': A.RandomRotate90(p=1.0),\n         'ShiftScaleRotate': A.ShiftScaleRotate(p=1.0),\n        'Rotate': A.Rotate()\n       }\nshow_images(images, augs)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h1 id=\"snbt\">Scaling and normalization-based transforms</h1>","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"These principally revolve around transforms which scale the image, normalize it, invert pixel values etc.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def show_imagesunit8(images, aug_dict, read_region=(1780,1950)):\n    f, axes = plt.subplots(len(augs),6, figsize=(20, 2 * len(augs)), squeeze=False);\n    \n    for i, im in enumerate(images):\n        \n        for i, (key, aug) in enumerate(aug_dict.items()):\n            for j in range(6):\n                ax = axes[i, j]\n                if j == 0:\n                    ax.text(0.5, 0.5, key, horizontalalignment='center', verticalalignment='center', fontsize=15)\n                    ax.get_xaxis().set_visible(False);\n                    ax.get_yaxis().set_visible(False);\n                    ax.axis('off')\n                else:\n                    image_path = '../input/osic-pulmonary-fibrosis-progression/' + \"train/ID00007637202177411956430/\" + str(j) +'.dcm'\n                    image = pydicom.dcmread(image_path).pixel_array.astype(\"uint8\")\n                    if aug is not None:\n                        image = aug(image=image)['image']\n                    ax.imshow(image, cmap='bone');\n        plt.tight_layout()\n        plt.show();\n        plt.close()\n\naugs = {'Original': None,\n             'Solarize': A.Solarize(p=1.0),\n         'Posterize': A.Posterize(p=1.0),\n        'Equalize': A.Equalize(),\n        'Downscale': A.Downscale()\n       }\nshow_imagesunit8(images, augs)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h1 id=\"ns\">Noise based transforms</h1>\n\nThese primarily are meant to add some sort of artificial noise to our image.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"augs = {'Original': None,\n             'GaussNoise': A.GaussNoise(p=1.0)\n       }\nshow_imagesunit8(images, augs)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"# Further Resources","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"This is the end of my not-so-pedagogical notebook which takes a surface level scan of these augmentations to introduce them to people who aren't familiar.\n\nThere are some other resources for learning about this are:\n+ https://albumentations.readthedocs.io/en/latest/api/augmentations.html <br>\n**These are the official docs for albumentations, please read.** <br>\n+ https://github.com/albumentations-team/albumentations <br>\n**This is the GitHub for albumentations.** <br>\n+ https://www.kaggle.com/shonenkov/nlp-albumentations <br>\n**Perhaps the most creative use of any sort of albumentations I have ever seen.** <br>\n+ https://albumentations.ai/ <br>\n**The official albumentations website.** <br>\n","execution_count":null}],"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":4,"nbformat_minor":4}