{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "1fe0cd5a",
   "metadata": {},
   "outputs": [],
   "source": [
    "import cv2\n",
    "import numpy as np\n",
    "from pathlib import Path\n",
    "import time\n",
    "%matplotlib inline\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "def mse(img1, img2):\n",
    "   h, w, _= img1.shape\n",
    "   diff = cv2.subtract(img1, img2)\n",
    "   err = np.sum(diff**2)\n",
    "   mse = err/(float(h*w))\n",
    "   return mse\n",
    "\n",
    "def mse_gray(img1, img2):\n",
    "   h, w = img1.shape\n",
    "   diff = cv2.subtract(img1, img2)\n",
    "   err = np.sum(diff**2)\n",
    "   mse = err/(float(h*w))\n",
    "   return mse\n",
    "\n",
    "def seconds_to_hms(seconds):\n",
    "    hours = seconds // 3600\n",
    "    minutes = (seconds % 3600) // 60\n",
    "    secs = seconds % 60\n",
    "    return f'{int(hours)}:{int(minutes):02}:{int(secs):02}'\n",
    "\n",
    "def removeBlackBorder(image):        \n",
    "   copyImg = cv2.cvtColor(image.copy(), cv2.COLOR_BGR2HSV)\n",
    "   h = copyImg[:,:,0]\n",
    "   mask = np.ones(h.shape, dtype=np.uint8) * 255\n",
    "   th = (25, 175)\n",
    "   mask[(h > th[0]) & (h < th[1])] = 0\n",
    "   copyImg = cv2.cvtColor(copyImg, cv2.COLOR_HSV2BGR)\n",
    "   resROI = cv2.bitwise_and(copyImg, copyImg, mask=mask)\n",
    "      \n",
    "   image_gray = cv2.cvtColor(resROI, cv2.COLOR_BGR2GRAY)\n",
    "   _, thresh = cv2.threshold(image_gray, 0, 255, cv2.THRESH_BINARY)\n",
    "   kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (15, 15))\n",
    "   morph = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)\n",
    "   contours = cv2.findContours(morph, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)\n",
    "   contours = contours[0] if len(contours) == 2 else contours[1]\n",
    "   bigCont = max(contours, key=cv2.contourArea)\n",
    "   x, y, w, h = cv2.boundingRect(bigCont)\n",
    "   crop = image[y : y + h, x : x + w]\n",
    "   return crop"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "7dd5c06a",
   "metadata": {},
   "outputs": [],
   "source": [
    "def centerCrop(img:np, size:tuple = None, pct_size:float = 0.3):\n",
    "    if size is None:\n",
    "        size = int(img.shape[0] * (1 - pct_size)), int(img.shape[1] * (1 - pct_size)//1.5)\n",
    "    x, y = (img.shape[1] - size[1]) // 2, (img.shape[0] - size[0]) // 2\n",
    "            \n",
    "    return img[y:y+size[0], x:x+size[1]]\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "882b7198",
   "metadata": {},
   "outputs": [],
   "source": [
    "img = cv2.imread(str(Path(\"../DataSet_Ando_All_no20/NVB/410.tiff\")), cv2.IMREAD_COLOR)\n",
    "#img = removeBlackBorder(img)\n",
    "#img = centerCrop(img, pct_size=0.49)\n",
    "\n",
    "cap = cv2.VideoCapture(\"RARP410_20201112.MP4\")\n",
    "if not cap.isOpened():\n",
    "    raise IOError(\"Error opening video stream or file\")\n",
    "\n",
    "time_seg = 303\n",
    "fps = cap.get(cv2.CAP_PROP_FPS)\n",
    "frame_from_time = int (fps * time_seg)\n",
    "cap.set(cv2.CAP_PROP_POS_FRAMES, frame_from_time)\n",
    "\n",
    "ret, frame = cap.read()\n",
    "if not ret:\n",
    "    raise IOError(\"Error reading frame\")\n",
    "\n",
    "#frame = removeBlackBorder(frame)\n",
    "#frame = centerCrop(frame, pct_size=0.49)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "376cfae7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1080, 1920, 3) (1080, 1920, 3)\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 949152 characters]",
      "text/plain": [
       "<Figure size 1500x800 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "108.89743441358024\n"
     ]
    }
   ],
   "source": [
    "img_size = img.shape[0] * img.shape[1]\n",
    "frame_size = frame.shape[0] * frame.shape[1]\n",
    "if (img_size > frame_size):\n",
    "    img = cv2.resize(img, (frame.shape[1], frame.shape[0]), interpolation=cv2.INTER_CUBIC)\n",
    "\n",
    "print (img.shape, frame.shape)\n",
    "\n",
    "fig, ax = plt.subplots(1, 2, figsize=(15, 8))\n",
    "\n",
    "ax[0].imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))\n",
    "ax[0].set_title(f\"Original Image \")\n",
    "ax[0].axis(\"off\")\n",
    "\n",
    "ax[1].imshow(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))\n",
    "ax[1].set_title(f\"Frame #{frame_from_time} time: {time_seg}\")\n",
    "ax[1].axis(\"off\")\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.show()\n",
    "\n",
    "print(mse(img, frame))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "3363c0b6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 42948 characters]",
      "text/plain": [
       "<Figure size 1400x500 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots(1, 2, figsize=(14, 5), sharey=True)\n",
    "\n",
    "dataset = [(img, f\"Target Image {img.shape[:-1]}\"), (frame, f\"Video Frame {frame.shape[:-1]}\")]\n",
    "\n",
    "for a, (im, title) in zip(ax, dataset):\n",
    "    for i, ch in enumerate([\"b\", \"g\", \"r\"]):\n",
    "        channel_data = im[:, :, i].flatten()\n",
    "        a.hist(channel_data, bins=256, range=(0, 255), color=ch, alpha=0.5, label=f\"{ch.upper()} channel\")\n",
    "\n",
    "    a.set_title(f\"{title} BGR Histogram\")\n",
    "    a.set_xlabel('Pixel Intensity')\n",
    "    a.set_ylabel('Frequency')\n",
    "    a.legend(loc='upper right')\n",
    "        \n",
    "plt.tight_layout()\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "88daf241",
   "metadata": {},
   "outputs": [],
   "source": [
    "def normalization(img, mean = 0.458971, std = 0.225609):\n",
    "    Norm_img = cv2.cvtColor(img.copy(), cv2.COLOR_BGR2GRAY).astype(np.float32) / 255.0\n",
    "    Norm_img = (Norm_img - mean) / std\n",
    "    Norm_img = cv2.GaussianBlur(Norm_img, (5, 5), 1)\n",
    "    \n",
    "    return Norm_img"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "15d4fb7c",
   "metadata": {},
   "outputs": [],
   "source": [
    "n_img = normalization(img)\n",
    "n_frame = normalization(frame)\n",
    "\n",
    "#n_img = cv2.resize(n_img, (n_img.shape[1] // 4, n_img.shape[0] // 4))\n",
    "#n_frame = cv2.resize(n_frame, (n_frame.shape[1] // 4, n_frame.shape[0] // 4))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "1c682fc0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 575616 characters]",
      "text/plain": [
       "<Figure size 1500x800 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.4049924045138889\n"
     ]
    }
   ],
   "source": [
    "fig, ax = plt.subplots(1, 2, figsize=(15, 8))\n",
    "\n",
    "ax[0].imshow(n_img, cmap=\"gray\")\n",
    "ax[0].set_title(f\"Original Image {n_img.shape}\")\n",
    "ax[0].axis(\"off\")\n",
    "\n",
    "ax[1].imshow(n_frame, cmap=\"gray\")\n",
    "ax[1].set_title(f\"Frame #{frame_from_time} {n_frame.shape} time: {seconds_to_hms(time_seg)}\")\n",
    "ax[1].axis(\"off\")\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.show()\n",
    "\n",
    "print(mse_gray(n_img, n_frame))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "c3636782",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(2.3980823, -2.0343647, 2.3980823, -2.0343647)"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "n_img.max(), n_img.min(), n_frame.max(), n_frame.min()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "7ea7c2a8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 46784 characters]",
      "text/plain": [
       "<Figure size 1400x500 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots(1, 2, figsize=(14, 5), sharey=True)\n",
    "\n",
    "dataset = [(n_img, f\"Target Image {n_img.shape}\"), (n_frame, f\"Video Frame {n_img.shape}\")]\n",
    "\n",
    "for a, (im, title) in zip(ax, dataset):\n",
    "    for i, ch in enumerate([\"black\"]):\n",
    "        channel_data = im[:, :].flatten()\n",
    "        a.hist(channel_data, bins=256, range=(-2, 2), color=ch, alpha=0.5, label=f\"{ch.upper()} channel\")\n",
    "\n",
    "    a.set_title(f\"{title} Grayscale Histogram\")\n",
    "    a.set_xlabel('Pixel Intensity')\n",
    "    a.set_ylabel('Frequency')\n",
    "    a.legend(loc='upper right')\n",
    "        \n",
    "plt.tight_layout()\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "c27e3768",
   "metadata": {},
   "outputs": [],
   "source": [
    "def fft_cross_correlation(img1, img2):\n",
    "    h, w = img1.shape\n",
    "    \n",
    "    H, W = cv2.getOptimalDFTSize(2*h), cv2.getOptimalDFTSize(2*w)\n",
    "    pad1 = np.zeros((H, W), dtype=np.float32)\n",
    "    pad2 = np.zeros((H, W), dtype=np.float32)\n",
    "    pad1[:h, :w] = img1\n",
    "    pad2[:h, :w] = img2\n",
    "    \n",
    "    dtf1 = cv2.dft(pad1, flags=cv2.DFT_COMPLEX_OUTPUT)\n",
    "    dtf2 = cv2.dft(pad2, flags=cv2.DFT_COMPLEX_OUTPUT)\n",
    "    \n",
    "    cross_power = cv2.mulSpectrums(dtf1, dtf2, 0, conjB=True)\n",
    "    \n",
    "    corr = cv2.idft(cross_power, flags=cv2.DFT_SCALE | cv2.DFT_REAL_OUTPUT)\n",
    "    \n",
    "    corr = np.fft.fftshift(corr)\n",
    "    \n",
    "    max_val = corr.max()\n",
    "    n_img1 = np.linalg.norm(img1)\n",
    "    n_img2 = np.linalg.norm(img2)\n",
    "    sim = max_val / (n_img1 * n_img2)\n",
    "    \n",
    "    return corr, sim\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "c67f6dc9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 365016 characters]",
      "text/plain": [
       "<Figure size 1500x800 with 3 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "similarity: 0.9340651035308838\n"
     ]
    }
   ],
   "source": [
    "corr, sim = fft_cross_correlation(n_img, n_frame)\n",
    "\n",
    "fig, ax = plt.subplots(1, 3, figsize=(15, 8))\n",
    "\n",
    "ax[0].imshow(n_img, cmap=\"gray\")\n",
    "ax[0].set_title(f\"Original Image \")\n",
    "ax[0].axis(\"off\")\n",
    "\n",
    "ax[1].imshow(n_frame, cmap=\"gray\")\n",
    "ax[1].set_title(f\"Frame #{frame_from_time} time: {time_seg}\")\n",
    "ax[1].axis(\"off\")\n",
    "\n",
    "ax[2].imshow(corr)\n",
    "ax[2].set_title(f\"Correlation\")\n",
    "ax[2].axis(\"off\")\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.show()\n",
    "\n",
    "print (f\"similarity: {sim}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "19202604",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 525680 characters]",
      "text/plain": [
       "<Figure size 1500x800 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.93395734\n"
     ]
    }
   ],
   "source": [
    "fig, ax = plt.subplots(1, 2, figsize=(15, 8))\n",
    "\n",
    "ax[0].imshow(n_img, cmap=\"gray\")\n",
    "ax[0].set_title(f\"Original Image {n_img.shape}\")\n",
    "ax[0].axis(\"off\")\n",
    "\n",
    "ax[1].imshow(n_frame, cmap=\"gray\")\n",
    "ax[1].set_title(f\"Frame #{frame_from_time} {n_frame.shape} time: {seconds_to_hms(time_seg)}\")\n",
    "ax[1].axis(\"off\")\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.show()\n",
    "res = cv2.matchTemplate(n_img, n_frame, cv2.TM_CCORR_NORMED), cv2.matchTemplate(n_img, n_frame, cv2.TM_CCORR_NORMED)\n",
    "\n",
    "print(res[0][0][0])"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "pyRARP",
   "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.11.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
