diff --git a/.ipynb_checkpoints/Emotion Detector-checkpoint.ipynb b/.ipynb_checkpoints/Emotion Detector-checkpoint.ipynb new file mode 100644 index 0000000000..42f55a9fe0 --- /dev/null +++ b/.ipynb_checkpoints/Emotion Detector-checkpoint.ipynb @@ -0,0 +1,136 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Using TensorFlow backend.\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "import tensorflow as tf\n", + "import sklearn\n", + "import gradio\n", + "from keras.models import Sequential\n", + "from keras.layers import Dense, Dropout, Activation, Flatten\n", + "from keras.layers import Conv2D, MaxPooling2D, BatchNormalization\n", + "from keras.losses import categorical_crossentropy\n", + "from keras.optimizers import Adam\n", + "from keras.regularizers import l2\n", + "from keras.callbacks import ReduceLROnPlateau, TensorBoard, EarlyStopping, ModelCheckpoint\n", + "from keras.models import load_model\n", + "\n", + "\n", + "%load_ext autoreload\n", + "%autoreload 2" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "WARNING:tensorflow:From C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\tensorflow\\python\\framework\\op_def_library.py:263: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.\n", + "Instructions for updating:\n", + "Colocations handled automatically by placer.\n", + "WARNING:tensorflow:From C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\keras\\backend\\tensorflow_backend.py:3445: calling dropout (from tensorflow.python.ops.nn_ops) with keep_prob is deprecated and will be removed in a future version.\n", + "Instructions for updating:\n", + "Please use `rate` instead of `keep_prob`. Rate should be set to `rate = 1 - keep_prob`.\n", + "WARNING:tensorflow:From C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\tensorflow\\python\\ops\\math_ops.py:3066: to_int32 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\n", + "Instructions for updating:\n", + "Use tf.cast instead.\n" + ] + } + ], + "source": [ + "model = load_model('model.h5') # found random emotion detector model on github ''(its not very accurate)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\ALI\\Desktop\\gradiome\\gradio.py:191: UserWarning: No parser was explicitly specified, so I'm using the best available HTML parser for this system (\"lxml\"). This usually isn't a problem, but if you run this code on another system, or in a different virtual environment, it may use a different parser and behave differently.\n", + "\n", + "The code that caused this warning is on line 191 of the file C:\\Users\\ALI\\Desktop\\gradiome\\gradio.py. To get rid of this warning, pass the additional argument 'features=\"lxml\"' to the BeautifulSoup constructor.\n", + "\n", + " input_soup = BeautifulSoup(input_page.read())\n", + "C:\\Users\\ALI\\Desktop\\gradiome\\gradio.py:192: UserWarning: No parser was explicitly specified, so I'm using the best available HTML parser for this system (\"lxml\"). This usually isn't a problem, but if you run this code on another system, or in a different virtual environment, it may use a different parser and behave differently.\n", + "\n", + "The code that caused this warning is on line 192 of the file C:\\Users\\ALI\\Desktop\\gradiome\\gradio.py. To get rid of this warning, pass the additional argument 'features=\"lxml\"' to the BeautifulSoup constructor.\n", + "\n", + " output_soup = BeautifulSoup(output_page.read())\n", + "C:\\Users\\ALI\\Desktop\\gradiome\\gradio.py:196: UserWarning: No parser was explicitly specified, so I'm using the best available HTML parser for this system (\"lxml\"). This usually isn't a problem, but if you run this code on another system, or in a different virtual environment, it may use a different parser and behave differently.\n", + "\n", + "The code that caused this warning is on line 196 of the file C:\\Users\\ALI\\Desktop\\gradiome\\gradio.py. To get rid of this warning, pass the additional argument 'features=\"lxml\"' to the BeautifulSoup constructor.\n", + "\n", + " all_io_soup = BeautifulSoup(all_io_page.read())\n", + "Error in connection handler\n", + "Traceback (most recent call last):\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\server.py\", line 169, in handler\n", + " yield from self.ws_handler(self, path)\n", + " File \"C:\\Users\\ALI\\Desktop\\gradiome\\gradio.py\", line 223, in communicate\n", + " processed_input = self.input_interface._pre_process(await websocket.recv())\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 434, in recv\n", + " yield from self.ensure_open()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 646, in ensure_open\n", + " ) from self.transfer_data_exc\n", + "websockets.exceptions.ConnectionClosed: WebSocket connection is closed: code = 1001 (going away), no reason\n", + "Error in connection handler\n", + "Traceback (most recent call last):\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\server.py\", line 169, in handler\n", + " yield from self.ws_handler(self, path)\n", + " File \"C:\\Users\\ALI\\Desktop\\gradiome\\gradio.py\", line 223, in communicate\n", + " processed_input = self.input_interface._pre_process(await websocket.recv())\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 434, in recv\n", + " yield from self.ensure_open()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 646, in ensure_open\n", + " ) from self.transfer_data_exc\n", + "websockets.exceptions.ConnectionClosed: WebSocket connection is closed: code = 1001 (going away), no reason\n" + ] + } + ], + "source": [ + "iface = gradio.Interface(input='sketchpad',output='class',model_obj=model, model_type='keras')\n", + "iface.launch()" + ] + } + ], + "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.7.1" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Emotion Detector.ipynb b/Emotion Detector.ipynb new file mode 100644 index 0000000000..c77b3511cf --- /dev/null +++ b/Emotion Detector.ipynb @@ -0,0 +1,125 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Using TensorFlow backend.\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "import tensorflow as tf\n", + "import sklearn\n", + "import gradio\n", + "from keras.models import Sequential\n", + "from keras.layers import Dense, Dropout, Activation, Flatten\n", + "from keras.layers import Conv2D, MaxPooling2D, BatchNormalization\n", + "from keras.losses import categorical_crossentropy\n", + "from keras.optimizers import Adam\n", + "from keras.regularizers import l2\n", + "from keras.callbacks import ReduceLROnPlateau, TensorBoard, EarlyStopping, ModelCheckpoint\n", + "from keras.models import load_model\n", + "\n", + "\n", + "%load_ext autoreload\n", + "%autoreload 2" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "WARNING:tensorflow:From C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\tensorflow\\python\\framework\\op_def_library.py:263: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.\n", + "Instructions for updating:\n", + "Colocations handled automatically by placer.\n", + "WARNING:tensorflow:From C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\keras\\backend\\tensorflow_backend.py:3445: calling dropout (from tensorflow.python.ops.nn_ops) with keep_prob is deprecated and will be removed in a future version.\n", + "Instructions for updating:\n", + "Please use `rate` instead of `keep_prob`. Rate should be set to `rate = 1 - keep_prob`.\n", + "WARNING:tensorflow:From C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\tensorflow\\python\\ops\\math_ops.py:3066: to_int32 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\n", + "Instructions for updating:\n", + "Use tf.cast instead.\n" + ] + } + ], + "source": [ + "model = load_model('model.h5') # found random emotion detector model on github ''(its not very accurate)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\ALI\\Desktop\\gradiome\\gradio.py:191: UserWarning: No parser was explicitly specified, so I'm using the best available HTML parser for this system (\"lxml\"). This usually isn't a problem, but if you run this code on another system, or in a different virtual environment, it may use a different parser and behave differently.\n", + "\n", + "The code that caused this warning is on line 191 of the file C:\\Users\\ALI\\Desktop\\gradiome\\gradio.py. To get rid of this warning, pass the additional argument 'features=\"lxml\"' to the BeautifulSoup constructor.\n", + "\n", + " input_soup = BeautifulSoup(input_page.read())\n", + "C:\\Users\\ALI\\Desktop\\gradiome\\gradio.py:192: UserWarning: No parser was explicitly specified, so I'm using the best available HTML parser for this system (\"lxml\"). This usually isn't a problem, but if you run this code on another system, or in a different virtual environment, it may use a different parser and behave differently.\n", + "\n", + "The code that caused this warning is on line 192 of the file C:\\Users\\ALI\\Desktop\\gradiome\\gradio.py. To get rid of this warning, pass the additional argument 'features=\"lxml\"' to the BeautifulSoup constructor.\n", + "\n", + " output_soup = BeautifulSoup(output_page.read())\n", + "C:\\Users\\ALI\\Desktop\\gradiome\\gradio.py:196: UserWarning: No parser was explicitly specified, so I'm using the best available HTML parser for this system (\"lxml\"). This usually isn't a problem, but if you run this code on another system, or in a different virtual environment, it may use a different parser and behave differently.\n", + "\n", + "The code that caused this warning is on line 196 of the file C:\\Users\\ALI\\Desktop\\gradiome\\gradio.py. To get rid of this warning, pass the additional argument 'features=\"lxml\"' to the BeautifulSoup constructor.\n", + "\n", + " all_io_soup = BeautifulSoup(all_io_page.read())\n", + "Error in connection handler\n", + "Traceback (most recent call last):\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\server.py\", line 169, in handler\n", + " yield from self.ws_handler(self, path)\n", + " File \"C:\\Users\\ALI\\Desktop\\gradiome\\gradio.py\", line 223, in communicate\n", + " processed_input = self.input_interface._pre_process(await websocket.recv())\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 434, in recv\n", + " yield from self.ensure_open()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 646, in ensure_open\n", + " ) from self.transfer_data_exc\n", + "websockets.exceptions.ConnectionClosed: WebSocket connection is closed: code = 1001 (going away), no reason\n" + ] + } + ], + "source": [ + "iface = gradio.Interface(input='webcam',output='class',model_obj=model, model_type='keras')\n", + "iface.launch()" + ] + } + ], + "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.7.1" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Usage.ipynb b/Usage.ipynb index 75fb0782e6..b8b91ce68c 100644 --- a/Usage.ipynb +++ b/Usage.ipynb @@ -16,7 +16,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -38,15 +38,22 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch 1/1\n", - "60000/60000 [==============================] - 25s 417us/step - loss: 0.2184 - acc: 0.9352\n", - "10000/10000 [==============================] - 1s 89us/step\n" + "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz\n", + "11493376/11490434 [==============================] - 7s 1us/step\n", + "WARNING:tensorflow:From C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\tensorflow\\python\\ops\\resource_variable_ops.py:435: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.\n", + "Instructions for updating:\n", + "Colocations handled automatically by placer.\n", + "WARNING:tensorflow:From C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\tensorflow\\python\\keras\\layers\\core.py:143: calling dropout (from tensorflow.python.ops.nn_ops) with keep_prob is deprecated and will be removed in a future version.\n", + "Instructions for updating:\n", + "Please use `rate` instead of `keep_prob`. Rate should be set to `rate = 1 - keep_prob`.\n", + "60000/60000 [==============================] - 25s 413us/sample - loss: 0.2209 - acc: 0.9343\n", + "10000/10000 [==============================] - 1s 72us/sample - loss: 0.0958 - acc: 0.9712\n" ] }, { "data": { "text/plain": [ - "[0.10298147459961474, 0.9698]" + "[0.09579291099403053, 0.9712]" ] }, "execution_count": 4, @@ -83,15 +90,203 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, "outputs": [ { - "name": "stdout", + "ename": "OSError", + "evalue": "[Errno 10048] error while attempting to bind on address ('127.0.0.1', 5679): only one usage of each socket address (protocol/network address/port) is normally permitted", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mOSError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mgradio\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mDrawADigit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmodel_obj\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mmodel\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmodel_type\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'keras'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstart\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[1;32m~\\Desktop\\gradiome\\gradio.py\u001b[0m in \u001b[0;36mstart\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 124\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 125\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mstart\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 126\u001b[1;33m \u001b[0msuper\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstart\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 127\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 128\u001b[0m \u001b[1;32masync\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mcommunicate\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mwebsocket\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpath\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32m~\\Desktop\\gradiome\\gradio.py\u001b[0m in \u001b[0;36mstart\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 90\u001b[0m \u001b[0mwebbrowser\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mopen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'file://'\u001b[0m \u001b[1;33m+\u001b[0m \u001b[0mos\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mpath\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrealpath\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_get_template_path\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 91\u001b[0m \u001b[0mstart_server\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mwebsockets\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mserve\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcommunicate\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mLOCALHOST_IP\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mSOCKET_PORT\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 92\u001b[1;33m \u001b[0masyncio\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mget_event_loop\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrun_until_complete\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mstart_server\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 93\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 94\u001b[0m \u001b[0masyncio\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mget_event_loop\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrun_forever\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32m~\\Anaconda3\\lib\\site-packages\\nest_asyncio.py\u001b[0m in \u001b[0;36mrun_until_complete\u001b[1;34m(self, future)\u001b[0m\n\u001b[0;32m 59\u001b[0m \u001b[1;32mwhile\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0mf\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdone\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 60\u001b[0m \u001b[0mrun_once\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 61\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mf\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mresult\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 62\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 63\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_run_until_complete_orig\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfuture\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32m~\\Anaconda3\\lib\\asyncio\\futures.py\u001b[0m in \u001b[0;36mresult\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 176\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__log_traceback\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;32mFalse\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 177\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_exception\u001b[0m \u001b[1;32mis\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 178\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_exception\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 179\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_result\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 180\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32m~\\Anaconda3\\lib\\asyncio\\tasks.py\u001b[0m in \u001b[0;36m__step\u001b[1;34m(***failed resolving arguments***)\u001b[0m\n\u001b[0;32m 221\u001b[0m \u001b[1;31m# We use the `send` method directly, because coroutines\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 222\u001b[0m \u001b[1;31m# don't have `__iter__` and `__next__` methods.\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 223\u001b[1;33m \u001b[0mresult\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mcoro\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msend\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;32mNone\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 224\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 225\u001b[0m \u001b[0mresult\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mcoro\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mthrow\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mexc\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32m~\\Anaconda3\\lib\\asyncio\\tasks.py\u001b[0m in \u001b[0;36m_wrap_awaitable\u001b[1;34m(awaitable)\u001b[0m\n\u001b[0;32m 601\u001b[0m \u001b[0mthat\u001b[0m \u001b[0mwill\u001b[0m \u001b[0mlater\u001b[0m \u001b[0mbe\u001b[0m \u001b[0mwrapped\u001b[0m \u001b[1;32min\u001b[0m \u001b[0ma\u001b[0m \u001b[0mTask\u001b[0m \u001b[0mby\u001b[0m \u001b[0mensure_future\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 602\u001b[0m \"\"\"\n\u001b[1;32m--> 603\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[1;33m(\u001b[0m\u001b[1;32myield\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mawaitable\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__await__\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 604\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 605\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32m~\\Anaconda3\\lib\\site-packages\\websockets\\py35\\server.py\u001b[0m in \u001b[0;36m__await_impl__\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 11\u001b[0m \u001b[1;31m# Duplicated with __iter__ because Python 3.7 requires an async function\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 12\u001b[0m \u001b[1;31m# (as explained in __await__ below) which Python 3.4 doesn't support.\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 13\u001b[1;33m \u001b[0mserver\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;32mawait\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_creating_server\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 14\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mws_server\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwrap\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mserver\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 15\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mws_server\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32m~\\Anaconda3\\lib\\asyncio\\base_events.py\u001b[0m in \u001b[0;36mcreate_server\u001b[1;34m(self, protocol_factory, host, port, family, flags, sock, backlog, ssl, reuse_address, reuse_port, ssl_handshake_timeout, start_serving)\u001b[0m\n\u001b[0;32m 1365\u001b[0m raise OSError(err.errno, 'error while attempting '\n\u001b[0;32m 1366\u001b[0m \u001b[1;34m'to bind on address %r: %s'\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 1367\u001b[1;33m % (sa, err.strerror.lower())) from None\n\u001b[0m\u001b[0;32m 1368\u001b[0m \u001b[0mcompleted\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;32mTrue\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1369\u001b[0m \u001b[1;32mfinally\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mOSError\u001b[0m: [Errno 10048] error while attempting to bind on address ('127.0.0.1', 5679): only one usage of each socket address (protocol/network address/port) is normally permitted" + ] + }, + { + "name": "stderr", "output_type": "stream", "text": [ - "Using keras model\n", - "Using keras model\n" + "Error in connection handler\n", + "Traceback (most recent call last):\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\server.py\", line 169, in handler\n", + " yield from self.ws_handler(self, path)\n", + " File \"C:\\Users\\ALI\\Desktop\\gradiome\\gradio.py\", line 135, in communicate\n", + " imgstring = await websocket.recv()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 434, in recv\n", + " yield from self.ensure_open()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 658, in ensure_open\n", + " ) from self.transfer_data_exc\n", + "websockets.exceptions.ConnectionClosed: WebSocket connection is closed: code = 1001 (going away), no reason\n", + "Error in connection handler\n", + "Traceback (most recent call last):\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\server.py\", line 169, in handler\n", + " yield from self.ws_handler(self, path)\n", + " File \"C:\\Users\\ALI\\Desktop\\gradiome\\gradio.py\", line 135, in communicate\n", + " imgstring = await websocket.recv()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 434, in recv\n", + " yield from self.ensure_open()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 646, in ensure_open\n", + " ) from self.transfer_data_exc\n", + "websockets.exceptions.ConnectionClosed: WebSocket connection is closed: code = 1001 (going away), no reason\n", + "Error in connection handler\n", + "Traceback (most recent call last):\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\server.py\", line 169, in handler\n", + " yield from self.ws_handler(self, path)\n", + " File \"C:\\Users\\ALI\\Desktop\\gradiome\\gradio.py\", line 135, in communicate\n", + " imgstring = await websocket.recv()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 434, in recv\n", + " yield from self.ensure_open()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 646, in ensure_open\n", + " ) from self.transfer_data_exc\n", + "websockets.exceptions.ConnectionClosed: WebSocket connection is closed: code = 1001 (going away), no reason\n", + "Error in connection handler\n", + "Traceback (most recent call last):\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\server.py\", line 169, in handler\n", + " yield from self.ws_handler(self, path)\n", + " File \"C:\\Users\\ALI\\Desktop\\gradiome\\gradio.py\", line 135, in communicate\n", + " imgstring = await websocket.recv()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 434, in recv\n", + " yield from self.ensure_open()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 646, in ensure_open\n", + " ) from self.transfer_data_exc\n", + "websockets.exceptions.ConnectionClosed: WebSocket connection is closed: code = 1001 (going away), no reason\n", + "Error in connection handler\n", + "Traceback (most recent call last):\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\server.py\", line 169, in handler\n", + " yield from self.ws_handler(self, path)\n", + " File \"C:\\Users\\ALI\\Desktop\\gradiome\\gradio.py\", line 135, in communicate\n", + " imgstring = await websocket.recv()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 434, in recv\n", + " yield from self.ensure_open()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 646, in ensure_open\n", + " ) from self.transfer_data_exc\n", + "websockets.exceptions.ConnectionClosed: WebSocket connection is closed: code = 1001 (going away), no reason\n", + "Error in connection handler\n", + "Traceback (most recent call last):\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\server.py\", line 169, in handler\n", + " yield from self.ws_handler(self, path)\n", + " File \"C:\\Users\\ALI\\Desktop\\gradiome\\gradio.py\", line 135, in communicate\n", + " imgstring = await websocket.recv()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 434, in recv\n", + " yield from self.ensure_open()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 646, in ensure_open\n", + " ) from self.transfer_data_exc\n", + "websockets.exceptions.ConnectionClosed: WebSocket connection is closed: code = 1001 (going away), no reason\n", + "Error in connection handler\n", + "Traceback (most recent call last):\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\server.py\", line 169, in handler\n", + " yield from self.ws_handler(self, path)\n", + " File \"C:\\Users\\ALI\\Desktop\\gradiome\\gradio.py\", line 135, in communicate\n", + " imgstring = await websocket.recv()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 434, in recv\n", + " yield from self.ensure_open()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 658, in ensure_open\n", + " ) from self.transfer_data_exc\n", + "websockets.exceptions.ConnectionClosed: WebSocket connection is closed: code = 1001 (going away), no reason\n", + "Error in connection handler\n", + "Traceback (most recent call last):\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\server.py\", line 169, in handler\n", + " yield from self.ws_handler(self, path)\n", + " File \"C:\\Users\\ALI\\Desktop\\gradiome\\gradio.py\", line 135, in communicate\n", + " imgstring = await websocket.recv()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 434, in recv\n", + " yield from self.ensure_open()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 646, in ensure_open\n", + " ) from self.transfer_data_exc\n", + "websockets.exceptions.ConnectionClosed: WebSocket connection is closed: code = 1001 (going away), no reason\n", + "Error in connection handler\n", + "Traceback (most recent call last):\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\server.py\", line 169, in handler\n", + " yield from self.ws_handler(self, path)\n", + " File \"C:\\Users\\ALI\\Desktop\\gradiome\\gradio.py\", line 135, in communicate\n", + " imgstring = await websocket.recv()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 434, in recv\n", + " yield from self.ensure_open()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 646, in ensure_open\n", + " ) from self.transfer_data_exc\n", + "websockets.exceptions.ConnectionClosed: WebSocket connection is closed: code = 1001 (going away), no reason\n", + "Error in connection handler\n", + "Traceback (most recent call last):\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\server.py\", line 169, in handler\n", + " yield from self.ws_handler(self, path)\n", + " File \"C:\\Users\\ALI\\Desktop\\gradiome\\gradio.py\", line 135, in communicate\n", + " imgstring = await websocket.recv()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 434, in recv\n", + " yield from self.ensure_open()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 646, in ensure_open\n", + " ) from self.transfer_data_exc\n", + "websockets.exceptions.ConnectionClosed: WebSocket connection is closed: code = 1001 (going away), no reason\n", + "Error in connection handler\n", + "Traceback (most recent call last):\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\server.py\", line 169, in handler\n", + " yield from self.ws_handler(self, path)\n", + " File \"C:\\Users\\ALI\\Desktop\\gradiome\\gradio.py\", line 135, in communicate\n", + " imgstring = await websocket.recv()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 434, in recv\n", + " yield from self.ensure_open()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 646, in ensure_open\n", + " ) from self.transfer_data_exc\n", + "websockets.exceptions.ConnectionClosed: WebSocket connection is closed: code = 1001 (going away), no reason\n", + "Error in connection handler\n", + "Traceback (most recent call last):\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\server.py\", line 169, in handler\n", + " yield from self.ws_handler(self, path)\n", + " File \"C:\\Users\\ALI\\Desktop\\gradiome\\gradio.py\", line 135, in communicate\n", + " imgstring = await websocket.recv()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 434, in recv\n", + " yield from self.ensure_open()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 646, in ensure_open\n", + " ) from self.transfer_data_exc\n", + "websockets.exceptions.ConnectionClosed: WebSocket connection is closed: code = 1001 (going away), no reason\n", + "Error in connection handler\n", + "Traceback (most recent call last):\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\server.py\", line 169, in handler\n", + " yield from self.ws_handler(self, path)\n", + " File \"C:\\Users\\ALI\\Desktop\\gradiome\\gradio.py\", line 135, in communicate\n", + " imgstring = await websocket.recv()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 434, in recv\n", + " yield from self.ensure_open()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 658, in ensure_open\n", + " ) from self.transfer_data_exc\n", + "websockets.exceptions.ConnectionClosed: WebSocket connection is closed: code = 1001 (going away), no reason\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Error in connection handler\n", + "Traceback (most recent call last):\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\server.py\", line 169, in handler\n", + " yield from self.ws_handler(self, path)\n", + " File \"C:\\Users\\ALI\\Desktop\\gradiome\\gradio.py\", line 135, in communicate\n", + " imgstring = await websocket.recv()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 434, in recv\n", + " yield from self.ensure_open()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 658, in ensure_open\n", + " ) from self.transfer_data_exc\n", + "websockets.exceptions.ConnectionClosed: WebSocket connection is closed: code = 1001 (going away), no reason\n", + "Error in connection handler\n", + "Traceback (most recent call last):\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\server.py\", line 169, in handler\n", + " yield from self.ws_handler(self, path)\n", + " File \"C:\\Users\\ALI\\Desktop\\gradiome\\gradio.py\", line 135, in communicate\n", + " imgstring = await websocket.recv()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 434, in recv\n", + " yield from self.ensure_open()\n", + " File \"C:\\Users\\ALI\\Anaconda3\\lib\\site-packages\\websockets\\protocol.py\", line 646, in ensure_open\n", + " ) from self.transfer_data_exc\n", + "websockets.exceptions.ConnectionClosed: WebSocket connection is closed: code = 1001 (going away), no reason\n" ] } ], @@ -102,9 +297,9 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3.6 (tensorflow)", + "display_name": "Python 3", "language": "python", - "name": "tensorflow" + "name": "python3" }, "language_info": { "codemirror_mode": { @@ -116,7 +311,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.7" + "version": "3.7.1" } }, "nbformat": 4, diff --git a/gradio.py b/gradio.py index ba838e0eaf..b0a649536e 100644 --- a/gradio.py +++ b/gradio.py @@ -8,11 +8,13 @@ from io import BytesIO import numpy as np import os import webbrowser +from bs4 import BeautifulSoup nest_asyncio.apply() LOCALHOST_IP = '127.0.0.1' -SOCKET_PORT = 5679 +SOCKET_PORT = 5680 + def resize_and_crop(img, size, crop_type='top'): @@ -67,33 +69,38 @@ def resize_and_crop(img, size, crop_type='top'): return img -class AbstractInterface(ABC): +class AbstractInput(ABC): """ - An abstract class for defining the methods that all gradio interfaces should have. + An abstract class for defining the methods that all gradio inputs should have. """ - def __init__(self, model_type, model_obj, **model_params): - """ - :param model_type: what kind of trained model, can be 'keras' or 'sklearn'. - :param model_obj: the model object, such as a sklearn classifier or keras model. - :param model_params: additional model parameters. - """ - self.model_type = model_type - self.model_obj = model_obj - self.model_params = model_params + def __init__(self): super().__init__() - def start(self): + + @abstractmethod + def _get_template_path(self): """ - Standard method shared by interfaces that launches a websocket at a specified IP address. + All interfaces should define a method that returns the path to its template. """ - webbrowser.open('file://' + os.path.realpath(self._get_template_path())) - start_server = websockets.serve(self.communicate, LOCALHOST_IP, SOCKET_PORT) - asyncio.get_event_loop().run_until_complete(start_server) - try: - asyncio.get_event_loop().run_forever() - except RuntimeError: # Runtime errors are thrown in jupyter notebooks because of async. - pass + pass + + @abstractmethod + def _pre_process(self): + """ + All interfaces should define a method that returns the path to its template. + """ + pass + +class AbstractOutput(ABC): + """ + An abstract class for defining the methods that all gradio inputs should have. + """ + + def __init__(self): + """ + """ + super().__init__() @abstractmethod def _get_template_path(self): @@ -103,14 +110,100 @@ class AbstractInterface(ABC): pass @abstractmethod - async def communicate(self, websocket, path): + def _post_process(self): """ - All interfaces should define a custom method that defines how they communicate with the websocket. + All interfaces should define a method that returns the path to its template. """ pass -class DrawADigit(AbstractInterface): +class Sketchpad(AbstractInput): + + def _get_template_path(self): + return 'templates/sketchpad_input.html' + + def _pre_process(self, imgstring): + """ + """ + content = imgstring.split(';')[1] + image_encoded = content.split(',')[1] + body = base64.decodebytes(image_encoded.encode('utf-8')) + im = Image.open(BytesIO(base64.b64decode(image_encoded))).convert('L') + im = resize_and_crop(im, (28, 28)) + array = np.array(im).flatten().reshape(1, -1) + return array + + +class Webcam(AbstractInput): + + def _get_template_path(self): + return 'templates/webcam_input.html' + + def _pre_process(self, imgstring): + """ + """ + content = imgstring.split(';')[1] + image_encoded = content.split(',')[1] + body = base64.decodebytes(image_encoded.encode('utf-8')) + im = Image.open(BytesIO(base64.b64decode(image_encoded))).convert('L') + im = resize_and_crop(im, (48, 48)) + array = np.array(im).flatten().reshape(1,48,48,1) + return array + +class Class(AbstractOutput): + + def _get_template_path(self): + return 'templates/class_output.html' + + def _post_process(self, prediction): + """ + """ + emotion_dict = {0: "Angry", 1: "Disgust", 2: "Fear", 3: "Happy", 4: "Sad", 5: "Surprise", 6: "Neutral"} + return emotion_dict[prediction] + +registry = { + 'webcam':Webcam, + 'sketchpad' :Sketchpad, + 'class' :Class, +} + +class Interface(): + """ + """ + + def __init__(self, input, output, model_obj, model_type, **model_params): + """ + :param model_type: what kind of trained model, can be 'keras' or 'sklearn'. + :param model_obj: the model object, such as a sklearn classifier or keras model. + :param model_params: additional model parameters. + """ + self.input_interface = registry[input]() + self.output_interface = registry[output]() + self.model_type = model_type + self.model_obj = model_obj + self.model_params = model_params + + def _build_template(self): + input_template_path = self.input_interface._get_template_path() + output_template_path = self.output_interface._get_template_path() + input_page = open(input_template_path) + output_page = open(output_template_path) + input_soup = BeautifulSoup(input_page.read()) + output_soup = BeautifulSoup(output_page.read()) + + all_io_url = 'templates/all_io.html' + all_io_page = open(all_io_url) + all_io_soup = BeautifulSoup(all_io_page.read()) + input_tag = all_io_soup.find("div", {"id": "input"}) + output_tag = all_io_soup.find("div", {"id": "output"}) + + input_tag.replace_with(input_soup) + output_tag.replace_with(output_soup) + + f = open("templates/tmp_html.html", "w") + f.write(str(all_io_soup.prettify)) + return 'templates/tmp_html.html' + def predict(self, array): if self.model_type=='sklearn': return self.model_obj.predict(array)[0] @@ -119,11 +212,6 @@ class DrawADigit(AbstractInterface): else: raise ValueError('model_type must be sklearn.') - def _get_template_path(self): - return 'templates/draw_a_digit.html' - - def start(self): - super().start() async def communicate(self, websocket, path): """ @@ -132,12 +220,19 @@ class DrawADigit(AbstractInterface): :param path: ignored """ while True: - imgstring = await websocket.recv() - content = imgstring.split(';')[1] - image_encoded = content.split(',')[1] - body = base64.decodebytes(image_encoded.encode('utf-8')) - im = Image.open(BytesIO(base64.b64decode(image_encoded))).convert('L') - im = resize_and_crop(im, (28, 28)) - array = np.array(im).flatten().reshape(1, -1) - prediction = self.predict(array) - await websocket.send(str(prediction)) \ No newline at end of file + processed_input = self.input_interface._pre_process(await websocket.recv()) + prediction = self.predict(processed_input) + processed_output = self.output_interface._post_process(prediction) + await websocket.send(str(processed_output)) + + def launch(self): + """ + Standard method shared by interfaces that launches a websocket at a specified IP address. + """ + webbrowser.open('file://' + os.path.realpath(self._build_template())) + start_server = websockets.serve(self.communicate, LOCALHOST_IP, SOCKET_PORT) + asyncio.get_event_loop().run_until_complete(start_server) + try: + asyncio.get_event_loop().run_forever() + except RuntimeError: # Runtime errors are thrown in jupyter notebooks because of async. + pass \ No newline at end of file diff --git a/index.html b/index.html index c0f81b65cd..dfe69e1ff7 100644 --- a/index.html +++ b/index.html @@ -176,7 +176,7 @@

