{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "FUNIT_MonsterMirror._v1.ipynb",
      "provenance": [],
      "collapsed_sections": [],
      "toc_visible": true,
      "include_colab_link": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "accelerator": "GPU"
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/mrm8488/shared_colab_notebooks/blob/master/FUNIT_MonsterMirror__v1.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "_PHL6qt3wzLQ",
        "colab_type": "text"
      },
      "source": [
        "# FUNIT Monster Mirror from selfie\n",
        "## Take a selfie and map it to an animal face!\n",
        "based on NVIDIA [Few-Shot Unsupervised Image-to-Image Translation](https://nvlabs.github.io/FUNIT/) and [MonsterMirror](https://github.com/leopd/MonsterMirror)\n",
        "\n",
        "> Colab by [mrm8488](https://twitter.com/mrm8488) https://mrm8488.github.io"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "iR9IPA20zQA2",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "!git clone https://github.com/leopd/MonsterMirror.git"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "jXkHPSSG04x_",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "cd MonsterMirror/"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "FQvGbmH51Kh7",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "!pip install -r requirements.txt"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "w4lK2tpW4OKE",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "!pip install -U PyYAML"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "1mcDS9S98BBZ",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "import cv2\n",
        "import os\n",
        "import numpy as np\n",
        "import sys\n",
        "from google.colab.patches import cv2_imshow"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "O1SEHl7d1emf",
        "colab_type": "text"
      },
      "source": [
        "# Download face detector"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "JBqmwxU61hWd",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "cd pretrained-models"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "HWBplQIH1ht4",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "!wget https://github.com/leopd/SFD_pytorch/releases/download/0.3/s3fd_model.tgz"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "PI8D9JzE1tGX",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "!tar xvzf s3fd_model.tgz\n",
        "!rm s3fd_model.tgz"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "os5_0__4198R",
        "colab_type": "text"
      },
      "source": [
        "# Download GANimal model"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "y-JOD3xV2Adz",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "!gdown https://drive.google.com/uc?id=1CsmSSWyMngtOLUL5lI-sEHVWc2gdJpF9"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "C2I_c0eE2IqO",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "!tar xvzf pretrained.tar.gz\n",
        "!rm pretrained.tar.gz\n",
        "!rm animal119_gen_00100000.pt"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "tbzqtua92lIW",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "cd /content/MonsterMirror"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "-da1XKde4CBw",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "from IPython.display import display, Javascript\n",
        "from google.colab.output import eval_js\n",
        "from base64 import b64decode\n",
        "\n",
        "def take_photo(filename='photo.jpg', quality=0.8):\n",
        "  js = Javascript('''\n",
        "    async function takePhoto(quality) {\n",
        "      const div = document.createElement('div');\n",
        "      const capture = document.createElement('button');\n",
        "      capture.textContent = 'Capture';\n",
        "      div.appendChild(capture);\n",
        "\n",
        "      const video = document.createElement('video');\n",
        "      video.style.display = 'block';\n",
        "      const stream = await navigator.mediaDevices.getUserMedia({video: true});\n",
        "\n",
        "      document.body.appendChild(div);\n",
        "      div.appendChild(video);\n",
        "      video.srcObject = stream;\n",
        "      await video.play();\n",
        "\n",
        "      // Resize the output to fit the video element.\n",
        "      google.colab.output.setIframeHeight(document.documentElement.scrollHeight, true);\n",
        "\n",
        "      // Wait for Capture to be clicked.\n",
        "      await new Promise((resolve) => capture.onclick = resolve);\n",
        "\n",
        "      const canvas = document.createElement('canvas');\n",
        "      canvas.width = video.videoWidth;\n",
        "      canvas.height = video.videoHeight;\n",
        "      canvas.getContext('2d').drawImage(video, 0, 0);\n",
        "      stream.getVideoTracks()[0].stop();\n",
        "      div.remove();\n",
        "      return canvas.toDataURL('image/jpeg', quality);\n",
        "    }\n",
        "    ''')\n",
        "  display(js)\n",
        "  data = eval_js('takePhoto({})'.format(quality))\n",
        "  binary = b64decode(data.split(',')[1])\n",
        "  with open(filename, 'wb') as f:\n",
        "    f.write(binary)\n",
        "  return filename"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "vkt_PuKKxP93",
        "colab_type": "text"
      },
      "source": [
        "# Take a selfie"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "hX74SX735Gjp",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "from IPython.display import Image\n",
        "try:\n",
        "  filename = take_photo()\n",
        "  print('Saved to {}'.format(filename))\n",
        "  \n",
        "  # Show the image which was just taken.\n",
        "  display(Image(filename))\n",
        "except Exception as err:\n",
        "  # Errors will be thrown if the user does not have a webcam or if they do not\n",
        "  # grant the page permission to access it.\n",
        "  print(str(err))"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Jx_TEwyQlFxZ",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "cd /content/MonsterMirror/monster_mirror/"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "fCm3nUrrl7bl",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "__file__ = \"localcam.py\""
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "9ib6YmC0lrS6",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..'))"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "SAuqiQBHmC0l",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "import spooky"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "z9UYvZq4DTst",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "def flip_img(img:np.ndarray) -> np.ndarray:\n",
        "    \"\"\"Mirror image left-right\n",
        "    \"\"\"\n",
        "    return img[:,::-1,:]"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "IZyuBVsQBZ20",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "cd /content/MonsterMirror"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "o6RpD7J5DdeZ",
        "colab_type": "text"
      },
      "source": [
        "# Choose an animal"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "hflADVoHB1eS",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "#@title Choose an animal to map your face\n",
        "\n",
        "option = 'meerkat' #@param [\"meerkat\", \"pomeranian\", \"tiger\"]\n",
        "print(option)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "wryz2WU1mKDE",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "spookifier = spooky.RoundRobinSpookifier(target_image_base=\"/content/MonsterMirror/photo.jpg\", target_classes=\"/content/MonsterMirror/target-images/\" + option +\",/content/MonsterMirror/target-images/\" +option+\",/content/MonsterMirror/target-images/\"+option,noise_drift=0.1,noise_speed=0.4, noise_mag=5)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "KmPE_ACtvHXe",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "im = cv2.imread(\"/content/MonsterMirror/photo.jpg\")\n",
        "img = spookifier.process_npimage(im, None)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "YCetulUcvl6C",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "flipped = flip_img(img)\n",
        "cv2_imshow(flipped)"
      ],
      "execution_count": 0,
      "outputs": []
    }
  ]
}