Ver código fonte

Refactoring embedding of video in notebooks

Jason Antic 6 anos atrás
pai
commit
1d0ae23ec5
3 arquivos alterados com 43 adições e 130 exclusões
  1. 18 64
      VideoColorizer.ipynb
  2. 7 57
      VideoColorizerColab.ipynb
  3. 18 9
      fasterai/visualize.py

+ 18 - 64
VideoColorizer.ipynb

@@ -2,17 +2,17 @@
  "cells": [
   {
    "cell_type": "code",
-   "execution_count": 1,
+   "execution_count": null,
    "metadata": {},
    "outputs": [],
    "source": [
     "import os\n",
-    "os.environ['CUDA_VISIBLE_DEVICES']='3' "
+    "os.environ['CUDA_VISIBLE_DEVICES']='0' "
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 2,
+   "execution_count": null,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -23,7 +23,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 3,
+   "execution_count": null,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -37,83 +37,37 @@
     "#It literally just is a number multiplied by 16 to get the square render resolution.  \n",
     "#Note that this doesn't affect the resolution of the final output- the output is the same resolution as the input.\n",
     "#Example:  render_factor=21 => color is rendered at 16x21 = 336x336 px.  \n",
-    "render_factor=25\n",
+    "render_factor=21\n",
     "#Specify media_url. Many sources will work (YouTube, Imgur, Twitter, Reddit, etc). \n",
     "#Complete list here: https://rg3.github.io/youtube-dl/supportedsites.html. \n",
     "#NOTE:  Make source_url None to just read from file at ./video/source/[file_name] directly without modification\n",
-    "source_url= 'https://twitter.com/silentmoviegifs/status/1112256563182489600'\n",
-    "#source_url=None\n",
-    "file_name = 'TheHighSign1921.mp4'"
+    "#source_url= 'https://twitter.com/silentmoviegifs/status/1112256563182489600'\n",
+    "#source_url='https://archive.org/details/impact'\n",
+    "source_url='https://twitter.com/silentmoviegifs/status/1116751583386034176'\n",
+    "file_name = 'DogBath.mp4'"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 4,
+   "execution_count": null,
    "metadata": {},
-   "outputs": [
-    {
-     "name": "stderr",
-     "output_type": "stream",
-     "text": [
-      "/media/jason/Projects/Deep Learning/DeOldifyV2/DeOldify/fastai/data_block.py:426: UserWarning: Your training set is empty. If this is by design, pass `ignore_empty=True` to remove this warning.\n",
-      "  warn(\"Your training set is empty. If this is by design, pass `ignore_empty=True` to remove this warning.\")\n",
-      "/media/jason/Projects/Deep Learning/DeOldifyV2/DeOldify/fastai/data_block.py:429: UserWarning: Your validation set is empty. If this is by design, use `no_split()`\n",
-      "                 or pass `ignore_empty=True` when labelling to remove this warning.\n",
-      "  or pass `ignore_empty=True` when labelling to remove this warning.\"\"\")\n"
-     ]
-    }
-   ],
+   "outputs": [],
    "source": [
-    "colorizer = get_video_colorizer(render_factor=render_factor)"
+    "colorizer = get_video_colorizer()"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 5,
+   "execution_count": null,
    "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "\n",
-       "    <div>\n",
-       "        <style>\n",
-       "            /* Turns off some styling */\n",
-       "            progress {\n",
-       "                /* gets rid of default border in Firefox and Opera. */\n",
-       "                border: none;\n",
-       "                /* Needs to be in here for Safari polyfill so background images work as expected. */\n",
-       "                background-size: auto;\n",
-       "            }\n",
-       "            .progress-bar-interrupted, .progress-bar-interrupted::-webkit-progress-bar {\n",
-       "                background: #F44336;\n",
-       "            }\n",
-       "        </style>\n",
-       "      <progress value='92' class='' max='92', style='width:300px; height:20px; vertical-align: middle;'></progress>\n",
-       "      100.00% [92/92 00:13<00:00]\n",
-       "    </div>\n",
-       "    "
-      ],
-      "text/plain": [
-       "<IPython.core.display.HTML object>"
-      ]
-     },
-     "metadata": {},
-     "output_type": "display_data"
-    },
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Video created here: video/result/TheHighSign1921.mp4\n"
-     ]
-    }
-   ],
+   "outputs": [],
    "source": [
     "if source_url is not None:\n",
-    "    colorizer.colorize_from_url(source_url, file_name)\n",
+    "    video_path = colorizer.colorize_from_url(source_url, file_name, render_factor=render_factor)\n",
+    "    show_video_in_notebook(video_path)\n",
     "else:\n",
-    "    colorizer.colorize_from_file_name(file_name)"
+    "    video_path = colorizer.colorize_from_file_name(file_name)\n",
+    "    show_video_in_notebook(video_path)"
    ]
   },
   {

+ 7 - 57
VideoColorizerColab.ipynb

@@ -138,8 +138,6 @@
     "import fastai\n",
     "from fasterai.visualize import *\n",
     "from pathlib import Path\n",
-    "import base64\n",
-    "from IPython import display as ipythondisplay\n",
     "torch.backends.cudnn.benchmark=True"
    ]
   },
