{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "da3fe980",
   "metadata": {},
   "outputs": [],
   "source": [
    "#############################################################\n",
    "############ Part 0. Import necessary library ###############\n",
    "#############################################################\n",
    "\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "plt.rcParams['figure.figsize'] = [32, 16]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "276bc08e",
   "metadata": {},
   "outputs": [],
   "source": [
    "#############################################################\n",
    "########## Part 1. Read and plot the original image #########\n",
    "#############################################################\n",
    "fig = plt.figure()\n",
    "# Read the original image\n",
    "org_pf = plt.imread(\"platform.png\")\n",
    "# Convert the image to grayscale and normalize it to the range [0, 1]\n",
    "org_gray_pf = np.mean(org_pf, 2)\n",
    "h, w = np.shape(org_gray_pf)\n",
    "fig.add_subplot(1, 2, 1)\n",
    "plt.imshow(org_gray_pf, cmap = 'gray')\n",
    "plt.title(\"Original Image\")\n",
    " \n",
    "org_freq = np.fft.fftshift(np.fft.fft2(org_gray_pf)) # The same as circshift(fft2(org_gray_pf), [h/2, w/2]), Shifting the low frequency components to the center. Our definition is equal to (1/(h^2)) * fft2 \n",
    "\n",
    "# Normalize the frequency component for visualization.\n",
    "log_org_freq = np.log(1+np.abs(org_freq))\n",
    "max_log_freq = np.max(log_org_freq)\n",
    "fig.add_subplot(1, 2, 2)\n",
    "plt.imshow(log_org_freq / max_log_freq, cmap = 'gray')\n",
    "plt.title(\"Frequency of original image\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a2f72555",
   "metadata": {},
   "outputs": [],
   "source": [
    "#############################################################\n",
    "######### Part 2. Read and plot the corrupted image #########\n",
    "#############################################################\n",
    "fig = plt.figure()\n",
    "# Read the image\n",
    "gray_pf = plt.imread(\"noisy_platform.png\")\n",
    "# Convert the image to grayscale and normalize it to the range [0, 1]\n",
    "fig.add_subplot(1, 2, 1)\n",
    "plt.imshow(gray_pf, cmap = 'gray')\n",
    "plt.title(\"Corrupted Image\")\n",
    "\n",
    "freq = np.fft.fftshift(np.fft.fft2(gray_pf))\n",
    "\n",
    "# Normalize the frequency component for visualization.\n",
    "log_freq = np.log(1+np.abs(freq))\n",
    "fig.add_subplot(1, 2, 2)\n",
    "plt.imshow(log_freq / max_log_freq, cmap = 'gray')\n",
    "plt.title(\"Frequency of corrupted image\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6d6285db",
   "metadata": {},
   "outputs": [],
   "source": [
    "#############################################################\n",
    "########### Part 3. Recover the corrupted image #############\n",
    "#############################################################\n",
    "fig = plt.figure()\n",
    "# Compute the distance.\n",
    "X, Y = np.meshgrid(np.arange(-w/2, w/2), np.arange(-h/2, h/2)) \n",
    "dist = X**2 + Y**2\n",
    "# Define the Gaussian Low Pass Filter.\n",
    "sigma = 100\n",
    "#############################################################\n",
    "# Complete the following lines to define the gaussian low pass filter.\n",
    "low_pass_filter = ?????\n",
    "#############################################################\n",
    "# Multiply the frequency components by the Gaussian Low Pass Filter.\n",
    "freq = freq * low_pass_filter\n",
    "\n",
    "# Visualize the resulting frequency domain.\n",
    "fig.add_subplot(1, 2, 2)\n",
    "plt.imshow(np.log(1+np.abs(freq)) / max_log_freq, cmap = 'gray')\n",
    "plt.title(\"Frequency of recovered image\")\n",
    "\n",
    "# Transform back to the spatial domain.\n",
    "recon = np.fft.ifft2(np.fft.ifftshift(freq))\n",
    "\n",
    "# Plot the recovered image.\n",
    "fig.add_subplot(1, 2, 1)\n",
    "plt.imshow(np.real(recon), cmap = 'gray')\n",
    "plt.title(\"Recovered Image\")"
   ]
  }
 ],
 "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.9.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
