{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "b0b9ff7b-e43a-4cb9-89e0-8bea2ba5c23c",
   "metadata": {},
   "outputs": [],
   "source": [
    "import cv2\n",
    "import numpy as np\n",
    "import os\n",
    "import tensorflow as tf\n",
    "\n",
    "import random\n",
    "from collections import deque\n",
    "import threading\n",
    "import time\n",
    "\n",
    "import dlib"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "397a2e48-7d21-408f-bf7c-a56386c5005e",
   "metadata": {},
   "outputs": [],
   "source": [
    "class DelayLayer(tf.keras.layers.Layer):\n",
    "    def __init__(self, delay_time=1.0, **kwargs):\n",
    "        super(DelayLayer, self).__init__(**kwargs)\n",
    "        self.delay_time = delay_time\n",
    "\n",
    "    def call(self, inputs, training=None):\n",
    "        if training:\n",
    "            tf.py_function(func=self._delay, inp=[], Tout=[])\n",
    "        return inputs\n",
    "\n",
    "    def _delay(self):\n",
    "        import time\n",
    "        time.sleep(self.delay_time)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "e2870e44-b0ad-4d0d-badb-28313f572e0d",
   "metadata": {},
   "outputs": [],
   "source": [
    "def ssim_metric(y_true, y_pred):\n",
    "    return tf.image.ssim(y_true, y_pred, max_val=1.0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "4a6f2990-f5aa-43c2-9da6-474139d70f21",
   "metadata": {},
   "outputs": [],
   "source": [
    "def psnr_metric(y_true, y_pred):\n",
    "    return tf.image.psnr(y_true, y_pred, max_val=1.0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "9e8b9710-dd2a-4bac-b18b-ab608a7de484",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From C:\\ProgramData\\anaconda3\\Lib\\site-packages\\keras\\src\\backend\\tensorflow\\core.py:204: The name tf.placeholder is deprecated. Please use tf.compat.v1.placeholder instead.\n",
      "\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:absl:Compiled the loaded model, but the compiled metrics have yet to be built. `model.compile_metrics` will be empty until you train or evaluate the model.\n"
     ]
    }
   ],
   "source": [
    "model_path1 = 'model_1_final.h5'\n",
    "model1 = tf.keras.models.load_model(model_path1, custom_objects={'mse':tf.keras.losses.MeanSquaredError(), 'psnr_metric': psnr_metric, 'ssim_metric': ssim_metric, 'DelayLayer':DelayLayer})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "19a9ad0e-a738-420e-b94a-d1452bf72f6f",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:absl:Compiled the loaded model, but the compiled metrics have yet to be built. `model.compile_metrics` will be empty until you train or evaluate the model.\n"
     ]
    }
   ],
   "source": [
    "model_path2 = 'model_2_final.h5'\n",
    "model2 = tf.keras.models.load_model(model_path2, custom_objects={'mse':tf.keras.losses.MeanSquaredError(), 'psnr_metric': psnr_metric, 'ssim_metric': ssim_metric, 'DelayLayer':DelayLayer})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "76584062-85cc-4fdd-9f2c-0807219c9127",
   "metadata": {},
   "outputs": [],
   "source": [
    "def process_roi(roi):\n",
    "    if roi.shape[0] < 35 or roi.shape[1] < 35:\n",
    "        roi = cv2.resize(roi, (25, 25))\n",
    "        img_normalized = roi / 255.0\n",
    "        roi_expanded = np.expand_dims(img_normalized, axis=0)\n",
    "        output1 = model1.predict(roi_expanded, verbose=0) \n",
    "        #output1 = cv2.resize(output1, (50, 50))\n",
    "        output2 = model2.predict(output1, verbose=0)\n",
    "        output2 = np.clip(output2 * 255.0, 0, 255).astype(np.uint8)\n",
    "        output2 = np.squeeze(output2, axis=0)\n",
    "    elif roi.shape[0] < 75 or roi.shape[1] < 75:\n",
    "        roi = cv2.resize(roi, (50, 50))\n",
    "        img_normalized = roi / 255.0\n",
    "        roi_expanded = np.expand_dims(img_normalized, axis=0)\n",
    "        output2 = model2.predict(roi_expanded, verbose=0)\n",
    "        output2 = np.clip(output2 * 255.0, 0, 255).astype(np.uint8)\n",
    "        output2 = np.squeeze(output2, axis=0)\n",
    "    else:\n",
    "        output2 = cv2.resize(roi, (100, 100))\n",
    "\n",
    "    return output2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "ed03375a-32f0-4ad9-97e6-3b03b000a206",
   "metadata": {},
   "outputs": [],
   "source": [
    "cnn_face_detector=dlib.cnn_face_detection_model_v1('mmod_human_face_detector.dat')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "d0e888a7-0190-4b25-8bab-31e9bd0e42dd",
   "metadata": {},
   "outputs": [],
   "source": [
    "def validate_roi_with_dlib(image):\n",
    "    faces = cnn_face_detector(image, 1)\n",
    "    return len(faces) > 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "9a1b456e-3ffa-44cd-860f-e6a015e30915",
   "metadata": {},
   "outputs": [],
   "source": [
    "def auto_correct_brightness(image, alpha=1.5, beta=0):\n",
    "    avg_brightness = np.mean(cv2.cvtColor(image, cv2.COLOR_BGR2GRAY))\n",
    "    if avg_brightness < 100: \n",
    "        corrected_image = cv2.convertScaleAbs(image, alpha=alpha, beta=beta)\n",
    "        return corrected_image\n",
    "    else:\n",
    "        return image"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "29943ca6-023a-450e-8117-e71219071417",
   "metadata": {},
   "outputs": [],
   "source": [
    "face_cascade = cv2.CascadeClassifier('cascade.xml')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4a3e0264-fdab-4386-bac3-6d1541a773d2",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Membaca satu gambar dari file\n",
    "input_image = cv2.imread('input_image.jpg')  # Gantilah dengan path gambar yang ingin Anda proses\n",
    "\n",
    "# Ubah ukuran gambar jika perlu\n",
    "input_image = cv2.resize(input_image, (1440, 810))\n",
    "\n",
    "# Membuat salinan gambar asli untuk anotasi\n",
    "annotated_image = input_image.copy()\n",
    "\n",
    "# Konversi gambar ke grayscale untuk deteksi wajah\n",
    "gray_image = cv2.cvtColor(input_image, cv2.COLOR_BGR2GRAY)\n",
    "\n",
    "# Deteksi wajah\n",
    "faces = face_cascade.detectMultiScale(gray_image, scaleFactor=1.1, minNeighbors=5)\n",
    "faces = faces.tolist()\n",
    "\n",
    "# Memilih wajah untuk diproses secara acak (maksimal 20 wajah)\n",
    "faces_to_process = random.sample(faces, min(20, len(faces)))\n",
    "\n",
    "# Variabel untuk mengecek apakah ada wajah terdeteksi yang divalidasi\n",
    "adafaces = False\n",
    "\n",
    "# Proses setiap wajah yang terdeteksi\n",
    "for (x, y, w, h) in faces_to_process:\n",
    "    # Ambil ROI wajah dari gambar\n",
    "    roi = input_image[y:y+h, x:x+w]\n",
    "    # Gambar kotak di sekitar wajah yang terdeteksi\n",
    "    cv2.rectangle(annotated_image, (x, y), (x + w, y + h), (0, 255, 0), 2)\n",
    "    \n",
    "    # Proses ROI (misalnya resize atau filter)\n",
    "    processed_face = process_roi(roi)\n",
    "    # Auto koreksi kecerahan\n",
    "    processed_face = auto_correct_brightness(processed_face)\n",
    "    \n",
    "    # Validasi ROI menggunakan dlib\n",
    "    if validate_roi_with_dlib(processed_face):\n",
    "        adafaces = True\n",
    "        # Menyimpan hasil ROI terdeteksi dan diproses\n",
    "        cv2.imwrite(f'face_{x}_{y}.jpg', processed_face)\n",
    "        # Tandai wajah terdeteksi pada gambar asli\n",
    "        cv2.rectangle(input_image, (x, y), (x + w, y + h), (0, 255, 0), 2)\n",
    "\n",
    "# Tampilkan hasil gambar menggunakan matplotlib\n",
    "plt.figure(figsize=(12, 8))\n",
    "plt.imshow(cv2.cvtColor(annotated_image, cv2.COLOR_BGR2RGB))\n",
    "plt.title('Hasil Deteksi Wajah dan Proses')\n",
    "plt.axis('off')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "50c552e5-87a3-4b23-b18e-47779827f52c",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
