{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "_cell_guid": "87529994-556a-8231-cde3-843396a1a29d"
      },
      "source": [
        "# Countless Sea Lions\n",
        "\n",
        "In this challenge we are given a set of images and are asked to calculate the number of sea lions in each image. We simplify the challenge a bit by only focusing on seals rather than the different types. We apply the concepts of the lecture like thresholding, connected component labeling and shape analysis to try and automatically find the sea lions. Much of the code is setup code specific to this challenge and so do not be concerned if you do not understand all of it."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "75b8f60e-0bda-5980-3fde-6a672b13ce79"
      },
      "outputs": [],
      "source": [
        "import numpy as np # linear algebra\n",
        "import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n",
        "from subprocess import check_output\n",
        "import matplotlib.pyplot as plt\n",
        "from glob import glob\n",
        "import seaborn as sns\n",
        "sns.set_style(\"whitegrid\", {'axes.grid': False})\n",
        "from scipy import stats\n",
        "from skimage.io import imread, imshow\n",
        "from skimage.util import crop\n",
        "import os\n",
        "import cv2\n",
        "from collections import namedtuple\n",
        "def get_dots_from_image(cropped_dotted, cropped_raw):\n",
        "    \"\"\"\n",
        "    # Get the markers only\n",
        "    There are also brown markers which are removed by our thresholding and are also not very present in the difference image itself.\"\"\"\n",
        "    y_max, x_max, _ = cropped_dotted.shape\n",
        "    diff = cv2.subtract(cropped_dotted, cropped_raw)\n",
        "    diff = diff/diff.max()\n",
        "    diff = cv2.absdiff(cropped_dotted, cropped_raw)\n",
        "    gray = cv2.cvtColor(diff, cv2.COLOR_RGB2GRAY)\n",
        "    ret,th1 = cv2.threshold(gray,0,255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)\n",
        "    cnts = cv2.findContours(th1.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[-2]\n",
        "    x, y = [], []\n",
        "    for loc in cnts:\n",
        "        x.append(loc[0][0][0])\n",
        "        y.append(loc[0][0][1])\n",
        "    x = np.array(x)\n",
        "    y = np.array(y)\n",
        "    return x,y\n",
        "\n",
        "labimg=namedtuple('LabeledImage',['image','x','y'])\n",
        "\n",
        "def load_image_and_labels(img_id):\n",
        "    \"\"\"\n",
        "    Read the images and compute the x,y coordinates of the sea lions\n",
        "    \"\"\"\n",
        "    temp_dotted = cv2.cvtColor(cv2.imread('../input/TrainDotted/{}'.format(img_id)), cv2.COLOR_BGR2RGB)\n",
        "    temp_raw = cv2.cvtColor(cv2.imread('../input/Train/{}'.format(img_id)), cv2.COLOR_BGR2RGB)\n",
        "    x,y = get_dots_from_image(temp_dotted,temp_raw)\n",
        "    return labimg(temp_raw,x,y)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "_cell_guid": "41760144-1374-06b8-6153-3f8e0f77ef4b"
      },
      "source": [
        "# Sample Images\n",
        "\n",
        "Each image in the training set as an unique training id and gives the counts of each sea lion category. \n",
        "\n",
        "Let's load a few images and have a look at them."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "80f24883-300a-9bae-f329-960ed8a1f52c"
      },
      "outputs": [],
      "source": [
        "training_image_ids = [os.path.basename(c) for c in glob('../input/Train/*.jpg')]\n",
        "print(len(training_image_ids),'images, first', training_image_ids[0])"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "96fd26f2-812c-0c26-3ade-2b9a37f64cca"
      },
      "outputs": [],
      "source": [
        "fig, m_axs = plt.subplots(2,2, figsize=(10,10))\n",
        "for c_ax, t_img_id in zip(m_axs.flatten(), training_image_ids):\n",
        "    t_img = load_image_and_labels(t_img_id)\n",
        "    c_ax.imshow(t_img.image)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "_cell_guid": "3c550022-884f-f28a-3495-5caad80c1fbb"
      },
      "source": [
        "# Show Identified Sea Lions\n",
        "Here we show the points at the center of gravity for Sea Lions"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "b121e93f-f18e-8193-4d98-9f63f9d72b64"
      },
      "outputs": [],
      "source": [
        "fig, m_axs = plt.subplots(4,1, figsize=(8,24))\n",
        "for (ax1), t_img_id in zip(m_axs, training_image_ids):\n",
        "    t_img = load_image_and_labels(t_img_id)\n",
        "    ax1.imshow(t_img.image)\n",
        "    ax1.plot(t_img.x,t_img.y,'r.')"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "_cell_guid": "4e56c6fc-5ee7-b890-3b38-553af8e6fbca"
      },
      "source": [
        "# Simple Threshold\n",
        "We convert the image to a grayscale by picking the 'sea-lion color' and subtracting it from every color in the image and measuring the mean absolute error (sum of absolute values)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "82495d3e-17ff-ad36-08c8-80139b1fea9c"
      },
      "outputs": [],
      "source": [
        "sea_lion_color=[ 196.26725,  182.58025,  168.52425]\n",
        "mae_sea_lion_map=lambda img: np.abs(img[:,:,0]-sea_lion_color[0])+np.abs(img[:,:,1]-sea_lion_color[1])+np.abs(img[:,:,2]-sea_lion_color[2])"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "657b7a93-f8bd-dfd8-d231-8c50fcdf5b17"
      },
      "outputs": [],
      "source": [
        "fig, m_axs = plt.subplots(2,2, figsize=(8,12))\n",
        "for (ax1,ax2), t_img_id in zip(m_axs, training_image_ids):\n",
        "    t_img = load_image_and_labels(t_img_id)\n",
        "    ax1.imshow(t_img.image)\n",
        "    ax1.plot(t_img.x,t_img.y,'r.')\n",
        "    \n",
        "    ax2.imshow(mae_sea_lion_map(t_img.image),cmap='bone')\n",
        "    ax2.plot(t_img.x,t_img.y,'r.')"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "1d152fbe-a4a1-183e-9ed2-f46504806a9a"
      },
      "outputs": [],
      "source": ""
    }
  ],
  "metadata": {
    "_change_revision": 0,
    "_is_fork": false,
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.6.0"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}