{"metadata": {"language_info": {"version": "3.6.4", "pygments_lexer": "ipython3", "codemirror_mode": {"version": 3, "name": "ipython"}, "mimetype": "text/x-python", "name": "python", "file_extension": ".py", "nbconvert_exporter": "python"}, "kernelspec": {"language": "python", "name": "python3", "display_name": "Python 3"}}, "cells": [{"metadata": {}, "source": ["In this notebook we fit an ellipise to each cell in orther to see if can be usefull for analysis."], "cell_type": "markdown"}, {"metadata": {"collapsed": true}, "outputs": [], "execution_count": null, "source": ["import numpy as np\n", "import pandas as pd\n", "import random\n", "import skimage.io\n", "import matplotlib.pyplot as plt\n", "import os\n", "from skimage import morphology\n", "import cv2\n", "from tqdm import tqdm\n", "import seaborn as sns\n", "\n", "%matplotlib inline"], "cell_type": "code"}, {"metadata": {"collapsed": true}, "outputs": [], "execution_count": null, "source": ["img_ids = os.listdir(\"../input/stage1_train/\")"], "cell_type": "code"}, {"metadata": {}, "outputs": [], "execution_count": null, "source": ["# This will [safelly] find the parameters of fitted ellipse\n", "def find_ellipse(mask):\n", "    try:\n", "        ret, thresh = cv2.threshold(mask, 127, 255, 0)\n", "        _, contours, hierarchy = cv2.findContours(thresh, 1, 2)\n", "        cnt = contours[0]\n", "        \n", "        ellipse = cv2.fitEllipse(cnt)\n", "    except:\n", "        ellipse = (1, 1), (1, 1), 1\n", "    \n", "    return ellipse"], "cell_type": "code"}, {"metadata": {}, "outputs": [], "execution_count": null, "source": ["# This will analyse the fitted ellipsis of an image\n", "def ellipse_analysis(image_id):\n", "    # Read files\n", "    image_file = \"../input/stage1_train/{}/images/{}.png\".format(image_id,image_id)\n", "    mask_file = \"../input/stage1_train/{}/masks/*.png\".format(image_id)\n", "    \n", "    image = cv2.cvtColor(cv2.imread(image_file), cv2.COLOR_BGR2RGB)\n", "    masks = skimage.io.imread_collection(mask_file).concatenate()\n", "    \n", "    # Find mask ellipsis\n", "    ellipsis = list(map(find_ellipse, masks))\n", "    \n", "    # Find width and height (second parameter)\n", "    ellipse_wh = lambda e: e[1]\n", "    ellipsis_wh = np.array(list(map(ellipse_wh, ellipsis)))\n", "    \n", "    # Calculate rate of each ellipisis\n", "    rates = ellipsis_wh.min(axis=1)/ellipsis_wh.max(axis=1)\n", "    \n", "    # Calculate mean RGB of image\n", "    img_mean_rgb = image.mean(axis=(0, 1))\n", "    \n", "    return rates.mean(), rates.std(), len(ellipsis), img_mean_rgb[0], img_mean_rgb[1], img_mean_rgb[2]"], "cell_type": "code"}, {"metadata": {}, "outputs": [], "execution_count": null, "source": ["# Dataframe for results (columns must sync with ellipse_analysis return)\n", "df_results = pd.DataFrame(index=img_ids, dtype=np.float,\n", "                          columns=[\"ellipsis_ratio_mean\", \"ellipsis_ratio_std\",\n", "                                   \"n_ellipsis\", \"image_mean_red\", \"image_mean_green\",\n", "                                   \"image_mean_blue\"])\n", "# Start analysis\n", "for image_id in tqdm(img_ids):\n", "    df_results.loc[image_id] = ellipse_analysis(image_id)"], "cell_type": "code"}, {"metadata": {}, "outputs": [], "execution_count": null, "source": ["# Plot results, with color being the average color of images\n", "fig, ax = plt.subplots(figsize=(10, 10))\n", "df_results.plot(kind=\"scatter\", x=\"ellipsis_ratio_mean\", y=\"ellipsis_ratio_std\", ax=ax, s=50, edgecolor='gray', lw = 1,\n", "        c=df_results[[\"image_mean_red\", \"image_mean_green\", \"image_mean_blue\"]].values / 255);"], "cell_type": "code"}, {"metadata": {}, "source": ["## Remarks\n", "\n", "* There is a small trend for black-and-white images to have more circular shape;\n", "* Someone can use the ellipisis ratio mean and std as new target for a regression and see if it helps in training the model."], "cell_type": "markdown"}], "nbformat": 4, "nbformat_minor": 1}