@@ -153,28 +151,6 @@
     "!wget https://www.dropbox.com/s/336vn9y4qwyg9yz/ColorizeVideo_gen.pth?dl=0 -O ./models/ColorizeVideo_gen.pth"
    ]
   },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "file_name = 'video.mp4'\n",
-    "source_dir = './video/source/'\n",
-    "source_path = source_dir + file_name\n",
-    "dest_dir = './video/result/'\n",
-    "dest_path = dest_dir + file_name"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "!mkdir file_dir"
-   ]
-  },
   {
    "cell_type": "code",
    "execution_count": null,
@@ -188,21 +164,6 @@
     "colorizer = get_video_colorizer()"
    ]
   },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "def show_video():\n",
-    "    video = io.open(dest_path, 'r+b').read()\n",
-    "    encoded = base64.b64encode(video)\n",
-    "    ipythondisplay.display(HTML(data='''<video alt=\"test\" autoplay \n",
-    "                loop controls style=\"height: 400px;\">\n",
-    "                <source src=\"data:video/mp4;base64,{0}\" type=\"video/mp4\" />\n",
-    "             </video>'''.format(encoded.decode('ascii'))))"
-   ]
-  },
   {
    "cell_type": "markdown",
    "metadata": {
@@ -220,10 +181,13 @@
     "### Instructions\n",
     "\n",
     "#### source_url\n",
-    "YouTube, Imgur, Twitter, Reddit ... files of type .gif, .gifv and .mp4 work. NOTE: If you want to use your own video, upload it first to a site like YouTube. \n",
+    "YouTube, Imgur, Twitter, Reddit, Vimeo, etc.  Many sources work!  GIFs also work.  Full list here: https://ytdl-org.github.io/youtube-dl/supportedsites.html NOTE: If you want to use your own video, upload it first to a site like YouTube. \n",
     "\n",
     "#### render_factor\n",
-    "The default value of 21 has been carefully chosen and should work -ok- for most scenarios (but probably won't be the -best-). This determines resolution at which video is rendered. Lower resolution will render faster, and colors also tend to look more vibrant. Older and lower quality film in particular will generally benefit by lowering the render factor. Higher render factors are often better for higher quality videos and inconsistencies (flashy render) will generally be reduced, but the colors may get slightly washed out. "
+    "The default value of 21 has been carefully chosen and should work -ok- for most scenarios (but probably won't be the -best-). This determines resolution at which video is rendered. Lower resolution will render faster, and colors also tend to look more vibrant. Older and lower quality film in particular will generally benefit by lowering the render factor. Higher render factors are often better for higher quality videos and inconsistencies (flashy render) will generally be reduced, but the colors may get slightly washed out. \n",
+    "\n",
+    "#### How to Download a Copy\n",
+    "Simply right click on the displayed video and click \"Save video as...\"!"
    ]
   },
   {
@@ -236,26 +200,12 @@
     "render_factor = 21  #@param {type: \"slider\", min: 7, max: 46}\n",
     "\n",
     "if source_url is not None and source_url !='':\n",
-    "    colorizer.colorize_from_url(source_url, file_name, render_factor)\n",
-    "    show_video()\n",
+    "    video_path = colorizer.colorize_from_url(source_url, 'video.mp4', render_factor)\n",
+    "    show_video_in_notebook(video_path)\n",
     "else:\n",
     "    print('Provide a video url and try again.')"
    ]
   },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "colab_type": "text",
