{"cells":[{"metadata":{"_uuid":"8b9aa863cd812b58d42e181ad815634b37e8f699"},"cell_type":"markdown","source":"# 1. Loading and visualizing the images\n### Airbus Ship Detection Challenge - A quick overview for computer vision noobs\n\n&nbsp;\n\n\nHi, and welcome! This is the first kernel of the series `Airbus Ship Detection Challenge - A quick overview for computer vision noobs.` \nIn this short kernel (~50 lines) we will find, load, resize and display the jpg satellital images using [PIL](https://pillow.readthedocs.io/en/latest/), we will map them to a rgb matrix representation using numpy [array](https://docs.scipy.org/doc/numpy/reference/generated/numpy.array.html) and we will display those rgb matrices on a nice grid using matplotlib's [imshow](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.imshow.html) and [subplots](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.subplots.html)).\n\n\n\nThe full series consist of the following notebooks:\n1. *[Loading and visualizing the images](https://www.kaggle.com/julian3833/1-loading-and-visualizing-the-images)*\n2. [Understanding and plotting rle bounding boxes](https://www.kaggle.com/julian3833/2-understanding-and-plotting-rle-bounding-boxes) \n3. [Basic exploratory analysis](https://www.kaggle.com/julian3833/3-basic-exploratory-analysis)\n4. [Exploring public models](https://www.kaggle.com/julian3833/4-exploring-models-shared-by-the-community)\n5. [1.0 submission: submitting the test file](https://www.kaggle.com/julian3833/5-1-0-submission-submitting-the-test-file)\n\nThis project aims to get some good understanding about the specific topic (image segmentation), including going over the dataset, learning common approaches and understanding the best models proposed by the community from a technical and theoretical point of view. The ideal reader is a data scientist noob with some general knowledge about deep learning.\n\nThis is an ongoing project, so expect more notebooks to be added to the series soon. Actually, we are currently working on the following ones:\n* Understanding and exploiting the data leak\n* A quick overview of image segmentation domain\n* Jumping into Pytorch\n* Understanding U-net\n* Proposing a simple improvement to U-net model"},{"metadata":{"_uuid":"5d29e4af8ad3eb1c536883b671c73da3c9814fd6"},"cell_type":"markdown","source":"<a id='one'></a>\n## 1. Finding the images"},{"metadata":{"_uuid":"3f106a1c783c5df12ba1f829a793ac01dfb79689"},"cell_type":"markdown","source":"Let's start with a quick glance of the `input` directory (remember to refer to the challenge's [Data tab](https://www.kaggle.com/c/airbus-ship-detection/data)  for more information about the dataset). \nThere are 3 csvs and 2 directories:"},{"metadata":{"trusted":true,"_uuid":"29f98df6777c653487e76f8dfb0035f90db2370f"},"cell_type":"code","source":"ls ../input/","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"f9ddf89ef4734194ffd4421a7c92a1c258b5e2e7"},"cell_type":"markdown","source":"The directories contain roughly 100,000 and 85,000 images each. In this kernel, we will focus only on them, leaving the analysis of the csvs content for [another](https://https://www.kaggle.com/julian3833/2-understanding-and-plotting-rle-bounding-boxes) kernel:"},{"metadata":{"trusted":true,"_uuid":"463117af2022cf452542f85b76d1cb772783c790"},"cell_type":"code","source":"import os\ntrain = os.listdir(\"../input/train\")\ntest = os.listdir(\"../input/test\")\nprint(f\"Train files: {len(train)}. ---> {train[:3]}\")\nprint(f\"Test files :  {len(test)}. ---> {test[:3]}\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"dd059b784f7ef28dfa386b07e1791fa226c899f7"},"cell_type":"markdown","source":"<a id='two'></a>\n## 2. Quick image display with [PIL](https://pillow.readthedocs.io/en/latest/)"},{"metadata":{"_uuid":"dfbfcd1dbd2b818f787631a1210ab6c1f479daa0"},"cell_type":"markdown","source":"The first thing we can do is to open and display some of the images from whitin Jupyter notebook itself. Using [PIL](https://pillow.readthedocs.io/en/latest/) is a good idea: it will allow us to load, resize and display a jpg image in one readable, pythonic line of code. \n\nLet's start opening an example jpg with [PIL.Image.open()](https://pillow.readthedocs.io/en/3.1.x/reference/Image.html#open-rotate-and-display-an-image-using-the-default-viewer) function. The image is automatically displayed by Jupyter:"},{"metadata":{"trusted":true,"_uuid":"5ed7ceefb61d5d7aae66a36bcc3a54586b9bf25a"},"cell_type":"code","source":"import PIL # We will import the packages at \"use-time (just for this kernel)\n\nPIL.Image.open(\"../input/train/000c34352.jpg\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b6db04bdd20e7465e4da86e80a17b0496c79b0f8"},"cell_type":"code","source":"PIL.Image.open(\"../input/train/000c34352.jpg\").size","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"5a5eaae63e9a9bfcc051d131ee1df4b959bec983"},"cell_type":"markdown","source":"<a id='three'></a>\n## 3. Resizing images"},{"metadata":{"_uuid":"b007ad777751d9e07e97d29c4cc3a957acbdd116"},"cell_type":"markdown","source":"In read-only mode it's not noticiable, but running the previous cell takes quite some time (>5 seconds): most of that time is spended by PIL and Jupyter trying to render a $(768 \\times 768)$ jpg.  Luckily,  we can overcome this by just resizing the image with the PIL Image's [resize()](https://pillow.readthedocs.io/en/3.1.x/reference/Image.html#PIL.Image.Image.resize) method. \n\nCheck the cell below: it's much faster, isn't it?"},{"metadata":{"trusted":true,"_uuid":"b44ecda0a4e4ed87854b5de607dca3d120397941"},"cell_type":"code","source":"PIL.Image.open('../input/train/000c34352.jpg').resize((200, 200))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"c128651a90478ff19b4fe1855241c2f1a536eb1f"},"cell_type":"markdown","source":"<a id='four'></a>\n## 4. JPG2<span style='color:red'>R</span><span style='color:green'>G</span><span style='color:blue'>B</span> with [np.array()](https://docs.scipy.org/doc/numpy/reference/generated/numpy.array.html)"},{"metadata":{"_uuid":"c7d5406fcfa65c3c61bce013aeaf11ea14a5ea3a"},"cell_type":"markdown","source":"Casting these PIL Image objects into a rgb matrix representation is as easy as resizing them. We just need to pass the Image to [np.array()](https://docs.scipy.org/doc/numpy/reference/generated/numpy.array.html) to obtain a (768, 768, 3) matrix. This matrix contains 3 integers for each of the 768$\\times$768 pixels, representing the red, green and blue saturation of each point in the picture:"},{"metadata":{"trusted":true,"_uuid":"86f1219f24b977d159ea61ba2b558a01066f7a50"},"cell_type":"code","source":"import numpy as np\n\n# Taking a shrinked version of the image to avoid unnecessary computation\nimg = PIL.Image.open('../input/train/000c34352.jpg').resize((200, 200))\n\nrgb_pixels = np.array(img)\nrgb_pixels.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7a07c212943a011002eb2a8c96214f71cbde258e"},"cell_type":"code","source":"# Red saturation of the top-left most 2x2 square pixels\nrgb_pixels[0:2, 0:2, 0]","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"2953325f53af863ca1330aa80bf259c0a4760f29"},"cell_type":"markdown","source":"<a id='five'></a>\n## 5. Visualizing rgb matrices with [plt.imshow()](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.imshow.html)"},{"metadata":{"_uuid":"5236f4bdb025608321f97e438e251332607df798"},"cell_type":"markdown","source":"We can easily plot this three-channel rgb representation with matplotlib's [imshow()](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.imshow.html):"},{"metadata":{"trusted":true,"_uuid":"7eef4fd1a7df4cdd8f8251666d0dc508a5667fa9"},"cell_type":"code","source":"import matplotlib.pyplot as plt\nplt.imshow(rgb_pixels);","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3719bcc79fad6ae5ca8a983001876b19cbc427b6"},"cell_type":"code","source":"# Note that imshow can plot a 1-channel image on monochrome\nplt.imshow(rgb_pixels[:, :, 1], cmap='Greys');","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ed42dbd29058270ad51d818574e6a55345467c57"},"cell_type":"code","source":"# And also:\nplt.imshow(np.random.random(size=(10, 10)));","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8d2a1d39446d475f0b47e12be3121f01d181dd5e"},"cell_type":"markdown","source":"<a id='six'></a>\n## 6. Displaying more than one image in the same cell with [plt.show()](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.show.html)"},{"metadata":{"_uuid":"b42b65384adbab5f1e92dc235015c38d054bfc73"},"cell_type":"markdown","source":"To display more than one image per cell  the easiest - but somehow insatisfactory - path we can take is to ask matplotlib kindly to flush the current figure calling [plt.show()](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.show.html) and start a new one:"},{"metadata":{"trusted":true,"_uuid":"40c916303706295401c5e8f317ec5a93ee64d18b"},"cell_type":"code","source":"plt.imshow(rgb_pixels)\nplt.title(\"Full image\"); # We can add a title with plt.title()\nplt.show()\n\nplt.imshow(rgb_pixels[0:200,0:100]) # And with can crop the image using standard python slicing\nplt.title(\"Left half\");\nplt.show()\n\nplt.imshow(rgb_pixels[0:200,100:200])\nplt.title(\"Right half\");\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"70c5e74707b9dc52a5b5382791878f2d85c6a6cc"},"cell_type":"markdown","source":"<a id='seven'></a>\n## 7. Displaying images compactly using [plt.subplots()](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.subplots.html)"},{"metadata":{"_uuid":"664164b8caf12940126915f3161b3310d12ca3b2"},"cell_type":"markdown","source":"As we mentioned, the previous display mechanism has a drawback: it doesn't exploit the screen width very well... unfortunately - and as far as we know - there is no easy solution for this with Jupyter, but using [subplots](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.subplots.html) is not that complicated:"},{"metadata":{"trusted":true,"_uuid":"abf48721762c37863f68a3c06a804f7b0a30bcaf"},"cell_type":"code","source":"# these two variables are \"the parameters\" of this cell\nw = 6\nh = 6\n\n# this function uses the open, resize and array functions we have seen before\nload_img = lambda filename: np.array(PIL.Image.open(f\"../input/train/{filename}\").resize((200, 200)))\n\n_, axes_list = plt.subplots(h, w, figsize=(2*w, 2*h)) # define a grid of (w, h)\n\nfor axes in axes_list:\n    for ax in axes:\n        ax.axis('off')\n        img = np.random.choice(train) # take a random train filename (like 000c34352.jpg)\n        ax.imshow(load_img(img)) # load and show\n        ax.set_title(img)\n        ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2483004a6a2aa30b8fffe09ebf1a5afd3cede4eb"},"cell_type":"markdown","source":"### References\n* [Airbus ship data vizualization](https://www.kaggle.com/meaninglesslives/airbus-ship-detection-data-visualization) - a nice data visualization and exploratory data analysis kernel. We didn't copy code from there, but it helped us to quick start the project.\n\n### What's next?\nYou can check the [next kernel](https://www.kaggle.com/julian3833/2-understanding-and-plotting-rle-bounding-boxes) of the series, where we understand the rle-encoding and plot the bounding boxes over the images."},{"metadata":{"trusted":true,"_uuid":"1d5f833a26f81e2bf1fcb785dd501e8fb6c1e4e7"},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}