{"cells":[{"metadata":{"_uuid":"2b5f5e60f265a24e24f7ebba9f7390d127e00dcb"},"cell_type":"markdown","source":"![min](http://www.muslimheritage.com/sites/default/files/east_meets_west_venice_02_1.jpg?slideshow=true&slideshowAuto=false&slideshowSpeed=4000&speed=350&transition=elastic)"},{"metadata":{"_uuid":"d8d39c15f4c741ffe8d88092f6a3f13fa4a0f685"},"cell_type":"markdown","source":"Object detection is very popular field of interest and new and new algorithms for improving it are realised by the day. In Airbus Ship Detection Challege the accent is on speed (of course not neglecting the accuracy too) which makes problem even more complicated. When working on such kind of models people often need to do some Image Processing first.\n### The idea of this Kernel is to do some feature engineering on images before feeding it to machine learning algorithms.  \nWith this in mind I performed several image processing techniques and went lightly through them, showing the joined results in the end. This could be good start before building predicting algorithm."},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"9662968888f3eabed2ca1236e42fabf7e82c686d"},"cell_type":"code","source":"import os\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport numpy as np\nfrom skimage import io\nfrom skimage import measure \nfrom skimage import feature\nfrom skimage.morphology import disk\nfrom skimage.filters import rank\nfrom skimage import exposure\nimport warnings\nwarnings.filterwarnings(\"ignore\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"51ec5867dc8015da7f7da84382b18ad19720ea1b","collapsed":true},"cell_type":"code","source":"marks = pd.read_csv('../input/airbus-ship-detection/train_ship_segmentations.csv') # Markers for ships\nfiles = os.listdir('../input/airbus-ship-detection/train') # Images for training\nship = io.imread('../input/picture/picture.png') \nos.chdir(\"../input/airbus-ship-detection/train\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"70a828ccbe1a81fd72dca9860bb00d9e1324135f"},"cell_type":"code","source":"Img_Height = 768\nImg_Width = 768","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"b5482409efc1e6fbaa30e3004be9236949459f74"},"cell_type":"code","source":"def mask_part(pic):\n    '''\n    Function that converts single marker from 'marks' into the image\n    '''\n    back = np.zeros(Img_Height**2)\n    starts = pic.split()[0::2]\n    lens = pic.split()[1::2]\n    for i in range(len(lens)):\n        back[(int(starts[i])-1):(int(starts[i])-1+int(lens[i]))] = 1\n    return np.reshape(back, (Img_Height, Img_Width))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"150476741a3e03823f0249ef6ed0a04a7dd22750"},"cell_type":"code","source":"def is_empty(key):\n    '''\n    Checks if there is a marker for specific image\n    i.e. if there is a ship on image\n    '''\n    df = marks[marks['ImageId'] == key].iloc[:,1]\n    if len(df) == 1 and type(df.iloc[0]) != str and np.isnan(df.iloc[0]):\n        return True\n    else:\n        return False","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"7e0faf9c1769781c83ed1441fab793143aaa4dee"},"cell_type":"code","source":"def masks_all(key):\n    '''\n    Collects together all single markers belonging to the same image\n    '''\n    df = marks[marks['ImageId'] == key].iloc[:,1]\n    masks= np.zeros((Img_Height, Img_Width))\n    if is_empty(key):\n        return masks\n    else:\n        for i in range(len(df)):\n            masks += mask_part(df.iloc[i])\n        return masks.T","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9bc495f877bc2739643ff570cd5039fe4cb2b82e","collapsed":true},"cell_type":"code","source":"def draw(file, rgb=0):\n    '''\n    Draws original image, correspondin mask and sum of two'''\n    plt.figure(figsize = (15,10))\n    plt.subplot(131, title ='Original Image')\n    plt.imshow(plt.imread(file))\n    plt.axis('off')\n    plt.subplot(132, title ='Mask of an Image')\n    plt.imshow(masks_all(file))\n    plt.axis('off')\n    plt.subplot(133, title ='Combined') \n    plt.imshow(plt.imread(file)[:,:,rgb]+masks_all(file)*200)\n    plt.axis('off')\n    plt.suptitle(file, y=0.77, verticalalignment ='top', fontsize = 22)\n    plt.show()\n    print('')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"508c8138514a2ac9be6a4df38c17e2fac4a2f321","scrolled":true,"collapsed":true},"cell_type":"code","source":"ships = [] # Here I restrict images only on those containing ship, for the sake of visualization\nfor file in files:\n    if not is_empty(file):\n        ships.append(file)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"73f869ad3e2ffebc6478c3ef5bcdc737b405e2c7"},"cell_type":"markdown","source":"### Below are 20 randomly chosen images with corresponding masks\nAs you can see from these plots, it is often very hard task even for you to detect a ship (or all the ships). So, you'll need a hell of a good model to achieve good results. "},{"metadata":{"trusted":true,"_uuid":"92d35123df1f9121647bbdc21ba772fa20126cc3","collapsed":true},"cell_type":"code","source":"for file in np.random.choice(ships, 20):\n    draw(file, rgb=1)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"dedca5d877593912057c4f8e2ae686b152f615c4"},"cell_type":"markdown","source":"## Finding Contours\nIt maght be interesting to look for the contours on image, becouse they could be around the ship and make problem a little easier.\nThis is not so trivial, becouse parameter must be choosen differently for different images so you need functions that will pick it wisely. The 'Parameter' function below tries to deal with this problem in a somewhat naive way, looking only if parameter is feasible, but not iff it gives good result."},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"7674315346fa3a6189e8c9d020ee830a601852a9"},"cell_type":"code","source":"def Parameter(file):\n    p = np.arange(10,250,20)\n    for i in p:\n        if Param(file, i):\n            break\n    return i","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"f0e0fcfcfd2fd40080bf629033e49fa51dee12d6"},"cell_type":"code","source":"def Param(file, param):\n    '''\n    Chooses feasible parameter for the function Contour (below)'''\n    img = io.imread(file)\n    img0 = img[:,:,0]\n    contours0 = measure.find_contours(img0, param)\n    img1 = img[:,:,1]\n    contours1 = measure.find_contours(img1, param)\n    img2 = img[:,:,2]\n    contours2 = measure.find_contours(img2, param)\n    if len(contours0) == 0 or len(contours1)==0 or len(contours2)==0:\n        return False\n    else:\n        return True","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"08fe2043e9f1de7522f6f021dfa5a1bc9536acac"},"cell_type":"code","source":"def Contour(file, param=150):\n    '''\n    Looks for contours on images across all three channels\n    '''\n    img = io.imread(file)\n    img0 = img[:,:,0]\n    contours0 = measure.find_contours(img0, param)\n    contour0 = max(contours0, key=len)\n    img1 = img[:,:,1]\n    contours1 = measure.find_contours(img1, param)\n    contour1 = max(contours1, key=len)\n    img2 = img[:,:,2]\n    contours2 = measure.find_contours(img2, param)\n    contour2 = max(contours2, key=len)\n    return contour0, contour1, contour2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":true,"_uuid":"bff181424f2b8165fe9a8fa326eb3ab40bcfd9aa","collapsed":true},"cell_type":"code","source":"def Draw_contour(file, param=150):\n    '''\n    Plots together contour on an original image,\n    zoomed part of original image containing contoure and contoure alone\n    in each of three color channels\n    '''\n    img = io.imread(file)\n    img0, img1, img2 = img[:,:,0],img[:,:,1],img[:,:,2]\n    contour0, contour1, contour2 = Contour(file, param)\n    fig, (ax, ax3, ax2) = plt.subplots(ncols=3, figsize=(20, 10))\n    fig.figsize = (20,20)\n    ax.plot(contour0[::,1], contour0[::,0], color = 'g', linewidth = 0.2)\n    ax.imshow(img0, origin='lower', cmap='Reds')\n    ax.axis('off')\n    ax.set(title = 'Red Spectrum')\n    ax2.plot(contour0[::,1], contour0[::,0], color = 'tan')\n    asp = np.diff(ax2.get_xlim())[0] / np.diff(ax2.get_ylim())[0]\n    ax2.set_aspect(asp)\n    ax2.axis('off')\n    ax2.set(title = 'Only Contour')\n    ax3.set(xlim=(min(contour0[::,1])-50,max(contour0[::,1])+50), ylim=(min(contour0[::,0])-50,max(contour0[::,0])+50), autoscale_on=False,\n               title='Zoom Section with Contour')\n    ax3.plot(contour0[::,1], contour0[::,0], color = 'g', linewidth = 0.9)\n    ax3.imshow(img0, cmap='Reds')\n    ax3.axis('off')\n    plt.suptitle(file, y=0.85, fontsize = 22, x=0.25)\n    plt.show()\n\n    fig, (ax, ax3, ax2) = plt.subplots(ncols=3, figsize=(20, 10))\n    fig.figsize = (20,20)\n    ax.plot(contour1[::,1], contour1[::,0], color = 'r', linewidth = 0.2)\n    ax.imshow(img1, origin='lower', cmap='Greens')\n    ax.axis('off')\n    ax.set(title = 'Green Spectrum')\n    ax2.plot(contour1[::,1], contour1[::,0], color = 'tan')\n    asp = np.diff(ax2.get_xlim())[0] / np.diff(ax2.get_ylim())[0]\n    ax2.set_aspect(asp)\n    ax2.axis('off')\n    ax2.set(title = 'Only Contour')\n    ax3.set(xlim=(min(contour1[::,1])-50,max(contour1[::,1])+50), ylim=(min(contour1[::,0])-50,max(contour1[::,0])+50), autoscale_on=False,\n               title='Zoom Section with Contour')\n    ax3.plot(contour1[::,1], contour1[::,0], color = 'r', linewidth = 0.9)\n    ax3.imshow(img1, cmap='Greens')\n    ax3.axis('off')\n    plt.suptitle(file, y=0.85, fontsize = 22, x=0.25)\n    plt.show()\n\n    fig, (ax, ax3, ax2) = plt.subplots(ncols=3, figsize=(20, 10))\n    fig.figsize = (20,20)\n    ax.plot(contour2[::,1], contour2[::,0], color = 'r', linewidth = 0.2)\n    ax.imshow(img2, origin='lower', cmap='Blues')\n    ax.axis('off')\n    ax.set(title = 'Blue Spectrum')\n    ax2.plot(contour2[::,1], contour2[::,0], color = 'tan')\n    asp = np.diff(ax2.get_xlim())[0] / np.diff(ax2.get_ylim())[0]\n    ax2.set_aspect(asp)\n    ax2.axis('off')\n    ax2.set(title = 'Only Contour')\n    ax3.set(xlim=(min(contour2[::,1])-20,max(contour2[::,1])+20), ylim=(min(contour2[::,0])-20,max(contour2[::,0])+20), autoscale_on=False,\n               title='Zoom Section with Contour')\n    ax3.plot(contour2[::,1], contour2[::,0], color = 'r', linewidth = 0.9)\n    ax3.imshow(img2, cmap='Blues')\n    ax3.axis('off')\n    plt.suptitle(file, y=0.85, fontsize = 22, x=0.25)\n    plt.show()\n    print('')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"4261b4a0b09836eb60ef81da868438792824ae1f"},"cell_type":"markdown","source":"### Plotting contours through color channels\nFrom the plots below we can see how contour on the same image can differ widely depending on spectrum. Sometimes this feature seems to be really helpful pointing to the whole ship or parts of it, but unfortunately, more offten it corresponds to the coast line or the border of a cloud. Even so, it might be of use to detect the cosat line when looking for ship. Anyway, with some better parameter tuning maybe results would be better too."},{"metadata":{"trusted":true,"scrolled":true,"_uuid":"f11ee1d195e9af9482dfc2fc991d804447a5164a","collapsed":true},"cell_type":"code","source":"for file in np.random.choice(ships, 20):\n    Draw_contour(file, Parameter(file))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"2ca49148e37ab988a974ff3b31fb41b278af26c7"},"cell_type":"markdown","source":"## Equalizing and Stretching Image Contrast\nLowering contrast is common in image processing, but also often used in order to 'nicer' looking picture, \npresenting in a way we consider looking good. On the other side, contrast stretching creates pictures that\naren't so 'nice' but are probably better suited for problems like this where you want to detect object.\nBoth these techniques are shown below."},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"3ae9741b16b948f28a177980ebde7498e7c2d69a"},"cell_type":"code","source":"def Equalizer(file):\n    '''\n    Equalizes image spectrum (in gray scale)\n    '''\n    img = io.imread(file, as_grey=True)\n    selem = disk(100)\n    img_eq = rank.equalize(img, selem=selem)\n    return img_eq","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":true,"_uuid":"952f3b1e892ae91abab3fc07d47fb202b1da5367","collapsed":true},"cell_type":"code","source":"for file in np.random.choice(ships, 10):\n    plt.imshow(Equalizer(file), cmap='inferno')\n    plt.axis('off')\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a1118de4a5d57ee05ab5e80023c31bfee3197a66","collapsed":true},"cell_type":"code","source":"def Contrast(file, channel = None):\n    '''\n    Creates high contrast image (in specified channel)\n    '''\n    img = io.imread(file, as_grey= False)\n    left, right = np.percentile(img, (30, 70))\n    if channel ==None:\n        img_rescale = exposure.rescale_intensity(img, in_range=(left, right))\n    else:\n        img_rescale = exposure.rescale_intensity(img[:,:,channel], in_range=(left, right))\n    return img_rescale","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b49e7f5f77f4b83b3ba4aba2d0604c43859e5a4a","collapsed":true},"cell_type":"code","source":"def draw_contrast(file):\n    '''\n    Plots together original image, \n    high contrast image (in rgb and in each of color channels)\n    and lower contrast image\n    '''\n    img = io.imread(file) \n    print('')\n    plt.figure(figsize = (15,15))\n    plt.subplot(161, title ='Original')\n    plt.imshow(img)\n    plt.axis('off')\n    plt.subplot(162, title ='High Contrast (HC)')\n    plt.imshow(Contrast(file))\n    plt.axis('off')\n    plt.subplot(163, title ='HC Red Spectrum') \n    plt.imshow(Contrast(file, 0), cmap='inferno')\n    plt.axis('off')\n    plt.subplot(164, title ='HC Green Spectrum') \n    plt.imshow(Contrast(file, 1), cmap='inferno')\n    plt.axis('off')\n    plt.subplot(165, title ='HC Blue Spectrum') \n    plt.imshow(Contrast(file, 2), cmap='inferno')\n    plt.axis('off')\n    plt.subplot(166, title ='Equalized Image') \n    plt.imshow(Equalizer(file), cmap='inferno')\n    plt.axis('off')\n    plt.suptitle(file, y=0.63, fontsize = 22)\n    plt.show()      ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9593f24757670b8cf38ce00ac67dba216e33a481"},"cell_type":"code","source":"for file in np.random.choice(ships, 20):\n    draw_contrast(file)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3087a4b6c583fe10104b687422aa690ba9002d5f","collapsed":true},"cell_type":"code","source":"def plot_all(file):\n    '''\n    Plots all extracted features together\n    '''\n    img = io.imread(file)\n    plt.figure(figsize = (12,15))\n    plt.subplot(431)\n    plt.xlim(4000,0)\n    plt.imshow(ship)\n    plt.axis('off')\n    plt.subplot(432, title ='Original')\n    plt.imshow(img)\n    plt.axis('off')\n    plt.subplot(433)\n    plt.imshow(ship)\n    plt.axis('off')\n    plt.subplot(434, title ='Mask')\n    plt.imshow(masks_all(file))\n    plt.axis('off')\n    plt.subplot(435, title ='High Contrast (HC)')\n    plt.imshow(Contrast(file))\n    plt.axis('off')\n    plt.subplot(436, title ='Equalized Image') \n    plt.imshow(Equalizer(file), cmap='inferno')\n    plt.axis('off')\n    plt.subplot(437, title ='HC Red Spectrum') \n    plt.imshow(Contrast(file, 0), cmap='inferno')\n    plt.axis('off')\n    plt.subplot(438, title ='HC Green Spectrum') \n    plt.imshow(Contrast(file, 1), cmap='inferno')\n    plt.axis('off')\n    plt.subplot(439, title ='HC Blue Spectrum') \n    plt.imshow(Contrast(file, 2), cmap='inferno')\n    plt.axis('off')\n    c0, c1, c2 = Contour(file, param=Parameter(file))\n    plt.subplot(4,3,10, title ='Red Spectrum Contours') \n    plt.plot(c0[::,1], c0[::,0], color = 'tan')\n    plt.axis('off')\n    plt.imshow(np.zeros((768,768)), cmap = 'summer')\n    plt.subplot(4,3,11, title ='Green Spectrum Contours') \n    plt.plot(c0[::,1], c0[::,0], color = 'tan')\n    plt.axis('off')\n    plt.imshow(np.zeros((768,768)), cmap = 'summer')\n    plt.subplot(4,3,12, title ='Blue Spectrum Contours') \n    plt.plot(c0[::,1], c0[::,0], color = 'tan')\n    plt.axis('off')\n    plt.imshow(np.zeros((768,768)), cmap ='summer')\n    plt.suptitle(file, y=0.92, fontsize = 22)\n    plt.show()\n    print('')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"cad5a858f500d32d4bf9073540c8113332f92ea9"},"cell_type":"markdown","source":"## All Together\nWe have come to the end, and below are presented together all features extracted. Hope this was usefull"},{"metadata":{"trusted":true,"_uuid":"3b86c18cb95e8e371935ac57103ab384946b681b"},"cell_type":"code","source":"for file in np.random.choice(ships, 20):\n    plot_all(file)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"dbf3f86e502d67e4eccdab3121cc35e4844c9a62"},"cell_type":"markdown","source":"##### That's all folks"},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"1fbb8e1f7f91d4fe36fa713833783a00a4095a76"},"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.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}