{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 简介"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "书接上回。还记得在卷积那章我们使用二维方波信号对图片进行卷积之后的结果吗？没错，图像变模糊了。也许你感觉很奇怪，为什么使用冲击卷积核之后图像并没有发生明显的变化，而方波信号却让图像变模糊了呢？是不是还有其他的卷积核，也可以让图片产生一些神奇的变化呢？别急，在这一章节中，我们将揭开图像处理最神秘的那层面纱——滤波。\n",
    "\n",
    "所谓滤波，就是在尽可能保留保留图像细节特征的条件下对目标图像的噪声进行抑制，是图像预处理中不可缺少的一环操作，其处理效果的好坏将直接影响到后续图像处理和分析的有效性和可靠性。由滤波的定义我们不难得出，滤波的目的有两个：一是突出图像特征细节以方便后续处理，二是抑制图片中的噪声。在接下来的介绍中，我们将重点介绍滤波在抑制噪声中的应用。\n",
    "\n",
    "那么你可能会有疑问，为什么滤波能对图片中的噪声进行抑制？我们知道，图像的能量大部分是集中在低频和中频中，而在高频部分，我们感兴趣的信息往往被大量的噪声所淹没。因此，当一个滤波器能够降低图像的高频成分的幅度时，它就可以减弱噪声的影响了。我们把这一过程叫做“图像的平滑化”或者“滤波操作”。\n",
    "\n",
    "所以，直观的说，平滑图像是一种低频增强的空间域滤波技术。在实际的操作中，空间域的平滑滤波一般采用简单的平均法进行，换言之，求邻近像素点的平均值。邻域的大小与平滑的效果直接相关，邻域越大平滑的效果越好，但邻域过大，平滑会使边缘信息损失的越大，从而使输出的图像变得模糊，因此需合理选择邻域的大小。\n",
    "\n",
    "所以，滤波器的设计就显得很重要。在接下来的章节中，我们将根据滤波器的性质分别进行相应的介绍。在正式开始之前，让我们先导入卷积中编写的二维卷积函数。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from PIL import Image\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import cv2\n",
    "import torch\n",
    "from torch.nn import functional as F\n",
    "\n",
    "class conv_2d():\n",
    "    def __init__(self, image, kernel):\n",
    "        self.img = image\n",
    "        self.k = kernel\n",
    "        \n",
    "    def plot(self):\n",
    "        # 展示原图\n",
    "        plt.figure()\n",
    "        plt.imshow(self.img, cmap='gray')\n",
    "        plt.axis('off')\n",
    "        plt.title('Input')\n",
    "    \n",
    "\n",
    "    # 定义二维卷积\n",
    "    def convolution(self, data, k):\n",
    "        # 直接调用库函数进行卷积操作\n",
    "        return cv2.filter2D(data,-1,k)\n",
    "\n",
    "    \n",
    "    # 展示二维卷积结果\n",
    "    def plot_conv(self):\n",
    "        img_new = self.convolution(self.img, self.k)  # 卷积过程\n",
    "        # 卷积结果可视化            \n",
    "        plt.figure()\n",
    "        plt.imshow(img_new, cmap='gray')\n",
    "        plt.title('Output')\n",
    "        plt.axis('off')\n",
    "        return\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 线性滤波"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "线性滤波器是图像处理最为基本的一种方法，它可以运行我们对图像进行处理，并产生各种不同的效果。线性滤波的基本原理是每个像素的输出值是周边像素的加权和。我们将分别介绍均值滤波器与高斯滤波器的原理，并测试对应的效果。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 均值滤波器"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "一般来说，图像具有局部连续的性质，即相邻的像素的值相近。而噪声使得噪点处产生像素跳跃，所以通过平滑噪点可以减少噪声，去除图像中的不相关细节。均值滤波器（Mean filter）是对邻域内的像素平均化来滤波，属于平滑滤波。滤波的输出是包含在滤波器模板邻域内的像素的平均值，这是一个低通滤波器。\n",
    "\n",
    "具体而言，均值滤波器的原型如下：\n",
    "$$ k = \\frac{1}{n^2}*\\begin{bmatrix}\n",
    "   1 & 1 &... & 1 \\\\\n",
    "   1 & 1 &... & 1 \\\\\n",
    "   ...\\\\\n",
    "   1 & 1 &... & 1\n",
    "  \\end{bmatrix}_{n\\times n} $$\n",
    "其中，$n$为滤波器的大小，一般更具实际情况对其进行调整。接下来，让我们在对一张图片进行均值滤波，并观察它的效果。在此之前，我们先给图像添加噪声。\n",
    "\n",
    "注：椒盐噪声可以理解为斑点，随机出现在图像中的黑点或白点；高斯噪声可以理解为拍摄图片时由于光照等原因造成的噪声。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import random\n",
    "# 添加高斯噪声\n",
    "def add_Gaussian(img):\n",
    "    mean = 0\n",
    "    sigma = 25\n",
    "    m, n = img.shape\n",
    "    gauss = np.random.normal(mean,sigma,(m,n))\n",
    "    noisy_img = img + gauss\n",
    "    noisy_img = np.clip(noisy_img,a_min=0,a_max=255)\n",
    "    return noisy_img\n",
    "\n",
    "# 添加椒盐噪声\n",
    "def add_Salt(img):\n",
    "    s_vs_p = 0.5\n",
    "    amount = 0.04\n",
    "    noisy_img = np.copy(img)\n",
    "    num_salt = np.ceil(amount * img.size * s_vs_p)\n",
    "    coords = [np.random.randint(0,i - 1, int(num_salt)) for i in img.shape]\n",
    "    noisy_img[tuple(coords)] = 255\n",
    "    num_pepper = np.ceil(amount * img.size * (1. - s_vs_p))\n",
    "    coords = [np.random.randint(0,i - 1, int(num_pepper)) for i in img.shape]\n",
    "    noisy_img[tuple(coords)] = 0\n",
    "    return noisy_img"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 173700 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 112168 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "img = Image.open('lena.jpeg')\n",
    "img = img.convert('L')\n",
    "img = np.array(img)\n",
    "\n",
    "# 添加高斯噪声的图像：\n",
    "img_gaussian = add_Gaussian(img)\n",
    "# 添加椒盐噪声的图像：\n",
    "img_salt = add_Salt(img)\n",
    "\n",
    "# 均值滤波器 size=3\n",
    "size = 3\n",
    "k3 = 1/size/size *np.ones((size, size))\n",
    "\n",
    "# 展示原图\n",
    "conv_gaussian = conv_2d(img_gaussian, k3)\n",
    "conv_gaussian.plot()\n",
    "\n",
    "# 展示卷积结果\n",
    "conv_gaussian.plot_conv()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以看出图片变的平滑了，但噪声依旧存在。我们增加均值滤波器的大小，并再次测试。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 173700 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 92196 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 75544 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 均值滤波器 size=5\n",
    "size = 5\n",
    "k5 = 1/size/size *np.ones((size,size))\n",
    "\n",
    "# 展示原图\n",
    "conv = conv_2d(img_gaussian, k5)\n",
    "conv.plot()\n",
    "\n",
    "# 展示卷积结果\n",
    "conv.plot_conv()\n",
    "\n",
    "\n",
    "\n",
    "# 均值滤波器 size=9\n",
    "size = 9\n",
    "k9 = 1/size/size * np.ones((size, size))\n",
    "\n",
    "conv = conv_2d(img_gaussian, k9)\n",
    "# 展示卷积结果\n",
    "conv.plot_conv()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这时，我们可以很明显的看出，当均值滤波器的大小为$5\\times5$时，噪声基本消失不见；而当滤波器大小为$9\\times9$时，不仅噪声消除了，图像也变得模糊了。因此在实际滤波过程中，我们需要为滤波器选择合适的大小，尽可能在保留图片特征的情况下消除噪声。\n",
    "\n",
    "那么，均值滤波器消除椒盐噪声的情况如何呢？"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 115312 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 94380 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 展示原图\n",
    "conv_salt = conv_2d(img_salt, k5)\n",
    "conv_salt.plot()\n",
    "\n",
    "# 展示卷积结果\n",
    "conv_salt.plot_conv()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "由此可见，均值滤波器也可以在一定范围内对椒盐噪声进行滤波，但椒盐噪声依旧能够看得见。当然，均值滤波器作为一种非常简单的滤波器，能产生的效果毕竟有限。接下来，我们将介绍另一种线性滤波器：高斯滤波器。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 高斯滤波器"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "高斯滤波（Gaussian filter）对于图像来说是一个低通滤波，广泛用于消除高斯噪声。和均值滤波器不同的是，高速滤波对邻域内的每一个像素点进行加权而非平均，权重由由高斯分布来确定。直观的看，高斯滤波器如下图所示：\n",
    "\n",
    "<center>\n",
    "    <img style=\"border-radius: 0.3125em;\" \n",
    "    src=\"gaussian.png\" width=500>\n",
    "    <br>\n",
    "    <div style=\"color:orange; \n",
    "    display: inline-block;\n",
    "    color: #999;\n",
    "    padding: 2px;\">图3-1 高斯滤波器</div>\n",
    "</center>\n",
    "\n",
    "\n",
    "高斯滤波后图像被平滑的程度取决于标准差。它的输出是临域像素的加权平均，同时离中心越近的像素权重越高。因此，相对于均值滤波它的平滑效果更柔和，而且边缘保留的也更好。\n",
    "\n",
    "高斯滤波器具体定义如下：\n",
    "$$G[x,y] = \\frac{1}{2\\pi\\sigma^2}e^{-\\frac{x^2+y^2}{2\\sigma^2}}$$\n",
    "\n",
    "其中，$x,y$表示像素点和滤波器中心点的在$x$轴与$y$轴的距离。接下来，我们将测试高斯函数的效果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 173700 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 106872 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 定义高斯核\n",
    "k_gaussian = np.array(\n",
    "[\n",
    "    [1,4,7,4,1],\n",
    "    [4,16,26,16,4],\n",
    "    [7,26,41,26,7],\n",
    "    [4,16,26,16,4],\n",
    "    [1,4,7,4,1]\n",
    "])\n",
    "k_gaussian = k_gaussian / np.sum(k_gaussian)\n",
    "\n",
    "# 展示原图\n",
    "conv = conv_2d(img_gaussian, k_gaussian)\n",
    "conv.plot()\n",
    "\n",
    "# 展示卷积结果\n",
    "conv.plot_conv()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "看来高斯噪声还得是高斯滤波器才能十分有效的解决。由于高斯卷积核编写较为麻烦，接下来我们将直接调用库函数（cv2.GaussianBlur()）进行操作。\n",
    "\n",
    "我们改变高斯核的标准差，并再次测试。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 107452 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 91628 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 91424 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(cv2.GaussianBlur(img_gaussian, (5,5), 1), cmap='gray')\n",
    "plt.axis('off')\n",
    "plt.show()\n",
    "plt.imshow(cv2.GaussianBlur(img_gaussian, (5,5), 3), cmap='gray')\n",
    "plt.axis('off')\n",
    "plt.show()\n",
    "plt.imshow(cv2.GaussianBlur(img_gaussian, (5,5), 10), cmap='gray')\n",
    "plt.axis('off')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果使用高斯滤波器处理椒盐噪声呢？"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 94144 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(cv2.GaussianBlur(img_salt, (5,5), 5), cmap='gray')\n",
    "plt.axis('off')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "和均值滤波器一样，高斯滤波器也无法有效的处理椒盐噪声。接下来，我们将介绍另外一类称之为椒盐噪声杀手的滤波器——非线性滤波器。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 非线性滤波器"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 中值滤波器"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "中值滤波器（Median filter）是一种统计排序滤波器，即图像像素等于周围像素排序后的中值。对于图像中一点$(x,y)$，中值滤波以该点为中心，将邻域内所有像素的统计排序中值作为此点的响应。根据中值滤波器的定义不难发现，他是一种很典型的非线性滤波手段。相比与均值滤波和高斯滤波，中值滤波可以有效的降低随机噪声，直接忽略掉噪声点，把噪声引起的模糊降到最低。线性滤波器在滤波的同时会造成图像细节模糊，中值滤波可以避免这个问题，其典型的应用就是中值滤波消除斑点噪声、椒盐噪声。\n",
    "\n",
    "下图是应用中值滤波器对图像滤波的一个例子。当中值滤波器滑动到图中绿色区域时，我们先对区域内的像素进行排序；之后我们选取排序的中值作为该点滤波的结果，即11。\n",
    "<center>\n",
    "    <img style=\"border-radius: 0.3125em;\" \n",
    "    src=\"median.png\" width=500>\n",
    "    <br>\n",
    "    <div style=\"color:orange; \n",
    "    display: inline-block;\n",
    "    color: #999;\n",
    "    padding: 2px;\">图3-2 中值滤波器</div>\n",
    "</center>\n",
    "\n",
    "\n",
    "\n",
    "接下来，我们将调用库函数（cv2.medianBlur()）对图片进行滤波。我们首先对添加了椒盐噪声的图像进行处理，检验中值滤波器是否是一个合格的“椒盐杀手”。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 115312 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 71228 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "conv_salt.plot()\n",
    "plt.show()\n",
    "plt.imshow(cv2.medianBlur(img_salt,9), cmap='gray')\n",
    "plt.title('output')\n",
    "plt.axis('off')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "图中的lena是不是看上去非常清晰？经过中值滤波器滤波之后，图片中连一点椒盐噪声的影子都看不见了。看来杀手这一称号名副其实。那么接下来，我们再看看中值滤波器能否高效的处理高斯噪声。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 173700 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 81592 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "conv_gaussian.plot()\n",
    "plt.show()\n",
    "plt.imshow(cv2.medianBlur(np.uint8(img_gaussian),9), cmap='gray')\n",
    "plt.title('output')\n",
    "plt.axis('off')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "看起来还不错？不过图片相应的也变模糊了。看来中值滤波器解决高斯噪声的能力并不如椒盐噪声。不过正如高斯滤波器擅长解决高斯噪声一样，金无足赤，在实际的处理中只要扬长避短即可。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 双边滤波"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "高斯滤波属于加权平均滤波，距离中心点越近的点越有较大权重，这种方法符合图像的平滑变化的特征，但是在边缘区域，像素值出现突变，这种方法反而会滤掉边缘轮廓，损失掉有用的边缘信息。双边滤波就是最常用的边缘保护滤波方法，就是为了处理这种情况而发明的。\n",
    "\n",
    "双边滤波（Bilateral filter）是一种非线性的滤波方法，是结合图像的空间邻近度和像素值相似度的一种折衷处理，同时考虑空域信息和灰度相似性，达到保边去噪的目的。双边滤波将高斯滤波中通过各个点到中心点的空间临近度计算的各个权值进行优化，将其优化为空间临近度计算的权值和像素值相似度计算的权值的乘积，优化后的权值再与图像作卷积运算，从而达到保边去噪的效果。具体来说，双边滤波器的数学公式如下：\n",
    "\n",
    "$$G[x,y] = \\frac{1}{2\\pi\\sigma_s^2}e^{-\\frac{x^2+y^2}{2\\sigma_s^2}} \\times \\frac{1}{2\\pi\\sigma_b^2}e^{-\\frac{k^2}{2\\sigma_b^2}}$$\n",
    "\n",
    "可以很直观的看出，双边滤波器只是在原有高斯函数的基础上加了一项。其中，$k$是像素在$x$和$y$处强度的差值。总体而言，在像素强度变换不大的区域，双边滤波有类似于高斯滤波的效果，而在图像边缘等强度梯度较大的地方，权重会减小，滤波效应也就变小。\n",
    "\n",
    "接下来，我们将调用库函数（cv2.bilateralFilter()）对图片进行滤波。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 173700 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 138472 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "conv_gaussian.plot()\n",
    "plt.show()\n",
    "\n",
    "plt.imshow(cv2.bilateralFilter(np.uint8(img_gaussian),10,25,15), cmap='gray')\n",
    "plt.title('output')\n",
    "plt.axis('off')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 115312 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 88540 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "conv_salt.plot()\n",
    "plt.show()\n",
    "\n",
    "plt.imshow(cv2.bilateralFilter(np.uint8(img_salt),10,25,15), cmap='gray')\n",
    "plt.title('output')\n",
    "plt.axis('off')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "看起来双边滤波器对椒盐噪声并不友好。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 总结"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在本章中，我们学习了滤波的基本概念以及几种不同的滤波器。在图像处理中，滤波器除了过滤噪声的作用之外，还有这其他有趣的作用，比如边缘检测、图像锐化等。感兴趣的同学可以自行查阅相关资料，我们也会在之后的章节中逐步介绍，届时你就会更深刻的理解，滤波在搭建一个庞大的计算机视觉框架中起到的作用。"
   ]
  },
  {
   "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.7.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
