{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "d5d62d24",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import cv2\n",
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "40a56d12-cc0f-481d-b3c5-c2020a7d137b",
   "metadata": {},
   "outputs": [],
   "source": [
    "from dataclasses import asdict\n",
    "from catppuccin.palette import PALETTE\n",
    "mpl.style.use(\"mocha\")\n",
    "colors = asdict(PALETTE.__getattribute__(\"mocha\").colors)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2799ab25",
   "metadata": {
    "jp-MarkdownHeadingCollapsed": true
   },
   "source": [
    "## Базовая работа с изображением"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "5037aa29",
   "metadata": {},
   "outputs": [],
   "source": [
    "image = cv2.imread('sar_2_color.jpg')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "3e5f356b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x7ff61af143e0>"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 490508 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(image)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "37b8f016",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(572, 974, 3)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "image.shape # h,w,c"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "e4530952",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([12, 12, 12], dtype=uint8)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "image[250,250] # b,g,r"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "51aab9ce",
   "metadata": {},
   "outputs": [],
   "source": [
    "# ROI\n",
    "img_roi = image[100:200, 500:700]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "70010d8b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x7ff61adadd90>"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 265828 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(img_roi)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "f882dac3",
   "metadata": {},
   "outputs": [],
   "source": [
    "b,g,r = cv2.split(image)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "1f89e4b5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x7ff61ade59a0>"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 304536 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(b, cmap = 'gray')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "80f48335",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x7ff61ae1e960>"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 311708 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(g, cmap = 'gray')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "14bf6bec",
   "metadata": {},
   "outputs": [],
   "source": [
    "# alternative approach\n",
    "b = image[:,:,0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "65f6cb65",
   "metadata": {},
   "outputs": [],
   "source": [
    "import copy\n",
    "\n",
    "image2 = copy.deepcopy(image)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "6e348740",
   "metadata": {},
   "outputs": [],
   "source": [
    "image2[50:100,50:100] = [0,0,0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "f0af9079",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x7ff61ab41580>"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 488608 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(image2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "7b3beafd",
   "metadata": {},
   "outputs": [],
   "source": [
    "# empty image\n",
    "image_template = np.zeros(image.shape,np.uint8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "649438f3",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x7ff61abafbf0>"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 10600 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(image_template)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3c9b56ab",
   "metadata": {
    "jp-MarkdownHeadingCollapsed": true
   },
   "source": [
    "## Конвертация цветовых моделей"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "ddf46c8d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 0, 0], dtype=uint8)"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "image_template[0,0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "90601bc7",
   "metadata": {},
   "outputs": [],
   "source": [
    "image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "4254803d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "np.uint8(40)"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "image_gray[0,0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "abb0a164",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(572, 974)"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "image_gray.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "f282c88e",
   "metadata": {},
   "outputs": [],
   "source": [
    "image_hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "d37c08b1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(572, 974, 3)"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "image_hsv.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "ae9ef2ca",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([117, 143,  75], dtype=uint8)"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "image_hsv[0,0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "d8cdda21",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([75, 37, 33], dtype=uint8)"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "image[0,0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "73fdb374",
   "metadata": {},
   "outputs": [],
   "source": [
    "image_lab = cv2.cvtColor(image, cv2.COLOR_BGR2Lab)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "0ed9c8e4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 42, 139, 104], dtype=uint8)"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "image_lab[0,0]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e0d7f4f0",
   "metadata": {
    "jp-MarkdownHeadingCollapsed": true
   },
   "source": [
    "## Пороговая фильтрация"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "0b6d5e3f",
   "metadata": {},
   "outputs": [],
   "source": [
    "_,thresh1 = cv2.threshold(image_gray,200,255,cv2.THRESH_BINARY)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "6e84b905",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x7ff610990590>"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 58704 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(thresh1, cmap='gray')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "f5e1453e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "np.uint64(0)"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "thresh1[thresh1==100].sum()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "396e3b66",
   "metadata": {
    "jp-MarkdownHeadingCollapsed": true
   },
   "source": [
    "## Построение гистограммы"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "4b455e07",
   "metadata": {},
   "outputs": [],
   "source": [
    "histSize = 256\n",
    "histRange = (0, 256)\n",
    "accumulate = False\n",
    "\n",
    "b_hist = cv2.calcHist([b], [0], None, [histSize], histRange, accumulate=accumulate)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "477df536",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x7ff6109546e0>]"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 31056 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(b_hist)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "92636df5",
   "metadata": {},
   "outputs": [],
   "source": [
    "b_hist_cum = b_hist.cumsum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "1a195130",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x7ff6108ac830>]"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 25908 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(b_hist_cum)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "e11f8476",
   "metadata": {},
   "outputs": [],
   "source": [
    "b_hist_norm = b_hist /  (image.shape[0] * image.shape[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "ae7a2b79",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x7ff610702a50>]"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 26440 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(b_hist_norm)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "aa3739f4",
   "metadata": {
    "jp-MarkdownHeadingCollapsed": true
   },
   "source": [
    "## Сравнение двух изображений"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "b67e4981",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "SSIM: 1.0\n"
     ]
    }
   ],
   "source": [
    "from skimage.metrics import structural_similarity, mean_squared_error\n",
    "\n",
    "(ssim, diff) = structural_similarity(image_gray, image_gray, full=True)\n",
    "diff = (diff * 255).astype(\"uint8\")\n",
    "print(\"SSIM: {}\".format(ssim))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "e130dabe",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x7ff5f694b740>"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 75536 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(diff)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "03ab140b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "np.float64(0.0)"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mse = mean_squared_error(image_gray, image_gray)\n",
    "mse"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a7c085bc",
   "metadata": {
    "jp-MarkdownHeadingCollapsed": true
   },
   "source": [
    "## Статистические характеристики изображений"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "de9202f2",
   "metadata": {},
   "outputs": [],
   "source": [
    "mean = image_gray.mean()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "aaff4206",
   "metadata": {},
   "outputs": [],
   "source": [
    "std = image_gray.std()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "248147b1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "67.41225535245043 52.016191875959635\n"
     ]
    }
   ],
   "source": [
    "print(mean,std)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "3fbab27e",
   "metadata": {},
   "outputs": [],
   "source": [
    "eq_gray = cv2.equalizeHist(image_gray)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "250af16c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x7ff5f697dd90>"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 343716 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(eq_gray, cmap=\"gray\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "7c013a0e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x7ff5f6a1c200>"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 309676 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(image_gray, cmap=\"gray\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f3ad3ea1-b103-4383-8219-946233ef84c5",
   "metadata": {},
   "source": [
    "# Задание"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8e91c442-8169-4179-9ee6-75022dc4f3b0",
   "metadata": {
    "jp-MarkdownHeadingCollapsed": true
   },
   "source": [
    "1. [x] Загрузите изображение в оттенках серого sar_1_gray.jpg. \n",
    "2. [x] Постройте гистограмму\n",
    "3. [x] Реализуйте алгоритм гамма коррекции с параметром гамма <1, >1.\n",
    "4. [x] Сравните исходное изображение, скорректированное при помощи гамма-фильтра. MSE, SSIM.\n",
    "5. [ ] Реализуйте алгоритм статистической цветокоррекции на основе статистики eq_gray.\n",
    "6. [ ] Протестируйте работу алгоритмов пороговой фильтрации с различными параметрами.\n",
    "\n",
    "Для каждого решения напечатайте результат\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e84c055d-24d3-4e08-bed5-513199dd48d0",
   "metadata": {},
   "source": [
    "## Загрузка"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "id": "2427bbf1-ffed-4948-80e5-a102df665e9d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x7ff5f6166240>"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 339860 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "image = cv2.imread('sar_1_gray.jpg', cv2.IMREAD_GRAYSCALE)\n",
    "plt.imshow(image, cmap=\"gray\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7682875b-29b9-456d-b541-be1872ea6934",
   "metadata": {
    "jp-MarkdownHeadingCollapsed": true
   },
   "source": [
    "## Гистограмма"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "f3134249-c6c5-4373-bcf1-09bee7f2a87d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 15788 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#hist = cv2.calcHist(image, [1], None, [256], (0, 255))\n",
    "#plt.plot(hist)\n",
    "_ = plt.hist(image.ravel(), bins=256)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "96ba1554-7885-41e1-8f3f-8d5af59e5345",
   "metadata": {
    "jp-MarkdownHeadingCollapsed": true
   },
   "source": [
    "## MSE и SSIM"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "8faf11eb-8aea-4720-b13a-84b83112765c",
   "metadata": {},
   "outputs": [],
   "source": [
    "def mse(img1, img2):\n",
    "    return np.mean((img1.astype(float) - img2.astype(float)) ** 2)\n",
    "\n",
    "def ssim(img1, img2):\n",
    "    C1 = (0.01 * 255) ** 2\n",
    "    C2 = (0.03 * 255) ** 2\n",
    "    \n",
    "    img1 = img1.astype(float)\n",
    "    img2 = img2.astype(float)\n",
    "    \n",
    "    mu1 = cv2.GaussianBlur(img1, (11, 11), 1.5)\n",
    "    mu2 = cv2.GaussianBlur(img2, (11, 11), 1.5)\n",
    "    \n",
    "    mu1_sq = mu1 ** 2\n",
    "    mu2_sq = mu2 ** 2\n",
    "    mu1_mu2 = mu1 * mu2\n",
    "    \n",
    "    sigma1_sq = cv2.GaussianBlur(img1 ** 2, (11, 11), 1.5) - mu1_sq\n",
    "    sigma2_sq = cv2.GaussianBlur(img2 ** 2, (11, 11), 1.5) - mu2_sq\n",
    "    sigma12 = cv2.GaussianBlur(img1 * img2, (11, 11), 1.5) - mu1_mu2\n",
    "    \n",
    "    numerator = (2 * mu1_mu2 + C1) * (2 * sigma12 + C2)\n",
    "    denominator = (mu1_sq + mu2_sq + C1) * (sigma1_sq + sigma2_sq + C2)\n",
    "    \n",
    "    ssim_map = numerator / denominator\n",
    "    return np.mean(ssim_map)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eec5284a-a3ab-4586-8027-f3200b49b8eb",
   "metadata": {
    "jp-MarkdownHeadingCollapsed": true
   },
   "source": [
    "## Гамма-коррекция"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "27333afa-6b18-44d0-b1b9-6183bad74e9a",
   "metadata": {},
   "outputs": [],
   "source": [
    "def gamma_correction(image, gamma):\n",
    "    image_normalized = image.astype(np.float32) / 255.0\n",
    "    corrected = np.power(image_normalized, gamma)\n",
    "    return (corrected * 255).astype(np.uint8)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2311c3da-523d-48b1-a3b8-b080b5ca855f",
   "metadata": {},
   "source": [
    "### <1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "510bde0a-9922-4534-a2ef-dbfdc19d0979",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 12240 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "image_gamma = gamma_correction(image, .5)\n",
    "_ = plt.hist(image_gamma.ravel(), bins=256, color=colors['green']['hex'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "fe0e57d1-7c9f-40c1-af77-1047f7751bac",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "MSE:   3250.429145833333\n",
      "SSIM:  0.7826855938698241\n"
     ]
    }
   ],
   "source": [
    "print(f\"MSE:  \", mse(image, image_gamma))\n",
    "print(f\"SSIM: \", ssim(image, image_gamma))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b6293286-528d-4b49-899a-262a47edefc4",
   "metadata": {},
   "source": [
    "### >1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "id": "068e5785-192c-4c0b-9037-64692de14ede",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 17916 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "image_gamma = gamma_correction(image, 2.)\n",
    "_ = plt.hist(image_gamma.ravel(), bins=256, color=colors['red']['hex'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "id": "453e0b4c-2109-4ead-b667-0619e475accd",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "MSE:   2383.7636375\n",
      "SSIM:  0.5193678832134501\n"
     ]
    }
   ],
   "source": [
    "print(f\"MSE:  \", mse(image, image_gamma))\n",
    "print(f\"SSIM: \", ssim(image, image_gamma))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fca1c8a3-f07d-4506-aa42-9742f29b72fc",
   "metadata": {
    "jp-MarkdownHeadingCollapsed": true
   },
   "source": [
    "## Статическая цветокоррекция"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "id": "73d59099-9f31-497c-b5d6-e5673a7a6473",
   "metadata": {},
   "outputs": [],
   "source": [
    "def statistical_color_correction(image, target_mean=None, target_std=None):\n",
    "    current_mean = np.mean(image)\n",
    "    current_std = np.std(image)\n",
    "    \n",
    "    if not target_mean:\n",
    "        target_mean = 128\n",
    "    if not target_std:\n",
    "        target_std = 64\n",
    "    \n",
    "    corrected = (image - current_mean) * (target_std / current_std) + target_mean\n",
    "    \n",
    "    corrected = np.clip(corrected, 0, 255)\n",
    "    \n",
    "    return corrected.astype(np.uint8)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3dbffd0f-30d1-4aca-9f4b-571e761693a8",
   "metadata": {},
   "source": [
    "### Статическая коррекция"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "id": "1b1114f0-b1f8-4763-9ee9-deac05773539",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 403296 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "image_stat_corrected = statistical_color_correction(image)\n",
    "_ = plt.imshow(image_stat_corrected, cmap=\"gray\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5c828c5a-976b-47c8-b048-5f296ba241cb",
   "metadata": {},
   "source": [
    "### Эталон"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "id": "3775d75c-6af3-4956-892b-6d2deaf7e311",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 449104 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "eq_gray = cv2.equalizeHist(image)\n",
    "_ = plt.imshow(eq_gray, cmap=\"gray\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "92a5abe8-162d-4e26-acda-0eb091075e28",
   "metadata": {},
   "source": [
    "### Коррекция по эталону"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "id": "a3f083a5-c0f0-4546-8059-a43b14d3f334",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 413292 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "image_stat_eq = statistical_color_correction(\n",
    "    image, \n",
    "    target_mean=np.mean(eq_gray), \n",
    "    target_std=np.std(eq_gray)\n",
    ")\n",
    "_ = plt.imshow(image_stat_eq, cmap=\"gray\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1c6047ee-8d73-4185-b51e-2b05e130cab5",
   "metadata": {},
   "source": [
    "## Пороговая фильтрация"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9ff998f2-4904-4d00-a0af-d1d86b558642",
   "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.12.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