-    "id": "A5WMS_GgP4fm"
-   },
-   "source": [
-    "#◢ Download\n",
-    "\n",
-    "* In the menu to the left, click **Files**\n",
-    "* If you don't see the 'DeOldify' folder, click \"Refresh\"\n",
-    "* By default, rendered video will be in /DeOldify/video/result/"
-   ]
-  },
   {
    "cell_type": "markdown",
    "metadata": {

+ 18 - 9
fasterai/visualize.py

@@ -5,7 +5,6 @@ from matplotlib.figure import Figure
 from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
 from .filters import IFilter, MasterFilter, ColorizerFilter
 from .generators import gen_inference_deep, gen_inference_wide
-from IPython.display import display
 from tensorboardX import SummaryWriter
 from scipy import misc
 from PIL import Image 
@@ -14,6 +13,9 @@ import youtube_dl
 import gc
 import requests
 from io import BytesIO
+import base64
+from IPython import display as ipythondisplay
+from IPython.display import HTML
 
 
 class ModelImageVisualizer():
@@ -122,7 +124,7 @@ class VideoColorizer():
                 color_image = self.vis.get_transformed_image(str(img_path), render_factor=render_factor)
                 color_image.save(str(colorframes_folder/img))
     
-    def _build_video(self, source_path:Path):
+    def _build_video(self, source_path:Path)->str:
         result_path = self.result_folder/source_path.name
         colorframes_folder = self.colorframes_root/(source_path.stem)
         colorframes_path_template = str(colorframes_folder/'%5d.jpg')
@@ -135,23 +137,24 @@ class VideoColorizer():
             .run(capture_stdout=True)
         
         print('Video created here: ' + str(result_path))
+        return result_path
 
-    def colorize_from_url(self, source_url, file_name:str, render_factor:int=None): 
+    def colorize_from_url(self, source_url, file_name:str, render_factor:int=None)->str: 
         source_path =  self.source_folder/file_name
         self._download_video_from_url(source_url, source_path)
-        self._colorize_from_path(source_path, render_factor=render_factor)
+        return self._colorize_from_path(source_path, render_factor=render_factor)
 
-    def colorize_from_file_name(self, file_name:str, render_factor:int=None):
+    def colorize_from_file_name(self, file_name:str, render_factor:int=None)->str:
         source_path =  self.source_folder/file_name
-        self._colorize_from_path(source_path, render_factor=render_factor)
+        return self._colorize_from_path(source_path, render_factor=render_factor)
 
-    def _colorize_from_path(self, source_path:Path, render_factor:int=None):
+    def _colorize_from_path(self, source_path:Path, render_factor:int=None)->str:
         if not source_path.exists():
             raise Exception('Video at path specfied, ' + str(source_path) + ' could not be found.')
 
         self._extract_raw_frames(source_path)
         self._colorize_raw_frames(source_path, render_factor=render_factor)
-        self._build_video(source_path)
+        return self._build_video(source_path)
 
 
 def get_video_colorizer(render_factor:int=21)->VideoColorizer:
@@ -184,6 +187,12 @@ def get_artistic_image_colorizer(root_folder:Path=Path('./'), weights_name:str='
     vis = ModelImageVisualizer(filtr, results_dir=results_dir)
     return vis
 
-
+def show_video_in_notebook(video_path:str):
+    video = io.open(video_path, 'r+b').read()
+    encoded = base64.b64encode(video)
+    ipythondisplay.display(HTML(data='''<video alt="test" autoplay 
+                loop controls style="height: 400px;">
+                <source src="data:video/mp4;base64,{0}" type="video/mp4" />
+             </video>'''.format(encoded.decode('ascii'))))