Emotion Detector: allow users to make emotions through their webcam and detect their emotion with your model.

- +
diff --git a/js/all-io.js b/js/all-io.js new file mode 100644 index 0000000000..b8a68e7b98 --- /dev/null +++ b/js/all-io.js @@ -0,0 +1,13 @@ +try { + var ws = new WebSocket("ws://127.0.0.1:5680/") + ws.onerror = function(evt) { + notifyError(evt) + }; + +} catch (e) { + notifyError(e) +} + +const sleep = (milliseconds) => { + return new Promise(resolve => setTimeout(resolve, milliseconds)) +} \ No newline at end of file diff --git a/js/class-output.js b/js/class-output.js new file mode 100644 index 0000000000..09419b114d --- /dev/null +++ b/js/class-output.js @@ -0,0 +1,43 @@ +var predict_canvas = document.getElementById("predict_canvas"); +var predict_ctx = predict_canvas.getContext("2d"); + + +function notifyError(error) { + $.notify({ + // options + message: 'Not able to communicate with model (is python code still running?)' + },{ + // settings + type: 'danger', + animate: { + enter: 'animated fadeInDown', + exit: 'animated fadeOutUp' + }, + placement: { + from: "bottom", + align: "right" + }, + delay: 5000 + + }); + } + +try { + ws.onerror = function(evt) { + notifyError(evt) + }; + + ws.onmessage = function (event) { + console.log(event.data); + predict_ctx.clearRect(0, 0, 400, 400); // Clears the canvas + predict_ctx.font = "60px Arial"; + predict_ctx.fillStyle = "white"; + sleep(300).then(() => { + predict_ctx.textAlign = "center"; + predict_ctx.fillText(event.data, 200, 200); + }) + + } +} catch (e) { + notifyError(e) +} diff --git a/js/emotion-detector.js b/js/emotion-detector.js new file mode 100644 index 0000000000..91efaf82df --- /dev/null +++ b/js/emotion-detector.js @@ -0,0 +1,180 @@ +videoWidth = 400; +videoHeight = 400; + +function isAndroid() { + return /Android/i.test(navigator.userAgent); +} + +function isiOS() { + return /iPhone|iPad|iPod/i.test(navigator.userAgent); +} + +function isMobile() { + return isAndroid() || isiOS(); +} + +var predict_canvas = document.getElementById("predict_canvas"); +var predict_ctx = predict_canvas.getContext("2d"); +var canvas = document.getElementById("canvas"); +var ctx = canvas.getContext("2d"); + + +const sleep = (milliseconds) => { + return new Promise(resolve => setTimeout(resolve, milliseconds)) +} + +async function setupCamera() { + if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) { + throw new Error( + 'Browser API navigator.mediaDevices.getUserMedia not available'); + } + + const video = document.getElementById('video'); + video.width = videoWidth; + video.height = videoHeight; + + + const mobile = isMobile(); + const stream = await navigator.mediaDevices.getUserMedia({ + 'audio': false, + 'video': { + facingMode: 'user', + width: mobile ? undefined : videoWidth, + height: mobile ? undefined : videoHeight, + }, + }); + + video.srcObject = stream; + + return new Promise((resolve) => { + video.onloadedmetadata = () => { + resolve(video); + }; + }); + +} + +async function loadVideo() { + const video = await setupCamera(); + video.play(); + + return video; +} + +function detectPoseInRealTime(video) { + const flipHorizontal = true; + async function poseDetectionFrame() { + + ctx.clearRect(0, 0, videoWidth, videoHeight); + + ctx.save(); + ctx.scale(-1, 1); + ctx.translate(-videoWidth, 0); + ctx.drawImage(video, 0, 0, videoWidth, videoHeight); + ctx.restore(); + + requestAnimationFrame(poseDetectionFrame); + + } + + poseDetectionFrame(); +} + +async function bindPage() { + + let video; + + try { + video = await loadVideo(); + } catch (e) { + let info = document.getElementById('info'); + info.textContent = 'this browser does not support video capture,' + + 'or this device does not have a camera'; + info.style.display = 'block'; + throw e; + } + + detectPoseInRealTime(video); + +} + +navigator.getUserMedia = navigator.getUserMedia || + navigator.webkitGetUserMedia || navigator.mozGetUserMedia; +// kick off the demo +bindPage(); + + +function notifyError(error) { + $.notify({ + // options + message: 'Not able to communicate with model (is python code still running?)' + },{ + // settings + type: 'danger', + animate: { + enter: 'animated fadeInDown', + exit: 'animated fadeOutUp' + }, + placement: { + from: "bottom", + align: "right" + }, + delay: 5000 + + }); + } + +try { + var ws = new WebSocket("ws://127.0.0.1:5679/") + ws.onerror = function(evt) { + notifyError(evt) + }; + + ws.onmessage = function (event) { + var emotion_dict = {0: "Angry", 1: "Disgust", 2: "Fear", 3: "Happy", 4: "Sad", 5: "Surprise", 6: "Neutral"} + console.log(event.data); + predict_ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); // Clears the canvas + predict_ctx.font = "60px Arial"; + predict_ctx.fillStyle = "white"; + sleep(300).then(() => { + // predict_ctx.fillText(emotion_dict[event.data], 110, 310); + predict_ctx.textAlign = "center"; + predict_ctx.fillText(emotion_dict[event.data], 200, 200); + }) + + } +} catch (e) { + notifyError(e) +} + +$('#clear-button').click(function(e){ + context.clearRect(0, 0, context.canvas.width, context.canvas.height); // Clears the canvas + clickX = new Array(); + clickY = new Array(); + clickDrag = new Array(); + context.fillStyle = "black"; + context.fillRect(0, 0, 400, 400); + ctx.clearRect(0, 0, context.canvas.width, context.canvas.height); // Clears the canvas +}) + + +$('#submit-button').click(function(e){ + var dataURL = canvas.toDataURL("image/png"); + ws.send(dataURL, function(e){ + notifyError(e) + }); + +}) + +$('#capture-button').click(function(e){ + ctx.clearRect(0, 0, videoWidth, videoHeight); + ctx.save(); + ctx.scale(-1, 1); + ctx.translate(-videoWidth, 0); + ctx.drawImage(video, 0, 0, videoWidth, videoHeight); + ctx.restore(); + var dataURL = canvas.toDataURL("image/png"); + ws.send(dataURL, function(e){ + notifyError(e) + }); +}) diff --git a/js/sketchpad-input.js b/js/sketchpad-input.js new file mode 100644 index 0000000000..c90b3235fc --- /dev/null +++ b/js/sketchpad-input.js @@ -0,0 +1,100 @@ +var canvas = document.getElementById('canvas'); +context = canvas.getContext("2d"); +context.fillStyle = "black"; +context.fillRect(0, 0, 400, 400); + + +function notifyError(error) { + $.notify({ + // options + message: 'Not able to communicate with model (is python code still running?)' + },{ + // settings + type: 'danger', + animate: { + enter: 'animated fadeInDown', + exit: 'animated fadeOutUp' + }, + placement: { + from: "bottom", + align: "right" + }, + delay: 5000 + + }); + } + + +$('#canvas').mousedown(function(e){ + var mouseX = e.pageX - this.getBoundingClientRect().left + document.documentElement.scrollLeft; + var mouseY = e.pageY - this.getBoundingClientRect().top + document.documentElement.scrollTop +; + + paint = true; + addClick(mouseX, mouseY); + redraw(); +}); +$('#canvas').mousemove(function(e){ + if(paint){ + addClick(e.pageX - this.getBoundingClientRect().left + document.documentElement.scrollLeft, e.pageY - this.getBoundingClientRect().top + document.documentElement.scrollTop, true); + redraw(); + } +}); +$('#canvas').mouseup(function(e){ + paint = false; +}); +$('#canvas').mouseleave(function(e){ + paint = false; +}); +var clickX = new Array(); +var clickY = new Array(); +var clickDrag = new Array(); +var paint; + +function addClick(x, y, dragging) +{ + clickX.push(x); + clickY.push(y); + clickDrag.push(dragging); +} +function redraw(){ + context.clearRect(0, 0, context.canvas.width, context.canvas.height); // Clears the canvas + context.fillStyle = "black"; + context.fillRect(0, 0, 400, 400); + + context.strokeStyle = "#FFF"; + context.lineJoin = "round"; + context.lineWidth = 25; + + for(var i=0; i < clickX.length; i++) { + context.beginPath(); + if(clickDrag[i] && i){ + context.moveTo(clickX[i-1], clickY[i-1]); + }else{ + context.moveTo(clickX[i]-1, clickY[i]); + } + context.lineTo(clickX[i], clickY[i]); + context.closePath(); + context.stroke(); + } +} + +$('#clear-button').click(function(e){ + context.clearRect(0, 0, context.canvas.width, context.canvas.height); // Clears the canvas + clickX = new Array(); + clickY = new Array(); + clickDrag = new Array(); + context.fillStyle = "black"; + context.fillRect(0, 0, 400, 400); + ctx.clearRect(0, 0, context.canvas.width, context.canvas.height); // Clears the canvas +}) + + +$('#submit-button').click(function(e){ + var dataURL = canvas.toDataURL("image/png"); + ws.send(dataURL, function(e){ + notifyError(e) + }); + +}) + diff --git a/js/webcam-input.js b/js/webcam-input.js new file mode 100644 index 0000000000..cda827e643 --- /dev/null +++ b/js/webcam-input.js @@ -0,0 +1,152 @@ +videoWidth = 400; +videoHeight = 400; + +function isAndroid() { + return /Android/i.test(navigator.userAgent); +} + +function isiOS() { + return /iPhone|iPad|iPod/i.test(navigator.userAgent); +} + +function isMobile() { + return isAndroid() || isiOS(); +} + +var canvas = document.getElementById("canvas"); +var ctx = canvas.getContext("2d"); + + +async function setupCamera() { + if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) { + throw new Error( + 'Browser API navigator.mediaDevices.getUserMedia not available'); + } + + const video = document.getElementById('video'); + video.width = videoWidth; + video.height = videoHeight; + + + const mobile = isMobile(); + const stream = await navigator.mediaDevices.getUserMedia({ + 'audio': false, + 'video': { + facingMode: 'user', + width: mobile ? undefined : videoWidth, + height: mobile ? undefined : videoHeight, + }, + }); + + video.srcObject = stream; + + return new Promise((resolve) => { + video.onloadedmetadata = () => { + resolve(video); + }; + }); + +} + +async function loadVideo() { + const video = await setupCamera(); + video.play(); + + return video; +} + +function detectPoseInRealTime(video) { + const flipHorizontal = true; + async function poseDetectionFrame() { + + ctx.clearRect(0, 0, videoWidth, videoHeight); + + ctx.save(); + ctx.scale(-1, 1); + ctx.translate(-videoWidth, 0); + ctx.drawImage(video, 0, 0, videoWidth, videoHeight); + ctx.restore(); + + requestAnimationFrame(poseDetectionFrame); + + } + + poseDetectionFrame(); +} + +async function bindPage() { + + let video; + + try { + video = await loadVideo(); + } catch (e) { + let info = document.getElementById('info'); + info.textContent = 'this browser does not support video capture,' + + 'or this device does not have a camera'; + info.style.display = 'block'; + throw e; + } + + detectPoseInRealTime(video); + +} + +navigator.getUserMedia = navigator.getUserMedia || + navigator.webkitGetUserMedia || navigator.mozGetUserMedia; +// kick off the demo +bindPage(); + + +function notifyError(error) { + $.notify({ + // options + message: 'Not able to communicate with model (is python code still running?)' + },{ + // settings + type: 'danger', + animate: { + enter: 'animated fadeInDown', + exit: 'animated fadeOutUp' + }, + placement: { + from: "bottom", + align: "right" + }, + delay: 5000 + + }); + } + + +$('#clear-button').click(function(e){ + context.clearRect(0, 0, context.canvas.width, context.canvas.height); // Clears the canvas + clickX = new Array(); + clickY = new Array(); + clickDrag = new Array(); + context.fillStyle = "black"; + context.fillRect(0, 0, 400, 400); + ctx.clearRect(0, 0, context.canvas.width, context.canvas.height); // Clears the canvas +}) + + +$('#submit-button').click(function(e){ + var dataURL = canvas.toDataURL("image/png"); + ws.send(dataURL, function(e){ + notifyError(e) + }); + +}) + +$('#capture-button').click(function(e){ + ctx.clearRect(0, 0, videoWidth, videoHeight); + ctx.save(); + ctx.scale(-1, 1); + ctx.translate(-videoWidth, 0); + ctx.drawImage(video, 0, 0, videoWidth, videoHeight); + ctx.restore(); + var dataURL = canvas.toDataURL("image/png"); + ws.send(dataURL, function(e){ + notifyError(e) + }); +}) diff --git a/script.py b/script.py new file mode 100644 index 0000000000..8b4896706a --- /dev/null +++ b/script.py @@ -0,0 +1,12 @@ +from bs4 import BeautifulSoup + +sketchpad_url = 'templates/sketchpad_input.html' +all_io_url = 'templates/all_io.html' +sketchpad_page = open(sketchpad_url) +all_io_page = open(all_io_url) +sketchpad_soup = BeautifulSoup(sketchpad_page.read()) +all_io_soup = BeautifulSoup(all_io_page.read()) +input_tag = all_io_soup.find("div", {"id": "input"}) +input_tag.replace_with(sketchpad_soup) +f = open("templates/tmp_html.html", "w") +f.write(str(all_io_soup.prettify)) \ No newline at end of file diff --git a/templates/all_io.html b/templates/all_io.html new file mode 100644 index 0000000000..7e8bb01076 --- /dev/null +++ b/templates/all_io.html @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + Gradio + + + + + + + + + + +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + Gradio is open-source, help make it better   + + + + + + + + Found this useful? Kindly spread the word   + + + + + +
+
+ + + + + + + + + + + + + diff --git a/templates/class_output.html b/templates/class_output.html new file mode 100644 index 0000000000..fd00bd5215 --- /dev/null +++ b/templates/class_output.html @@ -0,0 +1,6 @@ +
+
Text Output:
+
+
+ + diff --git a/templates/emotion_detector.html b/templates/emotion_detector.html new file mode 100644 index 0000000000..ccb21bb185 --- /dev/null +++ b/templates/emotion_detector.html @@ -0,0 +1,106 @@ + + + + + + + + + + Gradio: Emotion Detector + + + + + + + + + + + +
+ + +
+
+
See if we can guess what emotion you're expressing!
+ + +
+ +
+ + + +
+
+
+
Predicted emotion appears here
+
+
+
+ + + + + +
+ +
+
+ + + + Gradio is open-source, help make it better   + + + + + + + + Found this useful? Kindly spread the word   + + + + + +
+
+ + + + + + + + + diff --git a/templates/sketchpad_input.html b/templates/sketchpad_input.html new file mode 100644 index 0000000000..afe3951e9e --- /dev/null +++ b/templates/sketchpad_input.html @@ -0,0 +1,10 @@ +
+
Sketch Pad Input: (Use your cursor to draw)
+
+
+ + +
+
+ + diff --git a/templates/tmp_html.html b/templates/tmp_html.html new file mode 100644 index 0000000000..6277156e99 --- /dev/null +++ b/templates/tmp_html.html @@ -0,0 +1,86 @@ + + + + + + + + + +Gradio + + + + + + +
+
+ +
+
Webcam Input:
+ + +
+
+ + + +
+
+ + + +
+
Text Output:
+
+
+ + +
+
+
+
+ + + Gradio is open-source, help make it better   + + + + + Found this useful? Kindly spread the word   + + + +
+
+ + + +> \ No newline at end of file diff --git a/templates/webcam_input.html b/templates/webcam_input.html new file mode 100644 index 0000000000..63e0b99586 --- /dev/null +++ b/templates/webcam_input.html @@ -0,0 +1,19 @@ +
+
Webcam Input:
+ + +
+
+ + + +
+
+ +