{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Filtreler\n",
    "\n",
    "![alt text](assets/4-1.png)\n",
    "\n",
    "[resim kaynağı](https://docs.gimp.org/en/images/filters/examples/convolution-calculate.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-22T09:25:49.938704Z",
     "start_time": "2019-08-22T09:25:49.235218Z"
    }
   },
   "outputs": [],
   "source": [
    "from PIL import Image\n",
    "from matplotlib.pyplot import imshow\n",
    "import numpy as np\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-22T09:25:50.186495Z",
     "start_time": "2019-08-22T09:25:49.942483Z"
    }
   },
   "outputs": [],
   "source": [
    "img_noisy = Image.open(\"images/noisy_test.jpg\")\n",
    "imshow(img_noisy)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Median(Ortanca Değer) Filtresi\n",
    "\n",
    "![alt text](assets/5-median_filter.gif)\n",
    "\n",
    "### Tuz-buz gürültüsünden temizleme\n",
    "Bir pencere boyutu belirlenir ve resim üzerinde gezdirilen pencere içerisindeki piksel değerleri sıralanarak ortadaki değer alınır."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-22T09:25:51.741249Z",
     "start_time": "2019-08-22T09:25:51.738695Z"
    }
   },
   "outputs": [],
   "source": [
    "img_noisy_array = np.array(img_noisy)\n",
    "new_img_array = np.array(img_noisy)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3x3 Filtre"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-22T09:25:54.202873Z",
     "start_time": "2019-08-22T09:25:54.200374Z"
    }
   },
   "outputs": [],
   "source": [
    "def getMedian(li):\n",
    "    li.sort()\n",
    "    return li[int(len(li)/2)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-22T09:25:55.727097Z",
     "start_time": "2019-08-22T09:25:55.227480Z"
    }
   },
   "outputs": [],
   "source": [
    "############### 3x3 window ###############\n",
    "for i in range(1, img_noisy_array.shape[0] - 1):\n",
    "    for j in range(1, img_noisy_array.shape[1] - 1):\n",
    "        win = []\n",
    "        for x in range(i - 1, i + 2):\n",
    "            for y in range(j - 1, j + 2):\n",
    "                win.append(img_noisy_array[x][y])\n",
    "\n",
    "        new_img_array[i][j] = getMedian(win)\n",
    "\n",
    "imshow(new_img_array)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5x5 Filtre"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-22T09:25:58.303805Z",
     "start_time": "2019-08-22T09:25:57.481663Z"
    }
   },
   "outputs": [],
   "source": [
    "############### 5x5 window ###############\n",
    "img_noisy_array = np.array(img_noisy)\n",
    "new_img_array = np.array(img_noisy)\n",
    "\n",
    "for i in range(1, img_noisy_array.shape[0] - 2):\n",
    "    for j in range(1, img_noisy_array.shape[1] - 2):\n",
    "        win = []\n",
    "        for x in range(i - 2, i + 3):\n",
    "            for y in range(j - 2, j + 3):\n",
    "                win.append(img_noisy_array[x][y])\n",
    "        #sort the values\n",
    "        win.sort()\n",
    "        \n",
    "        new_img_array[i][j] = getMedian(win)\n",
    "\n",
    "imshow(new_img_array)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Mean (Ortalama) Filtresi\n",
    "Resim üzerinde gezdirilen pencere içerisindeki piksel değerlerinin ortalaması alınır."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-22T09:26:09.338443Z",
     "start_time": "2019-08-22T09:26:08.312591Z"
    }
   },
   "outputs": [],
   "source": [
    "############### 5x5 window ###############\n",
    "img_noisy_array = np.array(img_noisy)\n",
    "new_img_array = np.array(img_noisy)\n",
    "\n",
    "\n",
    "for i in range(1, img_noisy_array.shape[0] - 2):\n",
    "    for j in range(1, img_noisy_array.shape[1] - 2):\n",
    "        win = []\n",
    "        for x in range(i - 2, i + 3):\n",
    "            for y in range(j - 2, j + 3):\n",
    "                win.append(img_noisy_array[x][y])\n",
    "                \n",
    "        new_img_array[i][j] = (np.sum(win))/(5*5)\n",
    "\n",
    "imshow(new_img_array)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<hr>\n",
    "\n",
    "## Kenar nedir\n",
    "\n",
    "Piksel yoğunluklarında aşırı farklılıklar bulunan alan genellikle bir nesnenin kenarını gösterir.\n",
    "\n",
    "### Kenar Çeşitleri\n",
    "\n",
    "Bunlar, görüntülerde bulunan ana ideal kenar tipleridir. Bir görüntüdeki görüntü yoğunluğunun değişme şekli, o konumda mevcut olan kenar tipini belirler. Şekil 1, piksellerin x ya da y doğrultusundaki mesafelerine karşı olan görüntü yoğunluğunu temsil etmek için bir çizgi kullanarak bu farklılıkları göstermeye yardımcı olur.\n",
    "\n",
    "- a. Adım Kenarı (Step Edge) - Görüntünün yoğunluğunun derhal bir mesafeden arttığı yerde.\n",
    "- b. Rampa Kenarı (Ramp Edge) - Görüntünün yoğunluğunun belli bir mesafeye kademeli olarak arttığı yer.\n",
    "- c. Tavan Kenarı (Roof Edge) - Görüntünün yoğunluğunun geçici olarak belirli bir mesafeye yayıldığı yer.\n",
    "\n",
    "![alt text](assets/5-edge_type.jpg)\n",
    "\n",
    "[Makale ve Resim Referansı](http://www.doc.ic.ac.uk/~ts2615/contribution.html#1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Kenar Tespiti: Sobel Filtresi"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-22T10:22:01.318884Z",
     "start_time": "2019-08-22T10:22:01.085531Z"
    }
   },
   "outputs": [],
   "source": [
    "path = \"images/jet.jpg\"\n",
    "img = Image.open(path)\n",
    "\n",
    "imshow(img)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Sobel, bir görüntünün kenarlarını algılamak için çok yaygın bir operatördür, bu bir görüntünün türevine bir yaklaşımdır. Y ve x yönlerinde ayrıdır. Burada, her x ve y yönü için bir tane olmak üzere bir çekirdek 3 * 3 matrisi kullanıyoruz. X yönü için degrade, solda eksi sayılar, sağında da pozitif sayılar ve merkez pikselleri koruruz. Satır pikselleri.\n",
    "\n",
    "![alt text](assets/5-sobel_con_kernels.png)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-22T11:47:13.085126Z",
     "start_time": "2019-08-22T11:47:13.079943Z"
    }
   },
   "outputs": [],
   "source": [
    "img_array = np.array(img)\n",
    "\n",
    "#define horizontal and Vertical sobel kernels\n",
    "Gx = np.array([[-1, 0, 1],[-2, 0, 2],[-1, 0, 1]])\n",
    "Gy = np.array([[-1, -2, -1],[0, 0, 0],[1, 2, 1]])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Çekirdek evrişim fonksiyonunu tanımlamak\n",
    "\n",
    "Evrişim işlevi, aynı boyutta üçüncü bir sayı dizisini üretmek için genellikle farklı boyutlardaki iki sayı dizisini, burada gri skala görüntüsünü ve sobel / prewitt çekirdeklerini bir araya getirme yöntemidir. Evrişim, uygulanan çekirdeğin görüntünün tüm piksellerinin üzerine kaydırılmasıyla gerçekleştirilir.\n",
    "A, kaynak görüntüdür ve * evrişim işlemini gösterir.\n",
    "\n",
    "\n",
    "![alt text](assets/5-math_gx.svg)\n",
    "\n",
    "![alt text](assets/5-math_gy.svg)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-22T11:46:17.090795Z",
     "start_time": "2019-08-22T11:46:17.079526Z"
    }
   },
   "outputs": [],
   "source": [
    "#define kernal convolution function\n",
    "# with image X and filter F\n",
    "def convolve(X, F):\n",
    "    # height and width of the image\n",
    "    X_height = X.shape[0]\n",
    "    X_width = X.shape[1]\n",
    "    \n",
    "    # height and width of the filter\n",
    "    F_height = F.shape[0]\n",
    "    F_width = F.shape[1]\n",
    "    \n",
    "    H = (F_height - 1) // 2\n",
    "    W = (F_width - 1) // 2\n",
    "    \n",
    "    #output numpy matrix with height and width\n",
    "    out = np.zeros((X_height, X_width))\n",
    "    #iterate over all the pixel of image X\n",
    "    for i in np.arange(H, X_height-H):\n",
    "        for j in np.arange(W, X_width-W):\n",
    "            sum = 0\n",
    "            #iterate over the filter\n",
    "            for k in np.arange(-H, H+1):\n",
    "                for l in np.arange(-W, W+1):\n",
    "                    #get the corresponding value from image and filter\n",
    "                    a = X[i+k, j+l]\n",
    "                    w = F[H+k, W+l]\n",
    "                    sum += (w * a)\n",
    "            out[i,j] = sum\n",
    "    #return convolution  \n",
    "    return out"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Gradyan büyüklüğü\n",
    "\n",
    "Her yöndeki gradyan bileşeni daha sonra her noktada gradyanın mutlak büyüklüğünü ve bu gradyanın yönünü bulmak için bir araya getirilir."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-22T11:34:49.791406Z",
     "start_time": "2019-08-22T11:34:41.718703Z"
    }
   },
   "outputs": [],
   "source": [
    "#normalizing the vectors\n",
    "sob_x = convolve(img_array, Gx) / 9.0\n",
    "sob_y = convolve(img_array, Gy) / 9.0\n",
    "\n",
    "\n",
    "#calculate the gradient magnitude of vectors\n",
    "sob_out = np.sqrt(np.power(sob_x, 2) + np.power(sob_y, 2))\n",
    "# mapping values from 0 to 255\n",
    "sob_out = (sob_out / np.max(sob_out)) * 255\n",
    "\n",
    "\n",
    "imshow(sob_out)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "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.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}