{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "# Image Processing SS 18 - Assignment - 03\n",
    "\n",
    "### Deadline is 09.5.2018 at 8:00 o'clock\n",
    "\n",
    "Please solve the assignments together with a partner.\n",
    "I will run every notebook. Make sure the code runs through. Select `Kernel` -> `Restart & Run All` to test it.\n",
    "Please strip the output from the cells, either select `Cell` -> `All Output` -> `Clear` or use the `nb_strip_output.py` script / git hook."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# display the plots inside the notebook\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import pylab\n",
    "from urllib.request import urlopen\n",
    "from skimage.data import astronaut\n",
    "from skimage.color import rgb2gray, rgb2hsv, hsv2rgb\n",
    "\n",
    "pylab.rcParams['figure.figsize'] = (12, 12)   # This makes the plot bigger"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "img = astronaut() / 255.\n",
    "img_hsv = rgb2hsv(img)\n",
    "img_gray = rgb2gray(img)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Exercise 1 - Implement a Histogram Mapping - 1 Points"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def norm_cdf(arr):\n",
    "    return arr / arr[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def gamma_mapping(gamma):\n",
    "    \"\"\"\n",
    "    Returns a 1-dimensional numpy array. The value of the array at the n-position \n",
    "    is `(n/len(array))**gamma`.\n",
    "    \"\"\"\n",
    "    return norm_cdf(np.linspace(0, 1, 255)**gamma)\n",
    "\n",
    "\n",
    "def sigmoid_mapping(gain = 10, cutoff = 0.5):\n",
    "    \"\"\"\n",
    "    Returns a 1-dimensional numpy array. The value of the array at the n-position \n",
    "    is  `1/(1 + exp*(gain*(cutoff - (n/len(array)))))`.\n",
    "    \"\"\"\n",
    "    # your code here\n",
    "    return np.zeros(255)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "plt.plot(gamma_mapping(1.2))\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Exercise 2 - Histogram Transformation - 2 Points"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def apply_pixel_mapping(image, mapping):\n",
    "    \"\"\"Returns the image transformed according to the mapping array. \n",
    "       `mapping` is a one dimensional numpy array. `image` can be 2 or 3-dimensional.\n",
    "       The values of the image are in range 0 to 1. \n",
    "       If the mapping has for example 255 items, then all pixel with a value from 0 to 1/255 are assigned to \n",
    "       the value mapping[0]. If the pixel is between n / 255 and (n+1) / 255 then the value in the output image should \n",
    "       be mapping[n]\n",
    "    \"\"\"\n",
    "    # your code\n",
    "    return np.zeros_like(image)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# you can test your `apply_pixel_mapping` function\n",
    "# The first image should look lighter. The second and thrid should be the same image.\n",
    "img_gamma05 = apply_pixel_mapping(img, gamma_mapping(0.5))\n",
    "plt.subplot(131)\n",
    "plt.imshow(img_gamma05, cmap='gray')\n",
    "plt.subplot(132)\n",
    "plt.imshow(apply_pixel_mapping(img_gamma05, gamma_mapping(2)), cmap='gray')\n",
    "plt.subplot(133)\n",
    "plt.imshow(img, cmap='gray')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Exercise 3 - Implement Histogram Equalisation - 2 Points\n",
    "\n",
    "Equalise the image given image so that the histogram is mostly unifrom distributed.\n",
    "You can use `np.histogram` and `np.cumsum`. Checkout the documentation of `np.histogram`, it might has usefull optional arguments."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "f = urlopen(\"https://dl.dropboxusercontent.com/s/ahj4nff6ba8b8sg/lok.jpg?dl=0\")\n",
    "train = rgb2gray(plt.imread(f, format='jpeg'))\n",
    "plt.imshow(train, cmap='gray')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "hist = np.zeros(255) # get the histogramm of the image\n",
    "equalisation_mapping = np.zeros(255)  # callculate the right mapping"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "img_equalised = apply_pixel_mapping(train, equalisation_mapping)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "hist_of_equalised = np.zeros(255) # get the histogramm of the equalised image"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.subplot(131)\n",
    "plt.plot(hist.cumsum())\n",
    "plt.subplot(132)\n",
    "plt.plot(equalisation_mapping)\n",
    "plt.subplot(133)\n",
    "plt.plot(hist_of_equalised.cumsum())\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.subplot(121)\n",
    "plt.imshow(img_equalised, cmap='gray')\n",
    "plt.subplot(122)\n",
    "plt.imshow(train, cmap='gray')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Exercise 4 - Implement a hipster filter - 2 Points\n",
    "\n",
    "1. Convert the image to HSV \n",
    "1. Transform the V-Channel with `sigmoid_mapping` and gain = 10.\n",
    "1. Transform the S-Channel with `sigmoid_mapping` and gain = 10, cufoff=0.35\n",
    "1. Convert it back to RGB and add the color hsv(0.05, 1, 1) weighted by $0.5\\cdot(1 - V)$ to the image, where V is the resulting V-Channel from step 2.\n",
    "\n",
    "You can test the code with your own image or the `astronaut()` test image.\n",
    "If you choose a custom image, you can included it through the `urllib` library as done with the lok image.\n",
    "You can use the `rgb2hsv` and `hsv2rgb` functions from the skimage library."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "img2 = np.zeros_like(img)\n",
    "plt.imshow(hsv2rgb(img2))     # show the result from step 2\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "img3 = np.zeros_like(img2)\n",
    "plt.imshow(hsv2rgb(img3))     # show the result from step 3\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "img4 = np.zeros_like(img3)\n",
    "plt.imshow(hsv2rgb(img4))      # show the result from step 4\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# plot the original image\n",
    "plt.imshow(img)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Exercise 5 - Implement your own hipster filter - 3 Points\n",
    "\n",
    "You have mostly complete artistic freedom in this exercise. \n",
    "The filter should not be trivial. Converting the image only to grayscale is not enough ;) \n",
    "You should show off your knowledge of histogramm transformations. (Use at least 2 histogramm transformations)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# your code"
   ]
  }
 ],
 "metadata": {
  "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.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
