{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "_cell_guid": "9cfd0e90-cfef-21f9-9914-4304373f81f5"
   },
   "source": [
    "# Data exploration\n",
    "\n",
    "- Visualization of all training data, all testing data\n",
    "- Visualize some additional training data\n",
    "- Clustering of training and test data\n",
    "- Basic skin detection\n",
    "- Some stats using jpg exif"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "_cell_guid": "948f623a-4a94-5f35-ceaf-fe424582d564"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "additional\n",
      "sample_submission.csv\n",
      "test\n",
      "train\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# This Python 3 environment comes with many helpful analytics libraries installed\n",
    "# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n",
    "# For example, here's several helpful packages to load in \n",
    "\n",
    "import numpy as np # linear algebra\n",
    "import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n",
    "import cv2\n",
    "\n",
    "# Input data files are available in the \"../input/\" directory.\n",
    "# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory\n",
    "\n",
    "from subprocess import check_output\n",
    "print(check_output([\"ls ../input/\"], shell=True).decode(\"utf8\"))\n",
    "\n",
    "# Any results you write to the current directory are saved as output."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "_cell_guid": "51a49ad2-8ced-248b-191f-f54a4adfa419"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "250 781 450\n",
      "Type 1 ['0' '10' '1013' '1014' '1019' '102' '1023' '1024' '1026' '1027']\n",
      "Type 2 ['1' '100' '1001' '1002' '1005' '1006' '101' '1010' '1011' '1012']\n",
      "Type 3 ['1000' '1003' '1004' '1007' '1008' '1009' '1015' '1020' '1028' '1029']\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "from glob import glob\n",
    "TRAIN_DATA = \"../input/train\"\n",
    "type_1_files = glob(os.path.join(TRAIN_DATA, \"Type_1\", \"*.jpg\"))\n",
    "type_1_ids = np.array([s[len(os.path.join(TRAIN_DATA, \"Type_1\"))+1:-4] for s in type_1_files])\n",
    "type_2_files = glob(os.path.join(TRAIN_DATA, \"Type_2\", \"*.jpg\"))\n",
    "type_2_ids = np.array([s[len(os.path.join(TRAIN_DATA, \"Type_2\"))+1:-4] for s in type_2_files])\n",
    "type_3_files = glob(os.path.join(TRAIN_DATA, \"Type_3\", \"*.jpg\"))\n",
    "type_3_ids = np.array([s[len(os.path.join(TRAIN_DATA, \"Type_3\"))+1:-4] for s in type_3_files])\n",
    "\n",
    "print(len(type_1_files), len(type_2_files), len(type_3_files))\n",
    "print(\"Type 1\", type_1_ids[:10])\n",
    "print(\"Type 2\", type_2_ids[:10])\n",
    "print(\"Type 3\", type_3_ids[:10])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "_cell_guid": "4301126b-d4f5-3b05-f443-14b9fd20d319"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "512\n",
      "['0' '1' '10' '100' '101' '102' '103' '104' '105' '106']\n"
     ]
    }
   ],
   "source": [
    "TEST_DATA = \"../input/test\"\n",
    "test_files = glob(os.path.join(TEST_DATA, \"*.jpg\"))\n",
    "test_ids = np.array([s[len(TEST_DATA)+1:-4] for s in test_files])\n",
    "print(len(test_ids))\n",
    "print(test_ids[:10])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "_cell_guid": "07f0897f-17e2-f4c0-0b05-ab3f879a7424"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1191 3567 3567\n",
      "Type 1 ['2475' '4017' '10' '1000' '1001' '1003' '1004' '1005' '1009' '1011']\n",
      "Type 2 ['0' '1' '1002' '1006' '1007' '1008' '101' '1013' '1016' '1017']\n",
      "Type 3 ['100' '1010' '1012' '1014' '1019' '1021' '1027' '1041' '1048' '1051']\n"
     ]
    }
   ],
   "source": [
    "ADDITIONAL_DATA = \"../input/additional\"\n",
    "additional_type_1_files = glob(os.path.join(ADDITIONAL_DATA, \"Type_1\", \"*.jpg\"))\n",
    "additional_type_1_ids = np.array([s[len(os.path.join(ADDITIONAL_DATA, \"Type_1\"))+1:-4] for s in additional_type_1_files])\n",
    "additional_type_2_files = glob(os.path.join(ADDITIONAL_DATA, \"Type_2\", \"*.jpg\"))\n",
    "additional_type_2_ids = np.array([s[len(os.path.join(ADDITIONAL_DATA, \"Type_2\"))+1:-4] for s in additional_type_2_files])\n",
    "additional_type_3_files = glob(os.path.join(ADDITIONAL_DATA, \"Type_3\", \"*.jpg\"))\n",
    "additional_type_3_ids = np.array([s[len(os.path.join(ADDITIONAL_DATA, \"Type_3\"))+1:-4] for s in additional_type_3_files])\n",
    "\n",
    "print(len(additional_type_1_files), len(additional_type_2_files), len(additional_type_2_files))\n",
    "print(\"Type 1\", additional_type_1_ids[:10])\n",
    "print(\"Type 2\", additional_type_2_ids[:10])\n",
    "print(\"Type 3\", additional_type_3_ids[:10])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "_cell_guid": "edc35b44-c48c-0c56-453a-b8e9cebdad91"
   },
   "outputs": [
    {
     "ename": "IndentationError",
     "evalue": "expected an indented block (<ipython-input-5-77293a7c0db1>, line 4)",
     "output_type": "error",
     "traceback": [
      "\u001b[0;36m  File \u001b[0;32m\"<ipython-input-5-77293a7c0db1>\"\u001b[0;36m, line \u001b[0;32m4\u001b[0m\n\u001b[0;31m    \"\"\"\u001b[0m\n\u001b[0m       \n^\u001b[0m\n\u001b[0;31mIndentationError\u001b[0m\u001b[0;31m:\u001b[0m expected an indented block\n"
     ]
    }
   ],
   "source": [
    "    def get_filename(image_id, image_type):\n",
    "    \"\"\"\n",
    "    Method to get image file path from its id and type   \n",
    "    \"\"\"\n",
    "    if image_type == \"Type_1\" or \\\n",
    "        image_type == \"Type_2\" or \\\n",
    "        image_type == \"Type_3\":\n",
    "        data_path = os.path.join(TRAIN_DATA, image_type)\n",
    "    elif image_type == \"Test\":\n",
    "        data_path = TEST_DATA\n",
    "    elif image_type == \"AType_1\" or \\\n",
    "          image_type == \"AType_2\" or \\\n",
    "          image_type == \"AType_3\":\n",
    "        data_path = os.path.join(ADDITIONAL_DATA, image_type[1:])\n",
    "    else:\n",
    "        raise Exception(\"Image type '%s' is not recognized\" % image_type)\n",
    "\n",
    "    ext = 'jpg'\n",
    "    return os.path.join(data_path, \"{}.{}\".format(image_id, ext))\n",
    "\n",
    "\n",
    "def get_image_data(image_id, image_type):\n",
    "    \"\"\"\n",
    "    Method to get image data as np.array specifying image id and type\n",
    "    \"\"\"\n",
    "    fname = get_filename(image_id, image_type)\n",
    "    img = cv2.imread(fname)\n",
    "    assert img is not None, \"Failed to read image : %s, %s\" % (image_id, image_type)\n",
    "    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n",
    "    return img"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "_cell_guid": "73597458-63f1-42c9-fccb-104953aeb4bf"
   },
   "outputs": [],
   "source": [
    "import matplotlib.pylab as plt\n",
    "\n",
    "def plt_st(l1,l2):\n",
    "    plt.figure(figsize=(l1,l2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "_cell_guid": "4c26418c-8af9-6dd7-92f3-52776e424e67"
   },
   "source": [
    "## Display individual images"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "_cell_guid": "004079a9-2d7b-428a-8dbd-df9cd78ae669"
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Widget Javascript not detected.  It may not be installed properly. Did you enable the widgetsnbextension? If not, then run \"jupyter nbextension enable --py --sys-prefix widgetsnbextension\"\n"
     ]
    }
   ],
   "source": [
    "from ipywidgets import widgets\n",
    "from IPython.display import display\n",
    "\n",
    "text = widgets.Text()\n",
    "display(text)\n",
    " \n",
    "def handle_submit(sender):\n",
    "    img = get_image_data(text.value, 'Type_3')\n",
    "    plt.imshow(img)\n",
    "    \n",
    "text.on_submit(handle_submit)\n",
    "\n",
    "#for image_id in type_3_ids[11:11]:\n",
    "#    img = get_image_data(image_id, 'Type_3')\n",
    "#    plt.imshow(img)\n",
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "_cell_guid": "0519c890-f4b0-00d2-03de-c466eb3e47a6"
   },
   "source": [
    "# Display all train images of Type_1, Type_2, Type_3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "_cell_guid": "ebb9981e-51e6-0bce-7560-505152199dc0"
   },
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'get_image_data' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-8-0fbfa5ffccb3>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m     17\u001b[0m                 \u001b[0;32mbreak\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     18\u001b[0m             \u001b[0mimage_id\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtrain_ids\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mcounter\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m;\u001b[0m \u001b[0mcounter\u001b[0m\u001b[0;34m+=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 19\u001b[0;31m             \u001b[0mimg\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_image_data\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mimage_id\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Type_%i'\u001b[0m \u001b[0;34m%\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mk\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     20\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     21\u001b[0m             \u001b[0mimg\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcv2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mresize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mimg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdsize\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtile_size\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mNameError\u001b[0m: name 'get_image_data' is not defined"
     ]
    }
   ],
   "source": [
    "tile_size = (256, 256)\n",
    "n = 15\n",
    "\n",
    "complete_images = []\n",
    "for k, type_ids in enumerate([type_1_ids, type_2_ids, type_3_ids]):\n",
    "    m = int(np.ceil(len(type_ids) * 1.0 / n))\n",
    "    complete_image = np.zeros((m*(tile_size[0]+2), n*(tile_size[1]+2), 3), dtype=np.uint8)\n",
    "    train_ids = sorted(type_ids)\n",
    "    counter = 0\n",
    "    for i in range(m):\n",
    "        ys = i*(tile_size[1] + 2)\n",
    "        ye = ys + tile_size[1]\n",
    "        for j in range(n):\n",
    "            xs = j*(tile_size[0] + 2)\n",
    "            xe = xs + tile_size[0]\n",
    "            if counter == len(train_ids):\n",
    "                break\n",
    "            image_id = train_ids[counter]; counter+=1\n",
    "            img = get_image_data(image_id, 'Type_%i' % (k+1))\n",
    "           \n",
    "            img = cv2.resize(img, dsize=tile_size)\n",
    "            img = cv2.putText(img, image_id, (5,img.shape[0] - 5), cv2.FONT_HERSHEY_SIMPLEX, 2.0, (255, 255, 255), thickness=3)\n",
    "            complete_image[ys:ye, xs:xe, :] = img[:,:,:]\n",
    "        if counter == len(train_ids):\n",
    "            break\n",
    "    complete_images.append(complete_image)           "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "_cell_guid": "19d6c251-a771-ad13-a8b3-cabedd0ee402"
   },
   "outputs": [
    {
     "ename": "IndexError",
     "evalue": "list index out of range",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mIndexError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-9-f1ba8027d318>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[0mplt_st\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m20\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m20\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mimshow\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcomplete_images\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      3\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtitle\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Training dataset of type %i\"\u001b[0m \u001b[0;34m%\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mIndexError\u001b[0m: list index out of range"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7fbfeec34518>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt_st(20, 20)\n",
    "plt.imshow(complete_images[2])\n",
    "plt.title(\"Training dataset of type %i\" % (3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "_cell_guid": "a1ba4b31-428a-6d50-5677-dbde8b85d243"
   },
   "outputs": [
    {
     "ename": "IndexError",
     "evalue": "list index out of range",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mIndexError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-10-be90bc52aac5>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[0mindex\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mm\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcomplete_images\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mindex\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mtile_size\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      3\u001b[0m \u001b[0mn\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mceil\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mm\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0;36m20.0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      4\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      5\u001b[0m     \u001b[0mplt_st\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m20\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m20\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mIndexError\u001b[0m: list index out of range"
     ]
    }
   ],
   "source": [
    "index = 1\n",
    "m = complete_images[index].shape[0] / (tile_size[0] + 2)\n",
    "n = int(np.ceil(m / 20.0))\n",
    "for i in range(n):\n",
    "    plt_st(20, 20)\n",
    "    ys = i*(tile_size[0] + 2)*20\n",
    "    ye = min((i+1)*(tile_size[0] + 2)*20, complete_images[index].shape[0])\n",
    "    plt.imshow(complete_images[index][ys:ye,:,:])\n",
    "    plt.title(\"Training dataset of type %i, part %i\" % (index + 1, i))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "_cell_guid": "c087ff0a-bcdb-e823-9319-b0a9bec49d61"
   },
   "outputs": [
    {
     "ename": "IndexError",
     "evalue": "list index out of range",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mIndexError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-11-f7003584aeed>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[0mindex\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mm\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcomplete_images\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mindex\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mtile_size\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      3\u001b[0m \u001b[0mn\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mceil\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mm\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0;36m20.0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      4\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      5\u001b[0m     \u001b[0mplt_st\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m20\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m20\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mIndexError\u001b[0m: list index out of range"
     ]
    }
   ],
   "source": [
    "index = 2\n",
    "m = complete_images[index].shape[0] / (tile_size[0] + 2)\n",
    "n = int(np.ceil(m / 20.0))\n",
    "for i in range(n):\n",
    "    plt_st(20, 20)\n",
    "    ys = i*(tile_size[0] + 2)*20\n",
    "    ye = min((i+1)*(tile_size[0] + 2)*20, complete_images[index].shape[0])\n",
    "    plt.imshow(complete_images[index][ys:ye,:,:])\n",
    "    plt.title(\"Training dataset of type %i, part %i\" % (index + 1, i))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "_cell_guid": "902b1037-0846-ca12-b628-e15ce07fba18"
   },
   "source": [
    "### Display all test images"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "_cell_guid": "470cb510-1bfa-04db-82fb-cc5c94cca1d4"
   },
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'get_image_data' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-12-080072460b52>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m     13\u001b[0m             \u001b[0;32mbreak\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     14\u001b[0m         \u001b[0mimage_id\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtest_ids\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mcounter\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m;\u001b[0m \u001b[0mcounter\u001b[0m\u001b[0;34m+=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 15\u001b[0;31m         \u001b[0mimg\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_image_data\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mimage_id\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Test'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     16\u001b[0m         \u001b[0mimg\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcv2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mresize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mimg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdsize\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtile_size\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     17\u001b[0m         \u001b[0mimg\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcv2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mputText\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mimg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mimage_id\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mimg\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0;36m5\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcv2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mFONT_HERSHEY_SIMPLEX\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2.0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;36m255\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m255\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m255\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mthickness\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mNameError\u001b[0m: name 'get_image_data' is not defined"
     ]
    }
   ],
   "source": [
    "tile_size = (256, 256)\n",
    "n = 15\n",
    "m = int(np.ceil(len(test_ids) * 1.0 / n))\n",
    "complete_test_image = np.zeros((m*(tile_size[0]+2), n*(tile_size[1]+2), 3), dtype=np.uint8)\n",
    "counter = 0\n",
    "for i in range(m):\n",
    "    ys = i*(tile_size[1] + 2)\n",
    "    ye = ys + tile_size[1]\n",
    "    for j in range(n):\n",
    "        xs = j*(tile_size[0] + 2)\n",
    "        xe = xs + tile_size[0]\n",
    "        if counter == len(test_ids):\n",
    "            break\n",
    "        image_id = test_ids[counter]; counter+=1\n",
    "        img = get_image_data(image_id, 'Test')\n",
    "        img = cv2.resize(img, dsize=tile_size)\n",
    "        img = cv2.putText(img, image_id, (5,img.shape[0] - 5), cv2.FONT_HERSHEY_SIMPLEX, 2.0, (255, 255, 255), thickness=3)\n",
    "        complete_test_image[ys:ye, xs:xe, :] = img[:,:,:]\n",
    "    if counter == len(test_ids):\n",
    "        break"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "_cell_guid": "5c941d6f-2e27-81fd-5db1-2417e7f7ea5d"
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAA2EAAARuCAYAAABa/T9kAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3X/sdndd3/HXm4IUBpUysOnultFtjQ5c1FFqE9kvHdLM\nadmc0GWOLoN2i+hkY1uKUxcNcY2bYtgGpENHic7aqbFV6TYsRLdoLSgSLIhUEGntDxg/Cgwrhc/+\nuE7JxW3b+9v27qt3uR+P5Mr3XJ9zzuc65/7nzjPnXOeatVYAAADoeMRDfQAAAADHExEGAABQJMIA\nAACKRBgAAECRCAMAACgSYQAAAEUiDIBjzszcMjPPeqiPAwAeDCIMgCTJzHxi7/XZmfnU3vt/8ADm\nvXZmvvVoHuve3CfOzJqZ0x6M+dufc4RjuGRmXnuEbZ48Mz8/M5+cmffNzN9rHR8AB/fIh/oAADg2\nrLUed9fyzPx+khettX7poTsi7jIzB/3/+tIkH0nyJUm+OsnPzczb11rvedAODoD7zJUwAA5kZk6Y\nme+ZmffOzIdm5idm5gnbuj81M5fPzIdn5qMz8+szc/LM/FCSZyZ57XZF7YfuYe4XzswfzMwHZ+Zf\nHbbua7b5Pjozfzgzr9iLkl/Z/r57m/+529Wgq7e5PjwzV87MqXvzXTgzvz8zH9/O5Vv21v2TmXn3\ntt8vzsyhe/qcA/x7XT4z/3Fm3rx91jV782VmXj0zN87M7TNz3cycs7fukpn5bzPzUzPz8STnJ/kX\nSS7YPv+6u/m8k5N8Y5LvWWt9cq31piT/I8n9vooJwINDhAFwUP8yydcneVaS05J8OskrtnUvyu7u\nikNJnpTk25P88VrrpUnekt1Vtcdt7z/PzHxVkh9J8vxt3qduc9zl09t8fzrJX8kuNF60rfur298v\n3eb/uez+b3tNkqckOWNb/4rts05O8u+TfN1a6/Hbufz2tu75SV6yzX9Kkrcl+fF7+ZyD+IdJvivJ\nk5O8J8lle+t+Lclf2s7ryiT/fWYetbf+m7ftvzjJzyT54SSXbZ9/9t181pcl+fha6/17Y29P8vQD\nHisAJSIMgIP6p0kuXmv94Vrrj5J8X5Lnz8xkF0pPTvLn11p3rrXestb65AHn/ZYkP7PW+rW11h3Z\nRcvn/n9aa123zfeZtdbvJXltkr92T5OttW5da1251vrUWutjSf7d3Wz/5TNz4nYu79o7v5evtX53\nrfXp7fyeNTOnHPA87s7Pbef1R9t5fd3MPHk7ztevtT6yfdYPZBdjf25v319ea71hrfXZtdanDvBZ\nj0vyscPGbk/y+Adw/AA8CEQYAEe0hdbpSd6w3Rb40eyuFD0iu3j40SS/nOSnt1vsfmBmTjjg9H8m\nyQfuerOF0+diYmaett1eeOvM3J7ke/P5V8oOP9bHz8yPbbc33p7kf921/VrrI9ndnvfPktwyM1fN\nzF/Ydv2zSV6zd34fTHJndlfn7q/98/pwkk9s55uZedl26+PHsvse14mHndcHct98IslJh419cZKP\n39eDBuDBJcIAOKK11kpyU5KvXWs9Ye914lrrQ2utO9Za37vW+rLsbt37luy+x5Qk6wjT35xd4CVJ\nZuaLs4uHu/yXJL+Z3VW2k5J8f5K5l7kvzi6cnrlt//V722et9Ytrra/LLob+IMmrt1UfSPKPDju/\nx6y1fuMA53BP9s/ridldrbp5Zp6d5DuS/J0kT0jyxCSf2j/Ou/nMIx3D7yQ5aWaesjf2FUmuv3+H\nDsCDRYQBcFCvSXLJzJyeJDPzJTPzjdvy39yuWD0iu1vg7kzy2W2/W/P5t9kd7ookf3dmvnpmHp3k\n5Xv7Jrvb6T621vrEzDw9yYV3rdhuX/zYYfM/Psn/S/LRmXlSku++a8XMHJqZb5iZxya5I7urR3d9\n1muSfPfMfOm27ckz88339Dl7j63/3AM17sZ5h53Xm9dat23H+OnsrrZ9UXZheeK9zJPs/h3P2K5K\n/gnbVb5fSPL9M/PYmfkbSZ6T5CeOMC8AZSIMgIP6wSS/lORN2xP7fjXJX97WHcru4RIfz+5BF29I\n8lPbulckecHMfGRmfvDwSddab0vy0iQ/neTG7K5OfWhvk3+e5EUz84kk/3lv3rt8b3YPtfjozHxT\nkv+Q3W19/zfJ/9mO5S4nZHel7JZt/TOze+hH1lo/meQ/JfnZ7TbG30ry7Hv5nNOzu43wnffyb/bj\nSS7ZzucvJrlgG//57J64+HtJ3rut/+C9zJMklyd5bJIPz8yv3sM2F27n/qEk/zXJCz2eHuDYM7s7\nTACA+2JmXpTk0Frr++5h/eVJfnut9fLukQFwrPNjzQBwP6y1XvtQHwMAD0/12xFn5tztaVA3zMzF\n7c8HAAB4KFVvR9weV/y72d1jf2N2P+D599da93Y/PQAAwBeM9pWws5PcsNZ671rrj7P7kvF55WMA\nAAB4yLQj7FA+/8cnb9zGAAAAjgvH5IM5ZuaiJBdtb5/xUB4LAADAQa217vb3HPe1I+ym7H5X5S6n\nbWOfZ611aZJLk2RmPEMfAAD4gtG+HfEtSc6cmTNm5ouSnJ/kqvIxAAAAPGSqV8LWWnfOzLcn+Z9J\nTkjyY2ut65vHAAAA8FCqPqL+/nA7IgAA8HBxkO+E1X+sGQAA4HgmwgAAAIpEGAAAQJEIAwAAKBJh\nAAAARSIMAACgSIQBAAAUiTAAAIAiEQYAAFAkwgAAAIpEGAAAQJEIAwAAKBJhAAAARSIMAACgSIQB\nAAAUiTAAAIAiEQYAAFAkwgAAAIpEGAAAQJEIAwAAKBJhAAAARSIMAACgSIQBAAAUiTAAAIAiEQYA\nAFAkwgAAAIpEGAAAQJEIAwAAKBJhAAAARSIMAACgSIQBAAAUiTAAAIAiEQYAAFAkwgAAAIpEGAAA\nQJEIAwAAKBJhAAAARSIMAACgSIQBAAAUiTAAAIAiEQYAAFAkwgAAAIpEGAAAQJEIAwAAKBJhAAAA\nRSIMAACgSIQBAAAUiTAAAIAiEQYAAFAkwgAAAIpEGAAAQJEIAwAAKBJhAAAARSIMAACgSIQBAAAU\niTAAAIAiEQYAAFAkwgAAAIpEGAAAQJEIAwAAKBJhAAAARSIMAACgSIQBAAAUiTAAAIAiEQYAAFAk\nwgAAAIpEGAAAQJEIAwAAKBJhAAAARSIMAACgSIQBAAAUiTAAAIAiEQYAAFAkwgAAAIpEGAAAQJEI\nAwAAKBJhAAAARSIMAACgSIQBAAAUiTAAAIAiEQYAAFAkwgAAAIpEGAAAQJEIAwAAKBJhAAAARSIM\nAACgSIQBAAAUiTAAAIAiEQYAAFAkwgAAAIpEGAAAQJEIAwAAKBJhAAAARSIMAACgSIQBAAAUiTAA\nAIAiEQYAAFAkwgAAAIpEGAAAQJEIAwAAKBJhAAAARSIMAACgSIQBAAAUiTAAAIAiEQYAAFAkwgAA\nAIpEGAAAQJEIAwAAKBJhAAAARSIMAACgSIQBAAAUiTAAAIAiEQYAAFAkwgAAAIpEGAAAQJEIAwAA\nKBJhAAAARSIMAACgSIQBAAAUiTAAAIAiEQYAAFAkwgAAAIpEGAAAQJEIAwAAKBJhAAAARSIMAACg\nSIQBAAAUiTAAAIAiEQYAAFAkwgAAAIpEGAAAQJEIAwAAKBJhAAAARSIMAACgSIQBAAAUiTAAAIAi\nEQYAAFAkwgAAAIpEGAAAQJEIAwAAKBJhAAAARSIMAACgSIQBAAAUiTAAAIAiEQYAAFAkwgAAAIpE\nGAAAQJEIAwAAKBJhAAAARSIMAACgSIQBAAAUiTAAAIAiEQYAAFAkwgAAAIpEGAAAQJEIAwAAKBJh\nAAAARSIMAACgSIQBAAAUiTAAAIAiEQYAAFAkwgAAAIpEGAAAQJEIAwAAKBJhAAAARSIMAACgSIQB\nAAAUiTAAAIAiEQYAAFAkwgAAAIpEGAAAQJEIAwAAKBJhAAAARSIMAACgSIQBAAAUiTAAAIAiEQYA\nAFAkwgAAAIpEGAAAQJEIAwAAKBJhAAAARSIMAACgSIQBAAAUiTAAAIAiEQYAAFAkwgAAAIpEGAAA\nQJEIAwAAKBJhAAAARSIMAACgSIQBAAAUiTAAAIAiEQYAAFAkwgAAAIpEGAAAQJEIAwAAKBJhAAAA\nRSIMAACgSIQBAAAUiTAAAIAiEQYAAFAkwgAAAIqOGGEz82Mzc9vM/Pbe2BNn5o0z857t78l76142\nMzfMzLtn5jl748+YmXds6145M3P0TwcAAODYdpArYa9Lcu5hYxcnuWatdWaSa7b3mZmnJTk/ydO3\nfV41Myds+7w6yYVJztxeh88JAADwBe+IEbbW+pUkHz5s+Lwkl23LlyV57t745WutO9Za70tyQ5Kz\nZ+bUJCetta5da60kr9/bBwAA4LjxyPu53ylrrZu35VuSnLItH0py7d52N25jn96WDx+/WzNzUZKL\n7uexAQAAHLPub4R9zlprzcw6GgezN+elSS5NkqM9NwAAwEPp/j4d8dbtFsNsf2/bxm9Kcvredqdt\nYzdty4ePAwAAHFfub4RdleSCbfmCJFfujZ8/M4+emTOyewDHdduti7fPzDnbUxFfsLcPAADAceOI\ntyPOzE8m+etJnjQzNyb5t0kuSXLFzLwwyfuTPC9J1lrXz8wVSd6Z5M4kL15rfWab6tuye9LiY5Jc\nvb0AAACOK7N7WOGxy3fCAACAh4u11hF/D/n+3o4IAADA/SDCAAAAikQYAABAkQgDAAAoEmEAAABF\nIgwAAKBIhAEAABSJMAAAgCIRBgAAUCTCAAAAikQYAABAkQgDAAAoEmEAAABFIgwAAKBIhAEAABSJ\nMAAAgCIRBgAAUCTCAAAAikQYAABAkQgDAAAoEmEAAABFIgwAAKBIhAEAABSJMAAAgCIRBgAAUCTC\nAAAAikQYAABAkQgDAAAoEmEAAABFIgwAAKBIhAEAABSJMAAAgCIRBgAAUCTCAAAAikQYAABAkQgD\nAAAoEmEAAABFIgwAAKBIhAEAABSJMAAAgCIRBgAAUCTCAAAAikQYAABAkQgDAAAoEmEAAABFIgwA\nAKBIhAEAABSJMAAAgCIRBgAAUCTCAAAAikQYAABAkQgDAAAoEmEAAABFIgwAAKBIhAEAABSJMAAA\ngCIRBgAAUCTCAAAAikQYAABAkQgDAAAoEmEAAABFIgwAAKBIhAEAABSJMAAAgCIRBgAAUCTCAAAA\nikQYAABAkQgDAAAoEmEAAABFIgwAAKBIhAEAABSJMAAAgCIRBgAAUCTCAAAAikQYAABAkQgDAAAo\nEmEAAABFIgwAAKBIhAEAABSJMAAAgCIRBgAAUCTCAAAAikQYAABAkQgDAAAoEmEAAABFIgwAAKBI\nhAEAABSJMAAAgCIRBgAAUCTCAAAAikQYAABAkQgDAAAoEmEAAABFIgwAAKBIhAEAABSJMAAAgCIR\nBgAAUCTCAAAAikQYAABAkQgDAAAoEmEAAABFIgwAAKBIhAEAABSJMAAAgCIRBgAAUCTCAAAAikQY\nAABAkQgDAAAoEmEAAABFIgwAAKBIhAEAABSJMAAAgCIRBgAAUCTCAAAAikQYAABAkQgDAAAoEmEA\nAABFIgwAAKBIhAEAABSJMAAAgCIRBgAAUCTCAAAAikQYAABAkQgDAAAoEmEAAABFIgwAAKBIhAEA\nABSJMAAAgCIRBgAAUCTCAAAAikQYAABAkQgDAAAoEmEAAABFIgwAAKBIhAEAABSJMAAAgCIRBgAA\nUCTCAAAAikQYAABAkQgDAAAoEmEAAABFIgwAAKBIhAEAABSJMAAAgCIRBgAAUCTCAAAAikQYAABA\nkQgDAAAoEmEAAABFIgwAAKBIhAEAABSJMAAAgCIRBgAAUCTCAAAAikQYAABAkQgDAAAoEmEAAABF\nIgwAAKBIhAEAABSJMAAAgCIRBgAAUCTCAAAAikQYAABAkQgDAAAoEmEAAABFIgwAAKBIhAEAABSJ\nMAAAgCIRBgAAUCTCAAAAikQYAABAkQgDAAAoEmEAAABFIgwAAKBIhAEAABSJMAAAgCIRBgAAUCTC\nAAAAikQYAABAkQgDAAAoEmEAAABFIgwAAKBIhAEAABSJMAAAgCIRBgAAUCTCAAAAikQYAABAkQgD\nAAAoEmEAAABFIgwAAKBIhAEAABSJMAAAgCIRBgAAUCTCAAAAikQYAABAkQgDAAAoEmEAAABFIgwA\nAKBIhAEAABSJMAAAgCIRBgAAUCTCAAAAio4YYTNz+sy8eWbeOTPXz8x3buNPnJk3zsx7tr8n7+3z\nspm5YWbePTPP2Rt/xsy8Y1v3ypmZB+e0AAAAjk0HuRJ2Z5KXrrWeluScJC+emacluTjJNWutM5Nc\ns73Ptu78JE9Pcm6SV83MCdtcr05yYZIzt9e5R/FcAAAAjnlHjLC11s1rrd/clj+e5F1JDiU5L8ll\n22aXJXnutnxeksvXWnestd6X5IYkZ8/MqUlOWmtdu9ZaSV6/tw8AAMBx4ZH3ZeOZeWqSr0ry60lO\nWWvdvK26Jckp2/KhJNfu7XbjNvbpbfnw8bv7nIuSXHRfjg0AAODh4MAP5piZxyX5mSQvWWvdvr9u\nu7K1jtZBrbUuXWudtdY662jNCQAAcCw4UITNzKOyC7CfWGv97DZ863aLYba/t23jNyU5fW/307ax\nm7blw8cBAACOGwd5OuIk+dEk71pr/fDeqquSXLAtX5Dkyr3x82fm0TNzRnYP4Lhuu3Xx9pk5Z5vz\nBXv7AAAAHBdmdyfhvWww86wk/zvJO5J8dhv+ruy+F3ZFkqckeX+S5621Przt82+S/OPsnqz4krXW\n1dv4WUlel+QxSa5O8h3rCAcwM0ftNkcAAIAH01rriD/DdcQIe6iJMAAA4OHiIBF24AdzAAAA8MCJ\nMAAAgCIRBgAAUCTCAAAAikQYAABAkQgDAAAoEmEAAABFIgwAAKBIhAEAABSJMAAAgCIRBgAAUCTC\nAAAAikQYAABAkQgDAAAoEmEAAABFIgwAAKBIhAEAABSJMAAAgCIRBgAAUCTCAAAAikQYAABAkQgD\nAAAoEmEAAABFIgwAAKBIhAEAABSJMAAAgCIRBgAAUCTCAAAAikQYAABAkQgDAAAoEmEAAABFIgwA\nAKBIhAEAABSJMAAAgCIRBgAAUCTCAAAAikQYAABAkQgDAAAoEmEAAABFIgwAAKBIhAEAABSJMAAA\ngCIRBgAAUCTCAAAAikQYAABAkQgDAAAoEmEAAABFIgwAAKBIhAEAABSJMAAAgCIRBgAAUCTCAAAA\nikQYAABAkQgDAAAoEmEAAABFIgwAAKBIhAEAABSJMAAAgCIRBgAAUCTCAAAAikQYAABAkQgDAAAo\nEmEAAABFIgwAAKBIhAEAABSJMAAAgCIRBgAAUCTCAAAAikQYAABAkQgDAAAoEmEAAABFIgwAAKBI\nhAEAABSJMAAAgCIRBgAAUCTCAAAAikQYAABAkQgDAAAoEmEAAABFIgwAAKBIhAEAABSJMAAAgCIR\nBgAAUCTCAAAAikQYAABAkQgDAAAoEmEAAABFIgwAAKBIhAEAABSJMAAAgCIRBgAAUCTCAAAAikQY\nAABAkQgDAAAoEmEAAABFIgwAAKBIhAEAABSJMAAAgCIRBgAAUCTCAAAAikQYAABAkQgDAAAoEmEA\nAABFIgwAAKBIhAEAABSJMAAAgCIRBgAAUCTCAAAAikQYAABAkQgDAAAoEmEAAABFIgwAAKBIhAEA\nABSJMAAAgCIRBgAAUCTCAAAAikQYAABAkQgDAAAoEmEAAABFIgwAAKBIhAEAABSJMAAAgCIRBgAA\nUCTCAAAAikQYAABAkQgDAAAoEmEAAABFIgwAAKBIhAEAABSJMAAAgCIRBgAAUCTCAAAAikQYAABA\nkQgDAAAoEmEAAABFIgwAAKBIhAEAABSJMAAAgCIRBgAAUCTCAAAAikQYAABAkQgDAAAoEmEAAABF\nIgwAAKBIhAEAABSJMAAAgCIRBgAAUCTCAAAAikQYAABAkQgDAAAoEmEAAABFIgwAAKBIhAEAABSJ\nMAAAgCIRBgAAUCTCAAAAikQYAABAkQgDAAAoEmEAAABFIgwAAKBIhAEAABSJMAAAgCIRBgAAUCTC\nAAAAikQYAABAkQgDAAAoEmEAAABFIgwAAKBIhAEAABSJMAAAgCIRBgAAUCTCAAAAikQYAABAkQgD\nAAAoEmEAAABFIgwAAKBIhAEAABSJMAAAgCIRBgAAUCTCAAAAikQYAABAkQgDAAAoEmEAAABFIgwA\nAKBIhAEAABSJMAAAgCIRBgAAUCTCAAAAikQYAABAkQgDAAAoEmEAAABFIgwAAKBIhAEAABSJMAAA\ngCIRBgAAUCTCAAAAikQYAABAkQgDAAAoEmEAAABFIgwAAKBIhAEAABQdMcJm5sSZuW5m3j4z18/M\n923jT5yZN87Me7a/J+/t87KZuWFm3j0zz9kbf8bMvGNb98qZmQfntAAAAI5NB7kSdkeSr11rfUWS\nr0xy7syck+TiJNestc5Mcs32PjPztCTnJ3l6knOTvGpmTtjmenWSC5Ocub3OPYrnAgAAcMw7YoSt\nnU9sbx+1vVaS85Jcto1fluS52/J5SS5fa92x1npfkhuSnD0zpyY5aa117VprJXn93j4AAADHhQN9\nJ2xmTpiZ30pyW5I3rrV+Pckpa62bt01uSXLKtnwoyQf2dr9xGzu0LR8+DgAAcNw4UISttT6z1vrK\nJKdld1Xryw9bv7K7OnZUzMxFM/PWmXnr0ZoTAADgWHCfno641vpokjdn912uW7dbDLP9vW3b7KYk\np+/tdto2dtO2fPj43X3OpWuts9ZaZ92X4wMAADjWHeTpiE+emSdsy49J8uwkv5PkqiQXbJtdkOTK\nbfmqJOfPzKNn5ozsHsBx3Xbr4u0zc872VMQX7O0DAABwXHjkAbY5Ncll2xMOH5HkirXWL8zMryW5\nYmZemOT9SZ6XJGut62fmiiTvTHJnkhevtT6zzfVtSV6X5DFJrt5eAAAAx43ZfZ3r2DUzx/YBAgAA\nbNZaR/wt5Pv0nTAAAAAeGBEGAABQJMIAAACKRBgAAECRCAMAACgSYQAAAEUiDAAAoEiEAQAAFIkw\nAACAIhEGAABQJMIAAACKRBgAAECRCAMAACgSYQAAAEUiDAAAoEiEAQAAFIkwAACAIhEGAABQJMIA\nAACKRBgAAECRCAMAACgSYQAAAEUiDAAAoEiEAQAAFIkwAACAIhEGAABQJMIAAACKRBgAAECRCAMA\nACgSYQAAAEUiDAAAoEiEAQAAFIkwAACAIhEGAABQJMIAAACKRBgAAECRCAMAACgSYQAAAEUiDAAA\noEiEAQAAFIkwAACAIhEGAABQJMIAAACKRBgAAECRCAMAACgSYQAAAEUiDAAAoEiEAQAAFIkwAACA\nIhEGAABQJMIAAACKRBgAAECRCAMAACgSYQAAAEUiDAAAoEiEAQAAFIkwAACAIhEGAABQJMIAAACK\nRBgAAECRCAMAACgSYQAAAEUiDAAAoEiEAQAAFIkwAACAIhEGAABQJMIAAACKRBgAAECRCAMAACgS\nYQAAAEUiDAAAoEiEAQAAFIkwAACAIhEGAABQJMIAAACKRBgAAECRCAMAACgSYQAAAEUiDAAAoEiE\nAQAAFIkwAACAIhEGAABQJMIAAACKRBgAAECRCAMAACgSYQAAAEUiDAAAoEiEAQAAFIkwAACAIhEG\nAABQJMIAAACKRBgAAECRCAMAACgSYQAAAEUiDAAAoEiEAQAAFIkwAACAIhEGAABQJMIAAACKRBgA\nAECRCAMAACgSYQAAAEUiDAAAoEiEAQAAFIkwAACAIhEGAABQJMIAAACKRBgAAECRCAMAACgSYQAA\nAEUiDAAAoEiEAQAAFIkwAACAIhEGAABQJMIAAACKRBgAAECRCAMAACgSYQAAAEUiDAAAoEiEAQAA\nFIkwAACAIhEGAABQJMIAAACKRBgAAECRCAMAACgSYQAAAEUiDAAAoEiEAQAAFIkwAACAIhEGAABQ\nJMIAAACKRBgAAECRCAMAACgSYQAAAEUiDAAAoEiEAQAAFIkwAACAIhEGAABQJMIAAACKRBgAAECR\nCAMAACgSYQAAAEUiDAAAoEiEAQAAFIkwAACAIhEGAABQJMIAAACKRBgAAECRCAMAACgSYQAAAEUi\nDAAAoEiEAQAAFIkwAACAIhEGAABQJMIAAACKRBgAAECRCAMAACgSYQAAAEUiDAAAoEiEAQAAFIkw\nAACAIhEGAABQJMIAAACKRBgAAECRCAMAACgSYQAAAEUiDAAAoEiEAQAAFIkwAACAIhEGAABQJMIA\nAACKRBgAAECRCAMAACgSYQAAAEUiDAAAoEiEAQAAFIkwAACAIhEGAABQJMIAAACKRBgAAECRCAMA\nACgSYQAAAEUiDAAAoEiEAQAAFIkwAACAIhEGAABQJMIAAACKRBgAAECRCAMAACgSYQAAAEUiDAAA\noEiEAQAAFIkwAACAIhEGAABQJMIAAACKRBgAAECRCAMAACgSYQAAAEUiDAAAoEiEAQAAFIkwAACA\nIhEGAABQdOAIm5kTZuZtM/ML2/snzswbZ+Y929+T97Z92czcMDPvnpnn7I0/Y2besa175czM0T0d\nAACAY9t9uRL2nUnetff+4iTXrLXOTHLN9j4z87Qk5yd5epJzk7xqZk7Y9nl1kguTnLm9zn1ARw8A\nAPAwc6AIm5nTknxDktfuDZ+X5LJt+bIkz90bv3ytdcda631Jbkhy9sycmuSktda1a62V5PV7+wAA\nABwXDnol7EeS/Oskn90bO2WtdfO2fEuSU7blQ0k+sLfdjdvYoW358PE/YWYumpm3zsxbD3h8AAAA\nDwtHjLCZ+dtJbltr/cY9bbNd2VpH66DWWpeutc5aa511tOYEAAA4FjzyANt8TZJvmpm/leTEJCfN\nzI8nuXVmTl1r3bzdanjbtv1NSU7f2/+0beymbfnwcQAAgOPGEa+ErbVettY6ba311OweuPGmtda3\n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\nDPofkMuu6uxtPwQAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7fbfeebe2cc0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAABHEAAARuCAYAAABUaKsPAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3X/srnV93/HXW2jBVqwwLaEHOnFj3WBLdCAzmdvcXIV0\n6aBrVJZuskyhS60tnWsCXWftYjrS1bKwTQi1REhbKa1tYSlsU2bqllYBqSk/HPVUVM4pP3TIr82i\n4Ht/3Ndpbk8P5/vlnC+H8z48Hsmd73V/ruv6XNd1/jp55rquu7o7AAAAABzcXvBcnwAAAAAAGxNx\nAAAAAAYQcQAAAAAGEHEAAAAABhBxAAAAAAYQcQAAAAAGEHEAgFGq6v6qeu1zfR4AAAeaiAMAbKiq\nHl/7fL2qvrL2/Qf2Y96PV9U/2cpzXZv7yKrqqjr+2Zj/QB9ng3O4uKrev8E2P1ZVt1XVV6vq8gN1\nbgDA1jn8uT4BAODg190v2rVcVZ9L8rbu/shzd0bsUlWb/f/cjiTvTnL2s3c2AMCzyZ04AMB+q6rD\nqurfVNVnq+pLVfXLVfWSZd23VtU1VfVQVT1cVZ+oqqOr6r1JXp3k/csdPe99mrnfWlVfqKovVtWP\n77buby7zPVxVf1xVl6xFjY8tf+9e5j+7ql5WVTcucz1UVddV1XFr851XVZ+rqseWa3nj2rofrKq7\nl/1+u6q2Pd1xNvHvdU1V/ceq+uhyrJvW5ktVXVZVO6rq0aq6uapes7bu4qr6lar61ap6LMk5Sf5l\nknOX49+8p2N296919/VJHtro/ACAg5OIAwBshX+V5A1JXpvk+CRfS3LJsu5tWd39uy3JS5P8cJKv\ndvc7k9yS1V09L1q+f4OqelWS/5Dkzcu8L1/m2OVry3x/LsnfSvK9y/GS5G8vf79rmf+3svq/z+VJ\nvjPJicv6S5ZjHZ3k3yd5fXcftVzLHcu6Nye5YJn/2CS/n+SX9nKczfinSX4iycuSfCbJVWvrfi/J\nX1uu67okv1ZV37S2/vuX7b8tyYeS/HySq5bjn77J4wMAw4g4AMBW+BdJLuzuP+7uP0ny00neXFWV\nVWh5WZK/0N1Pdvct3f1/NznvG5N8qLt/r7ufyCp6/On/X7r75mW+p7r7j5K8P8nfebrJuvuB7r6u\nu7/S3Y8k+Xd72P6vVtWRy7V8eu363tPdf9jdX1uu77VVdewmr2NPfmu5rj9Zruv1VfWy5Tyv7u4v\n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\nHAAAAIABRBwAAACAAUQcAAAAgAFEHAAAAIABRBwAAACAAUQcAAAAgAFEHAAAAIABRBwAAACAAUQc\nAAAAgAFEHAAAAIABRBwAAACAAUQcAAAAgAFEHAAAAIABRBwAAACAAUQcAAAAgAFEHAAAAIABRBwA\nAACAAUQcAAAAgAFEHAAAAIABRBwAAACAAUQcAAAAgAFEHAAAAIABRBwAAACAAUQcAAAAgAFEHAAA\nAIABRBwAAACAAUQcAAAAgAFEHAAAAIABRBwAAACAAUQcAAAAgAFEHAAAAIABRBwAAACAAUQcAAAA\ngAFEHAAAAIABRBwAAACAAUQcAAAAgAFEHAAAAIABRBwAAACAAUQcAAAAgAFEHAAAAIABRBwAAACA\nAUQcAAAAgAFEHAAAAIABRBwAAACAAUQcAAAAgAFEHAAAAIABRBwAAACAAUQcAAAAgAFEHAAAAIAB\nRBwAAACAAUQcAAAAgAFEHAAAAIABRBwAAACAAUQcAAAAgAFEHAAAAIABRBwAAACAAUQcAAAAgAFE\nHAAAAIABRBwAAACAAUQcAAAAgAFEHAAAAIABRBwAAACAAUQcAAAAgAFEHAAAAIABRBwAAACAAUQc\nAAAAgAFEHAAAAIABRBwAAACAAUQcAAAAgAE2jDhVdWVVPVhVd6yNHVNVH66qzyx/j15bd1FVba+q\nu6vqjLXxU6vq9mXdpVVVW385AAAAAIemzdyJ84EkZ+42dmGSm7r7pCQ3Ld9TVScnOSfJKcs+76uq\nw5Z9LktyXpKTls/ucwIAAADwNDaMON39sSQP7TZ8VpKrluWrkpy9Nn5Ndz/R3fck2Z7k9Ko6LsmL\nu/vj3d1Jrl7bBwAAAIAN7Os7cY7t7vuW5fuTHLssb0ty79p2O5axbcvy7uMAAAAAbMLh+ztBd3dV\n9VaczC5VdX6S87dyTgAAAIDJ9vVOnAeWR6Sy/H1wGd+Z5IS17Y5fxnYuy7uP71F3X9Hdp3X3aft4\nfgAAAACHlH2NONcnOXdZPjfJdWvj51TVEVV1YlYvML55efTq0ap6zfKrVG9Z2wcAAACADWz4OFVV\nfTDJ65K8tKp2JPmpJBcnubaq3prk80nelCTdfWdVXZvkriRPJnl7dz+1TPVDWf3S1QuT3Lh8AAAA\nANiEWv1Y1MFrq9+3AwAAAHCw6e7aaJt9fZwKAAAAgANIxAEAAAAYQMQBAAAAGEDEAQAAABhAxAEA\nAAAYQMQBAAAAGEDEAQAAABhAxAEAAAAYQMQBAAAAGEDEAQAAABhAxAEAAAAYQMQBAAAAGEDEAQAA\nABhAxAEAAAAYQMQBAAAAGEDEAQAAABhAxAEAAAAYQMQBAAAAGEDEAQAAABhAxAEAAAAYQMQBAAAA\nGEDEAQAAABhAxAEAAAAYQMQBAAAAGEDEAQAAABhAxAEAAAAYQMQBAAAAGEDEAQAAABhAxAEAAAAY\nQMQBAAAAGEDEAQAAABhAxAEAAAAYQMQBAAAAGEDEAQAAABhAxAEAAAAYQMQBAAAAGEDEAQAAABhA\nxAEAAAAYQMQBAAAAGEDEAQAAABhAxAEAAAAYQMQBAAAAGEDEAQAAABhAxAEAAAAYQMQBAAAAGEDE\nAQAAABhAxAEAAAAYQMQBAAAAGEDEAQAAABhAxAEAAAAYQMQBAAAAGEDEAQAAABhAxAEAAAAYQMQB\nAAAAGEDEAQAAABhAxAEAAAAYQMQBAAAAGEDEAQAAABhAxAEAAAAYQMQBAAAAGEDEAQAAABhAxAEA\nAAAYQMQBAAAAGEDEAQAAABhAxAEAAAAYQMQBAAAAGEDEAQAAABhAxAEAAAAYQMQBAAAAGEDEAQAA\nABhAxAEAAAAYQMQBAAAAGEDEAQAAABhAxAEAAAAYQMQBAAAAGEDEAQAAABhAxAEAAAAYQMQBAAAA\nGEDEAQAAABhAxAEAAAAYQMQBAAAAGEDEAQAAABhAxAEAAAAYQMQBAAAAGEDEAQAAABhAxAEAAAAY\nQMQBAAAAGEDEAQAAABhAxAEAAAAYQMQBAAAAGEDEAQAAABhAxAEAAAAYQMQBAAAAGEDEAQAAABhA\nxAEAAAAYQMQBAAAAGEDEAQAAABhAxAEAAAAYQMQBAAAAGEDEAQAAABhAxAEAAAAYQMQBAAAAGEDE\nAQAAABhAxAEAAAAYQMQBAAAAGEDEAQAAABhAxAEAAAAYQMQBAAAAGEDEAQAAABhAxAEAAAAYQMQB\nAAAAGEDEAQAAABhAxAEAAAAYQMQBAAAAGEDEAQAAABhAxAEAAAAYQMQBAAAAGEDEAQAAABhAxAEA\nAAAYQMQBAAAAGEDEAQAAABhAxAEAAAAYQMQBAAAAGEDEAQAAABhAxAEAAAAYQMQBAAAAGEDEAQAA\nABhAxAEAAAAYQMQBAAAAGEDEAQAAABhAxAEAAAAYQMQBAAAAGGDDiFNVV1bVg1V1x9rYu6tqZ1V9\n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\ncQAAAAAGEHEAAAAABhBxAAAAAAYQcQAAAAAGEHEAAAAABhBxAAAAAAYQcQAAAAAGEHEAAAAABhBx\nAAAAAAYQcQAAAAAGEHEAAAAABhBxAAAAAAYQcQAAAAAGEHEAAAAABhBxAAAAAAYQcQAAAAAGEHEA\nAAAABhBxAAAAAAYQcQAAAAAGEHEAAAAABhBxAAAAAAYQcQAAAAAGEHEAAAAABhBxAAAAAAYQcQAA\nAAAGEHEAAAAABhBxAAAAAAYQcQAAAAAGEHEAAAAABhBxAAAAAAYQcQAAAAAGEHEAAAAABhBxAAAA\nAAYQcQAAAAAGEHEAAAAABhBxAAAAAAYQcQAAAAAGEHEAAAAABhBxAAAAAAYQcQAAAAAGEHEAAAAA\nBhBxAAAAAAYQcQAAAAAGEHEAAAAABhBxAAAAAAYQcQAAAAAGEHEAAAAABhBxAAAAAAYQcQAAAAAG\nEHEAAAAABhBxAAAAAAYQcQAAAAAGEHEAAAAABhBxAAAAAAYQcQAAAAAGEHEAAAAABhBxAAAAAAYQ\ncQAAAAAGEHEAAAAABhBxAAAAAAYQcQAAAAAGEHEAAAAABhBxAAAAAAYQcQAAAAAGEHEAAAAABhBx\nAAAAAAYQcQAAAAAGEHEAAAAABhBxAAAAAAYQcQAAAAAGEHEAAAAABhBxAAAAAAYQcQAAAAAGEHEA\nAAAABhBxAAAAAAYQcQAAAAAGEHEAAAAABhBxAAAAAAYQcQAAAAAGEHEAAAAABhBxAAAAAAYQcQAA\nAAAGEHEAAAAABhBxAAAAAAYQcQAAAAAGEHEAAAAABhBxAAAAAAYQcQAAAAAGEHEAAAAABhBxAAAA\nAAYQcQAAAAAGEHEAAAAABhBxAAAAAAYQcQAAAAAGEHEAAAAABhBxAAAAAAYQcQAAAAAGEHEAAAAA\nBhBxAAAAAAYQcQAAAAAGEHEAAAAABhBxAAAAAAYQcQAAAAAGEHEAAAAABhBxAAAAAAYQcQAAAAAG\nEHEAAAAABhBxAAAAAAYQcQAAAAAGEHEAAAAABhBxAAAAAAYQcQAAAAAGEHEAAAAABhBxAAAAAAYQ\ncQAAAAAGEHEAAAAABhBxAAAAAAYQcQAAAAAGEHEAAAAABhBxAAAAAAYQcQAAAAAGEHEAAAAABhBx\nAAAAAAYQcQAAAAAGEHEAAAAABhBxAAAAAAYQcQAAAAAG2DDiVNUJVfXRqrqrqu6sqh9dxt9dVTur\n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\n3Ue7++h2jg8AAABgr9rK1aneVFWvW7b3J3l3kh8leSDJ7cvDbk9y/7L9QJJbq+q6qroxqxMYn1o+\nevVcVR1brkp125rnAAAAAHAZ12zhMQeSnFiuMPWqJCe7+5tV9Z0kJ6vqT5P8NMkHkqS7z1TVySRP\nJnkxyZ3dfXF5rTuS3Jtkf5IHlxsAAAAAm6jV6Wx2r6ra3QcIAAAA8P/U3bXZY7Z1ThwAAAAAdoaI\nAwAAADCAiAMAAAAwgIgDAAAAMICIAwAAADCAiAMAAAAwgIgDAAAAMICIAwAAADCAiAMAAAAwgIgD\nAAAAMICIAwAAADCAiAMAAAAwgIgDAAAAMICIAwAAADCAiAMAAAAwgIgDAAAAMICIAwAAADCAiAMA\nAAAwgIgDAAAAMICIAwAAADCAiAMAAAAwgIgDAAAAMICIAwAAADCAiAMAAAAwgIgDAAAAMICIAwAA\nADCAiAMAAAAwgIgDAAAAMICIAwAAADCAiAMAAAAwgIgDAAAAMICIAwAAADCAiAMAAAAwgIgDAAAA\nMICIAwAAADCAiAMAAAAwgIgDAAAAMICIAwAAADCAiAMAAAAwgIgDAAAAMICIAwAAADCAiAMAAAAw\ngIgDAAAAMICIAwAAADCAiAMAAAAwgIgDAAAAMICIAwAAADCAiAMAAAAwgIgDAAAAMICIAwAAADCA\niAMAAAAwgIgDAAAAMICIAwAAADCAiAMAAAAwgIgDAAAAMICIAwAAADCAiAMAAAAwgIgDAAAAMICI\nAwAAADCAiAMAAAAwgIgDAAAAMICIAwAAADCAiAMAAAAwgIgDAAAAMICIAwAAADCAiAMAAAAwgIgD\nAAAAMICIAwAAADCAiAMAAAAwgIgDAAAAMICIAwAAADCAiAMAAAAwgIgDAAAAMICIAwAAADCAiAMA\nAAAwgIgDAAAAMICIAwAAADCAiAMAAAAwgIgDAAAAMICIAwAAADCAiAMAAAAwgIgDAAAAMICIAwAA\nADCAiAMAAAAwgIgDAAAAMICIAwAAADCAiAMAAAAwgIgDAAAAMICIAwAAADCAiAMAAAAwgIgDAAAA\nMICIAwAAADCAiAMAAAAwgIgDAAAAMICIAwAAADCAiAMAAAAwgIgDAAAAMICIAwAAADCAiAMAAAAw\ngIgDAAAAMICIAwAAADCAiAMAAAAwgIgDAAAAMICIAwAAADCAiAMAAAAwgIgDAAAAMICIAwAAADCA\n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\nAf4HTHpVlIEy/GQAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7fbfe876f7b8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "m = complete_test_image.shape[0] / (tile_size[0] + 2)\n",
    "n = int(np.ceil(m / 20.0))\n",
    "for i in range(n):\n",
    "    plt_st(20, 20)\n",
    "    ys = i*(tile_size[0] + 2)*20\n",
    "    ye = min((i+1)*(tile_size[0] + 2)*20, complete_test_image.shape[0])\n",
    "    plt.imshow(complete_test_image[ys:ye,:,:])\n",
    "    plt.title(\"Test dataset, part %i\" % (i))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "_cell_guid": "ae360dea-8473-72e5-bf15-34f98168802f"
   },
   "source": [
    "## Display 500 addtional train images of Type_1, Type_2, Type_3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "_cell_guid": "a9a627cd-f77d-992e-ceef-6fbfa06150cb"
   },
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'get_image_data' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-14-fbc72bdb0f00>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m     17\u001b[0m                 \u001b[0;32mbreak\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     18\u001b[0m             \u001b[0mimage_id\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtrain_ids\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mcounter\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m;\u001b[0m \u001b[0mcounter\u001b[0m\u001b[0;34m+=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 19\u001b[0;31m             \u001b[0mimg\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_image_data\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mimage_id\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'AType_%i'\u001b[0m \u001b[0;34m%\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mk\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     20\u001b[0m             \u001b[0mimg\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcv2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mresize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mimg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdsize\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtile_size\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     21\u001b[0m             \u001b[0mimg\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcv2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mputText\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mimg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mimage_id\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mimg\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0;36m5\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcv2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mFONT_HERSHEY_SIMPLEX\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2.0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;36m255\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m255\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m255\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mthickness\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mNameError\u001b[0m: name 'get_image_data' is not defined"
     ]
    }
   ],
   "source": [
    "tile_size = (256, 256)\n",
    "n = 15\n",
    "ll = 500\n",
    "complete_images = []\n",
    "for k, type_ids in enumerate([additional_type_1_ids[:ll], additional_type_2_ids[:ll], additional_type_3_ids[:ll]]):\n",
    "    m = int(np.ceil(len(type_ids) * 1.0 / n))\n",
    "    complete_image = np.zeros((m*(tile_size[0]+2), n*(tile_size[1]+2), 3), dtype=np.uint8)\n",
    "    train_ids = sorted(type_ids)\n",
    "    counter = 0\n",
    "    for i in range(m):\n",
    "        ys = i*(tile_size[1] + 2)\n",
    "        ye = ys + tile_size[1]\n",
    "        for j in range(n):\n",
    "            xs = j*(tile_size[0] + 2)\n",
    "            xe = xs + tile_size[0]\n",
    "            if counter == len(train_ids):\n",
    "                break\n",
    "            image_id = train_ids[counter]; counter+=1\n",
    "            img = get_image_data(image_id, 'AType_%i' % (k+1))\n",
    "            img = cv2.resize(img, dsize=tile_size)\n",
    "            img = cv2.putText(img, image_id, (5,img.shape[0] - 5), cv2.FONT_HERSHEY_SIMPLEX, 2.0, (255, 255, 255), thickness=3)\n",
    "            complete_image[ys:ye, xs:xe, :] = img[:,:,:]\n",
    "        if counter == len(train_ids):\n",
    "            break\n",
    "    complete_images.append(complete_image)       "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "_cell_guid": "be57bd27-2106-7193-8254-dfb6cff4f0bf"
   },
   "outputs": [
    {
     "ename": "IndexError",
     "evalue": "list index out of range",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mIndexError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-15-83932f76b452>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[0mindex\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mm\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcomplete_images\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mindex\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mtile_size\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      3\u001b[0m \u001b[0mn\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mceil\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mm\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0;36m15.0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      4\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      5\u001b[0m     \u001b[0mplt_st\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m20\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m20\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mIndexError\u001b[0m: list index out of range"
     ]
    }
   ],
   "source": [
    "index = 0\n",
    "m = complete_images[index].shape[0] / (tile_size[0] + 2)\n",
    "n = int(np.ceil(m / 15.0))\n",
    "for i in range(n):\n",
    "    plt_st(20, 20)\n",
    "    ys = i*(tile_size[0] + 2)*15\n",
    "    ye = min((i+1)*(tile_size[0] + 2)*15, complete_images[index].shape[0])\n",
    "    plt.imshow(complete_images[index][ys:ye,:,:])\n",
    "    plt.title(\"Additional Training dataset (500 images) of type %i, part %i\" % (index + 1, i))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "_cell_guid": "5155c64b-eabf-725e-3dcb-79877f39ea55"
   },
   "outputs": [
    {
     "ename": "IndexError",
     "evalue": "list index out of range",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mIndexError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-16-f4bf62014695>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[0mindex\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mm\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcomplete_images\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mindex\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mtile_size\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      3\u001b[0m \u001b[0mn\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mceil\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mm\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0;36m15.0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      4\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      5\u001b[0m     \u001b[0mplt_st\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m20\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m20\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mIndexError\u001b[0m: list index out of range"
     ]
    }
   ],
   "source": [
    "index = 1\n",
    "m = complete_images[index].shape[0] / (tile_size[0] + 2)\n",
    "n = int(np.ceil(m / 15.0))\n",
    "for i in range(n):\n",
    "    plt_st(20, 20)\n",
    "    ys = i*(tile_size[0] + 2)*15\n",
    "    ye = min((i+1)*(tile_size[0] + 2)*15, complete_images[index].shape[0])\n",
    "    plt.imshow(complete_images[index][ys:ye,:,:])\n",
    "    plt.title(\"Additional Training dataset (500 images) of type %i, part %i\" % (index + 1, i))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "_cell_guid": "f8059659-22e0-f7af-0ab7-d1286773e0e9"
   },
   "outputs": [
    {
     "ename": "IndexError",
     "evalue": "list index out of range",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mIndexError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-17-3af613e6734a>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[0mindex\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mm\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcomplete_images\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mindex\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mtile_size\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      3\u001b[0m \u001b[0mn\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mceil\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mm\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0;36m15.0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      4\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      5\u001b[0m     \u001b[0mplt_st\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m20\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m20\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mIndexError\u001b[0m: list index out of range"
     ]
    }
   ],
   "source": [
    "index = 2\n",
    "m = complete_images[index].shape[0] / (tile_size[0] + 2)\n",
    "n = int(np.ceil(m / 15.0))\n",
    "for i in range(n):\n",
    "    plt_st(20, 20)\n",
    "    ys = i*(tile_size[0] + 2)*15\n",
    "    ye = min((i+1)*(tile_size[0] + 2)*15, complete_images[index].shape[0])\n",
    "    plt.imshow(complete_images[index][ys:ye,:,:])\n",
    "    plt.title(\"Additional Training dataset (500 images) of type %i, part %i\" % (index + 1, i))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "_cell_guid": "98f68fed-10fd-c499-cb08-52e8b68abb0b"
   },
   "source": [
    "## Basic skin detection"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "_cell_guid": "d954848f-6fd8-e644-6cd9-645b77130495"
   },
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'get_image_data' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-18-00e9e4ae1b3d>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mimg_1\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_image_data\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'1023'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Type_1'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      2\u001b[0m \u001b[0mimg_2\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_image_data\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'531'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Type_1'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      3\u001b[0m \u001b[0mimg_3\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_image_data\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'596'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Type_1'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      4\u001b[0m \u001b[0mimg_4\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_image_data\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'1061'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Type_1'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      5\u001b[0m \u001b[0mimg_5\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_image_data\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'1365'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Type_2'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mNameError\u001b[0m: name 'get_image_data' is not defined"
     ]
    }
   ],
   "source": [
    "img_1 = get_image_data('1023', 'Type_1')\n",
    "img_2 = get_image_data('531', 'Type_1')\n",
    "img_3 = get_image_data('596', 'Type_1')\n",
    "img_4 = get_image_data('1061', 'Type_1')\n",
    "img_5 = get_image_data('1365', 'Type_2')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "_cell_guid": "5e786612-1d1d-9903-ba5e-b2403c285444"
   },
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'img_1' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-19-6d889f1a7638>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m     51\u001b[0m     \u001b[0;32mreturn\u001b[0m \u001b[0mskin_segm_rgb\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     52\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 53\u001b[0;31m \u001b[0;32mfor\u001b[0m \u001b[0mimage\u001b[0m \u001b[0;32min\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mimg_1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mimg_2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mimg_3\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mimg_4\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mimg_5\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     54\u001b[0m     \u001b[0mimage\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcv2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mresize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mimage\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdsize\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m512\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m512\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     55\u001b[0m     \u001b[0mskin_segm_rgb\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdetect_skin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mimage\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mNameError\u001b[0m: name 'img_1' is not defined"
     ]
    }
   ],
   "source": [
    "def sieve(image, size):\n",
    "    \"\"\"\n",
    "    Filter removes small objects of 'size' from binary image\n",
    "    Input image should be a single band image of type np.uint8\n",
    "    Idea : use Opencv findContours\n",
    "    \"\"\"\n",
    "    sqLimit = size**2\n",
    "    linLimit = size*4\n",
    "    outImage = image.copy()\n",
    "    image, contours, hierarchy = cv2.findContours(image.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)\n",
    "    if len(hierarchy) > 0:\n",
    "        hierarchy = hierarchy[0]\n",
    "        index = 0\n",
    "        while index >= 0:\n",
    "            contour = contours[index]\n",
    "            p = cv2.arcLength(contour, True)\n",
    "            s = cv2.contourArea(contour)\n",
    "            r = cv2.boundingRect(contour)\n",
    "            if s <= sqLimit and p <= linLimit:\n",
    "                outImage[r[1]:r[1]+r[3], r[0]:r[0]+r[2]] = 0\n",
    "            index = hierarchy[index][0]\n",
    "    else:\n",
    "        pass\n",
    "        # print(\"No contours found\")\n",
    "    return outImage\n",
    "\n",
    "\n",
    "# in HSV :\n",
    "skin_range_1_min = np.array([120, 0, 0], dtype=np.uint8)\n",
    "skin_range_1_max = np.array([255, 255, 255], dtype=np.uint8)\n",
    "\n",
    "skin_range_2_min = np.array([0, 0, 0], dtype=np.uint8)\n",
    "skin_range_2_max = np.array([45, 255, 255], dtype=np.uint8)\n",
    "\n",
    "skin_kernel_size = 7\n",
    "skin_sieve_min_size = 5\n",
    "\n",
    "def detect_skin(image):\n",
    "    proc = cv2.medianBlur(image, 7)\n",
    "    ### Detect skin\n",
    "    image_hsv = cv2.cvtColor(proc, cv2.COLOR_RGB2HSV)\n",
    "    skin_like_mask = cv2.inRange(image_hsv, skin_range_1_min, skin_range_1_max)\n",
    "    skin_like_mask_2 = cv2.inRange(image_hsv, skin_range_2_min, skin_range_2_max)\n",
    "    skin_like_mask = cv2.bitwise_or(skin_like_mask, skin_like_mask_2)    \n",
    "    # Filter the skin mask :\n",
    "    skin_mask = sieve(skin_like_mask, skin_sieve_min_size)\n",
    "    kernel = np.ones((skin_kernel_size, skin_kernel_size), dtype=np.int8)\n",
    "    skin_mask = cv2.morphologyEx(skin_mask, cv2.MORPH_CLOSE, kernel)    \n",
    "    # Apply skin mask\n",
    "    skin_segm_rgb = cv2.bitwise_and(image, image, mask=skin_mask)\n",
    "    return skin_segm_rgb\n",
    "\n",
    "for image in [img_1, img_2, img_3, img_4, img_5]:       \n",
    "    image = cv2.resize(image, dsize=(512, 512))\n",
    "    skin_segm_rgb = detect_skin(image)\n",
    "    plt_st(12, 4)\n",
    "    plt.subplot(121)\n",
    "    plt.title(\"Original image\")    \n",
    "    plt.imshow(image)\n",
    "    plt.subplot(122)\n",
    "    plt.title(\"Skin segmentation\")\n",
    "    plt.imshow(skin_segm_rgb)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "_cell_guid": "cda3aa57-8c54-8497-45ba-693874a1251d"
   },
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'get_image_data' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-20-bb86184d36be>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m     15\u001b[0m             \u001b[0mxe\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mxs\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mtile_size\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     16\u001b[0m             \u001b[0mimage_id\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtrain_ids\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mcounter\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m;\u001b[0m \u001b[0mcounter\u001b[0m\u001b[0;34m+=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 17\u001b[0;31m             \u001b[0mimg\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_image_data\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mimage_id\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Type_%i'\u001b[0m \u001b[0;34m%\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mk\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     18\u001b[0m             \u001b[0mimg\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcv2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mresize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mimg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdsize\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtile_size\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     19\u001b[0m             \u001b[0mimg\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdetect_skin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mimg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mNameError\u001b[0m: name 'get_image_data' is not defined"
     ]
    }
   ],
   "source": [
    "tile_size = (256, 256)\n",
    "n = 15\n",
    "\n",
    "complete_images = []\n",
    "for k, type_ids in enumerate([type_1_ids, ]):\n",
    "    m = int(np.floor(len(type_ids) / n))\n",
    "    complete_image = np.zeros((m*(tile_size[0]+2), n*(tile_size[1]+2), 3), dtype=np.uint8)\n",
    "    train_ids = sorted(type_ids)\n",
    "    counter = 0\n",
    "    for i in range(m):\n",
    "        ys = i*(tile_size[1] + 2)\n",
    "        ye = ys + tile_size[1]\n",
    "        for j in range(n):\n",
    "            xs = j*(tile_size[0] + 2)\n",
    "            xe = xs + tile_size[0]\n",
    "            image_id = train_ids[counter]; counter+=1\n",
    "            img = get_image_data(image_id, 'Type_%i' % (k+1))\n",
    "            img = cv2.resize(img, dsize=tile_size)\n",
    "            img = detect_skin(img)\n",
    "            img = cv2.putText(img, image_id, (5,img.shape[0] - 5), cv2.FONT_HERSHEY_SIMPLEX, 2.0, (255, 255, 255), thickness=3)\n",
    "            complete_image[ys:ye, xs:xe, :] = img[:,:,:]\n",
    "    complete_images.append(complete_image)    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "_cell_guid": "b429d2b1-99b2-1fbf-b2a8-5448ae524c5a"
   },
   "source": [
    "### Apply skin segmentation on all training data and visualize the result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "_cell_guid": "d0d6ed51-b54f-9599-3d1f-9b9cb3d6fa5d"
   },
   "outputs": [
    {
     "ename": "IndexError",
     "evalue": "list index out of range",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mIndexError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-21-379aead571f4>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[0mplt_st\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m20\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m20\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mimshow\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcomplete_images\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      3\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtitle\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Training dataset of type %i\"\u001b[0m \u001b[0;34m%\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mIndexError\u001b[0m: list index out of range"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7fbff1e2fba8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt_st(20, 20)\n",
    "plt.imshow(complete_images[0])\n",
    "plt.title(\"Training dataset of type %i\" % (0))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "_cell_guid": "71ebc9c0-0f9b-d9f7-8ea3-4cbab409f253"
   },
   "source": [
    "## Clustering\n",
    "\n",
    "- Take a number of images from all classified images and test images\n",
    "- Compute histogram on hue channel\n",
    "- Perform 5 classes clustering on the data "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "_cell_guid": "36027043-6945-bf2b-2bdc-ac24d79d9143"
   },
   "outputs": [],
   "source": [
    "def compute_histogram(img, hist_size=100):\n",
    "    hist = cv2.calcHist([img], [0], mask=None, histSize=[hist_size], ranges=(0, 255))\n",
    "    hist = cv2.normalize(hist, dst=hist)\n",
    "    return hist\n",
    "\n",
    "#for image in [img_1, img_2, img_3, img_4, img_5]:       \n",
    "#    image = cv2.resize(image, dsize=(512, 512))    \n",
    "#    hue = cv2.cvtColor(image, cv2.COLOR_RGB2HSV)[:,:,0]\n",
    "#    hist = compute_histogram(hue)\n",
    "#    plt_st(12, 4)\n",
    "#    plt.subplot(131)\n",
    "#    plt.title(\"Original image\")    \n",
    "#    plt.imshow(image)\n",
    "#    plt.subplot(132)\n",
    "#    plt.title(\"Hue\")    \n",
    "#    plt.imshow(hue, cmap='gray')\n",
    "#    plt.subplot(133)\n",
    "#    plt.title(\"Histogram\")\n",
    "#    plt.plot(hist)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "_cell_guid": "7fed17f0-6c5a-f607-3cb0-1c419d90c673"
   },
   "outputs": [],
   "source": [
    "train_nb_samples = 100\n",
    "type_ids=(type_1_ids, type_2_ids, type_3_ids, test_ids)\n",
    "image_types = [\"Type_1\", \"Type_2\", \"Type_3\", \"Test\"]\n",
    "ll = [int(len(ids)) for ids in type_ids]\n",
    "\n",
    "count = 0\n",
    "train_id_type_list = []\n",
    "while count < train_nb_samples:\n",
    "    for l, ids, image_type in zip(ll, type_ids, image_types):\n",
    "        image_id = ids[count % l]\n",
    "        train_id_type_list.append((image_id, image_type))\n",
    "    count += 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "_cell_guid": "b1a19394-f2c0-1490-6d87-6d6e6093ef02"
   },
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'get_image_data' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-24-aab1b40149a5>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      4\u001b[0m \u001b[0mY\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mzeros\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtrain_id_type_list\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfloat32\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      5\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mimage_id\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mimage_type\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32min\u001b[0m \u001b[0menumerate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtrain_id_type_list\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m     \u001b[0mimg\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_image_data\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mimage_id\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mimage_type\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      7\u001b[0m     \u001b[0mimg\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcv2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mresize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mimg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdsize\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mimage_size\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      8\u001b[0m     \u001b[0mhue\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcv2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcvtColor\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mimg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcv2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mCOLOR_RGB2HSV\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mNameError\u001b[0m: name 'get_image_data' is not defined"
     ]
    }
   ],
   "source": [
    "image_size = (256, 256)\n",
    "hist_size = 100\n",
    "X = np.zeros((len(train_id_type_list), hist_size), dtype=np.float32)\n",
    "Y = np.zeros((len(train_id_type_list), 2), dtype=np.float32)\n",
    "for i, (image_id, image_type) in enumerate(train_id_type_list):\n",
    "    img = get_image_data(image_id, image_type)\n",
    "    img = cv2.resize(img, dsize=image_size[::-1])\n",
    "    hue = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)[:,:,0]\n",
    "    hist = compute_histogram(hue, hist_size)    \n",
    "    X[i, :] = hist[:, 0]\n",
    "    Y[i, :] = (hist.mean(), hist.std())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "_cell_guid": "648bc088-0473-d86d-62ff-b888da52b828"
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\nxcCQJPXy/wHBsL2azzkMOwAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7fbff1e48eb8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.title(\"Image Hue Histogram std vs mean\")\n",
    "plt.scatter(Y[:, 0], Y[:, 1], s=50, cmap='viridis');"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "_cell_guid": "4a8d6762-0d93-fa88-1f6e-8a2f56a257a7"
   },
   "outputs": [],
   "source": [
    "np_classes = 5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "_cell_guid": "93a8db25-4de8-cf3a-fb72-9090428d1424"
   },
   "outputs": [],
   "source": [
    "#from sklearn.cluster import KMeans\n",
    "#kmeans = KMeans(n_clusters=np_classes)\n",
    "#kmeans.fit(X)\n",
    "#y_kmeans = kmeans.predict(X)\n",
    "#_ = plt.hist(y_kmeans)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "_cell_guid": "45d399a3-37af-e5d1-6a5c-4c4aa53b0f26"
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\nAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7fbfcc882a58>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from sklearn.cluster import SpectralClustering\n",
    "model = SpectralClustering(n_clusters=np_classes, affinity='nearest_neighbors', assign_labels='kmeans')\n",
    "y_spectral = model.fit_predict(X)\n",
    "_ = plt.hist(y_spectral)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "_cell_guid": "4542dc9e-c7b1-a8a2-894d-456e617721fd"
   },
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'get_image_data' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-29-95a324431743>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m     18\u001b[0m                 \u001b[0;32mbreak\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     19\u001b[0m             \u001b[0mimage_id\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mimage_type\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtrain_id_type_list\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mclass_indices\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mcounter\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m;\u001b[0m \u001b[0mcounter\u001b[0m\u001b[0;34m+=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 20\u001b[0;31m             \u001b[0mimg\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_image_data\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mimage_id\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mimage_type\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     21\u001b[0m             \u001b[0mimg\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcv2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mresize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mimg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdsize\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mimage_size\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     22\u001b[0m             \u001b[0mimg\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcv2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mputText\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mimg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mimage_id\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m' | '\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mimage_type\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m' | '\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mclass_index\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mimg\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0;36m5\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcv2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mFONT_HERSHEY_SIMPLEX\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1.0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;36m255\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m255\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m255\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mthickness\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mNameError\u001b[0m: name 'get_image_data' is not defined"
     ]
    }
   ],
   "source": [
    "image_size = (256, 256)\n",
    "all_classes_images = []\n",
    "for class_index in range(np_classes):\n",
    "    \n",
    "    class_indices = np.where(y_spectral == class_index)[0]\n",
    "    n = 10    \n",
    "    m = int(np.ceil(len(class_indices) / n)) \n",
    "    one_class_image = np.zeros((m*(image_size[0]+2), n*(image_size[1]+2), 3), dtype=np.uint8)    \n",
    "    \n",
    "    counter = 0\n",
    "    for i in range(m):\n",
    "        ys = i*(image_size[1] + 2)\n",
    "        ye = ys + image_size[1]\n",
    "        for j in range(n):\n",
    "            xs = j*(image_size[0] + 2)\n",
    "            xe = xs + image_size[0]\n",
    "            if counter == len(class_indices):\n",
    "                break\n",
    "            image_id, image_type = train_id_type_list[class_indices[counter]]; counter+=1\n",
    "            img = get_image_data(image_id, image_type)\n",
    "            img = cv2.resize(img, dsize=image_size)\n",
    "            img = cv2.putText(img, image_id + ' | ' + str(image_type) + ' | ' + str(class_index), (5,img.shape[0] - 5), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (255, 255, 255), thickness=2)\n",
    "            one_class_image[ys:ye, xs:xe, :] = img[:,:,:]\n",
    "\n",
    "        if counter == len(class_indices):\n",
    "            break\n",
    "    \n",
    "    all_classes_images.append(one_class_image)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "_cell_guid": "45ec1f8f-8be6-65a7-adc4-991f33930e16"
   },
   "outputs": [
    {
     "ename": "IndexError",
     "evalue": "list index out of range",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mIndexError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-30-28b47753d8c7>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mclass_index\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnp_classes\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      2\u001b[0m     \u001b[0mplt_st\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m20\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m20\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m     \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mimshow\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mall_classes_images\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mclass_index\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      4\u001b[0m     \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtitle\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Class %i\"\u001b[0m \u001b[0;34m%\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mclass_index\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mIndexError\u001b[0m: list index out of range"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7fbfc8554208>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "for class_index in range(np_classes):\n",
    "    plt_st(20, 20)\n",
    "    plt.imshow(all_classes_images[class_index])\n",
    "    plt.title(\"Class %i\" % (class_index)) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "_cell_guid": "834ef6ca-a2fd-6273-e004-945124e3835b"
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "_cell_guid": "6a9df9de-92f0-c38c-a3f9-e0c56a4e9ec8"
   },
   "source": [
    "## Some stats using jpg exif\n",
    "\n",
    "We can explore metadata of all these images. If exif metadata is present in images, we can found out camera name, camera type, acquisition date and time etc."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "_cell_guid": "234a1824-f994-b74d-ea27-49d0b617c7e2"
   },
   "outputs": [],
   "source": [
    "from PIL import Image\n",
    "import seaborn as sns\n",
    "\n",
    "def _get_image_data_pil(image_id, image_type, return_exif_md=False):\n",
    "    \"\"\"\n",
    "    Method to get image data as np.array specifying image id and type\n",
    "    \"\"\"\n",
    "    fname = get_filename(image_id, image_type)\n",
    "    try:\n",
    "        img_pil = Image.open(fname)\n",
    "    except Exception as e:\n",
    "        assert False, \"Failed to read image : %s, %s. Error message: %s\" % (image_id, image_type, e)\n",
    "\n",
    "    img = np.asarray(img_pil)\n",
    "    assert isinstance(img, np.ndarray), \"Open image is not an ndarray. Image id/type : %s, %s\" % (image_id, image_type)\n",
    "    if not return_exif_md:\n",
    "        return img\n",
    "    else:\n",
    "        return img, img_pil._getexif()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "_cell_guid": "ca93bb0b-fde1-d4a7-b3ca-2826196df0da"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-- Type_1\n"
     ]
    },
    {
     "ename": "NameError",
     "evalue": "name 'get_filename' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-32-9beefee4774a>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      8\u001b[0m     \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'--'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mimage_type\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      9\u001b[0m     \u001b[0;32mfor\u001b[0m \u001b[0mimage_id\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mids\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 10\u001b[0;31m         \u001b[0mimg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mexif_data\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_get_image_data_pil\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mimage_id\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mimage_type\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mreturn_exif_md\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     11\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mexif_data\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdict\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     12\u001b[0m             exif_stats.loc[counter, :] = [image_id, image_type, \n",
      "\u001b[0;32m<ipython-input-31-55701e756c99>\u001b[0m in \u001b[0;36m_get_image_data_pil\u001b[0;34m(image_id, image_type, return_exif_md)\u001b[0m\n\u001b[1;32m      6\u001b[0m     \u001b[0mMethod\u001b[0m \u001b[0mto\u001b[0m \u001b[0mget\u001b[0m \u001b[0mimage\u001b[0m \u001b[0mdata\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marray\u001b[0m \u001b[0mspecifying\u001b[0m \u001b[0mimage\u001b[0m \u001b[0mid\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mtype\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      7\u001b[0m     \"\"\"\n\u001b[0;32m----> 8\u001b[0;31m     \u001b[0mfname\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_filename\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mimage_id\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mimage_type\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      9\u001b[0m     \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     10\u001b[0m         \u001b[0mimg_pil\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mImage\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mopen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfname\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mNameError\u001b[0m: name 'get_filename' is not defined"
     ]
    }
   ],
   "source": [
    "exif_stats = pd.DataFrame(columns=['Image_id', 'Image_type', 'Camera_name', 'Camera_type', 'Datetime', 'ISO'])\n",
    "\n",
    "type_ids=(type_1_ids, type_2_ids, type_3_ids, test_ids)\n",
    "image_types = [\"Type_1\", \"Type_2\", \"Type_3\", \"Test\"]\n",
    "\n",
    "counter = 0\n",
    "for ids, image_type in zip(type_ids, image_types):\n",
    "    print('--', image_type)\n",
    "    for image_id in ids:\n",
    "        img, exif_data = _get_image_data_pil(image_id, image_type, return_exif_md=True)\n",
    "        if isinstance(exif_data, dict):\n",
    "            exif_stats.loc[counter, :] = [image_id, image_type, \n",
    "                                          exif_data[271], \n",
    "                                          exif_data[272], \n",
    "                                          exif_data[306],\n",
    "                                          exif_data[34855]] \n",
    "        else:            \n",
    "            exif_stats.loc[counter, :] = [image_id, image_type, \n",
    "                                          'NA', \n",
    "                                          'NA', \n",
    "                                          'NA', \n",
    "                                          'NA'] \n",
    "        counter+=1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "_cell_guid": "624db981-469c-d770-8b4b-bf5e9a48d52b"
   },
   "outputs": [],
   "source": [
    "exif_stats['Camera_name'] = exif_stats['Camera_name'].str.lower()\n",
    "exif_stats['YMD'] = exif_stats['Datetime'].apply(lambda x: x[:10])\n",
    "data_mask = exif_stats['Camera_name'] != 'na'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "_cell_guid": "b2fd2952-a7f4-3616-51b0-687a8f85eff2"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Image_id</th>\n",
       "      <th>Image_type</th>\n",
       "      <th>Camera_name</th>\n",
       "      <th>Camera_type</th>\n",
       "      <th>Datetime</th>\n",
       "      <th>ISO</th>\n",
       "      <th>YMD</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "Empty DataFrame\n",
       "Columns: [Image_id, Image_type, Camera_name, Camera_type, Datetime, ISO, YMD]\n",
       "Index: []"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "exif_stats.head(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "_cell_guid": "179f7a1a-2531-c33e-0fc1-becf3c9f96de"
   },
   "outputs": [
    {
     "ename": "ValueError",
     "evalue": "min() arg is an empty sequence",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mValueError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-35-85cf88bc65fa>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0msns\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcountplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mexif_stats\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'Camera_name'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mhue\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'Image_type'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/seaborn/categorical.py\u001b[0m in \u001b[0;36mcountplot\u001b[0;34m(x, y, hue, data, order, hue_order, orient, color, palette, saturation, ax, **kwargs)\u001b[0m\n\u001b[1;32m   3256\u001b[0m                           \u001b[0mestimator\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mci\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn_boot\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0munits\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   3257\u001b[0m                           \u001b[0morient\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcolor\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpalette\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msaturation\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3258\u001b[0;31m                           errcolor)\n\u001b[0m\u001b[1;32m   3259\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   3260\u001b[0m     \u001b[0mplotter\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalue_label\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"count\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/seaborn/categorical.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, x, y, hue, data, order, hue_order, estimator, ci, n_boot, units, orient, color, palette, saturation, errcolor, errwidth, capsize)\u001b[0m\n\u001b[1;32m   1542\u001b[0m         self.establish_variables(x, y, hue, data, orient,\n\u001b[1;32m   1543\u001b[0m                                  order, hue_order, units)\n\u001b[0;32m-> 1544\u001b[0;31m         \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mestablish_colors\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcolor\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpalette\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msaturation\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   1545\u001b[0m         \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mestimate_statistic\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mestimator\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mci\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn_boot\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1546\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/seaborn/categorical.py\u001b[0m in \u001b[0;36mestablish_colors\u001b[0;34m(self, color, palette, saturation)\u001b[0m\n\u001b[1;32m    304\u001b[0m         \u001b[0;31m# Determine the gray color to use for the lines framing the plot\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    305\u001b[0m         \u001b[0mlight_vals\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mcolorsys\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrgb_to_hls\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mc\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrgb_colors\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 306\u001b[0;31m         \u001b[0ml\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlight_vals\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0;36m.6\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    307\u001b[0m         \u001b[0mgray\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmpl\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcolors\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrgb2hex\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ml\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ml\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ml\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    308\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mValueError\u001b[0m: min() arg is an empty sequence"
     ]
    }
   ],
   "source": [
    "sns.countplot(data=exif_stats, x='Camera_name', hue='Image_type')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "_cell_guid": "fb56802a-5d1b-57fc-18c0-a2c93ecb5969"
   },
   "outputs": [
    {
     "ename": "ValueError",
     "evalue": "min() arg is an empty sequence",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mValueError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-36-51d06c5b35e8>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[0mplt_st\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m12\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m12\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0msns\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcountplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mexif_stats\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mdata_mask\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msort_values\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'YMD'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'YMD'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/seaborn/categorical.py\u001b[0m in \u001b[0;36mcountplot\u001b[0;34m(x, y, hue, data, order, hue_order, orient, color, palette, saturation, ax, **kwargs)\u001b[0m\n\u001b[1;32m   3256\u001b[0m                           \u001b[0mestimator\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mci\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn_boot\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0munits\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   3257\u001b[0m                           \u001b[0morient\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcolor\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpalette\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msaturation\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3258\u001b[0;31m                           errcolor)\n\u001b[0m\u001b[1;32m   3259\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   3260\u001b[0m     \u001b[0mplotter\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalue_label\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"count\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/seaborn/categorical.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, x, y, hue, data, order, hue_order, estimator, ci, n_boot, units, orient, color, palette, saturation, errcolor, errwidth, capsize)\u001b[0m\n\u001b[1;32m   1542\u001b[0m         self.establish_variables(x, y, hue, data, orient,\n\u001b[1;32m   1543\u001b[0m                                  order, hue_order, units)\n\u001b[0;32m-> 1544\u001b[0;31m         \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mestablish_colors\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcolor\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpalette\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msaturation\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   1545\u001b[0m         \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mestimate_statistic\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mestimator\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mci\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn_boot\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1546\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/seaborn/categorical.py\u001b[0m in \u001b[0;36mestablish_colors\u001b[0;34m(self, color, palette, saturation)\u001b[0m\n\u001b[1;32m    304\u001b[0m         \u001b[0;31m# Determine the gray color to use for the lines framing the plot\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    305\u001b[0m         \u001b[0mlight_vals\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mcolorsys\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrgb_to_hls\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mc\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrgb_colors\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 306\u001b[0;31m         \u001b[0ml\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlight_vals\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0;36m.6\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    307\u001b[0m         \u001b[0mgray\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmpl\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcolors\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrgb2hex\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ml\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ml\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ml\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    308\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mValueError\u001b[0m: min() arg is an empty sequence"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7fbfe7e27f28>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt_st(12, 12)\n",
    "sns.countplot(data=exif_stats[data_mask].sort_values(['YMD']), y='YMD')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "_cell_guid": "af181e08-61e8-47a5-5476-dba26b55d237"
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "_cell_guid": "2f0faf70-6b1e-0ce9-0a83-2a5ac14038aa"
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "_cell_guid": "a1079751-d6ef-95a5-7fe1-697fedc2a957"
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "_cell_guid": "059fa343-d05e-ab50-05a5-34d15c8e3024"
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "_change_revision": 56,
  "_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
}
