diff --git a/webCamGoogleColab_callbackVersion.ipynb b/webCamGoogleColab_callbackVersion.ipynb new file mode 100644 index 0000000..41fe79b --- /dev/null +++ b/webCamGoogleColab_callbackVersion.ipynb @@ -0,0 +1,179 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "webCamGoogleColab_callbackVersion.ipynb", + "provenance": [], + "collapsed_sections": [], + "authorship_tag": "ABX9TyM2I6DOr5c6reSNNpzLNA2S", + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9duzzorgTWLt", + "colab_type": "text" + }, + "source": [ + "# Use web camera in real-time on google colaboratory by callback\n", + "This version is simple and stable but low framerate." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YCzZhYPoTjZn", + "colab_type": "code", + "colab": {} + }, + "source": [ + "import IPython\n", + "from google.colab import output\n", + "import cv2\n", + "import numpy as np\n", + "from PIL import Image\n", + "from io import BytesIO\n", + "import base64\n", + "\n", + "def run(img_str):\n", + " #decode to image\n", + " decimg = base64.b64decode(img_str.split(',')[1], validate=True)\n", + " decimg = Image.open(BytesIO(decimg))\n", + " decimg = np.array(decimg, dtype=np.uint8); \n", + " decimg = cv2.cvtColor(decimg, cv2.COLOR_BGR2RGB)\n", + " \n", + " #############your process###############\n", + " \n", + " out_img = cv2.Canny(decimg,100,200)\n", + " #out_img = decimg\n", + " \n", + " #############your process###############\n", + "\n", + " #encode to string\n", + " _, encimg = cv2.imencode(\".jpg\", out_img, [int(cv2.IMWRITE_JPEG_QUALITY), 80])\n", + " img_str = encimg.tostring()\n", + " img_str = \"data:image/jpeg;base64,\" + base64.b64encode(img_str).decode('utf-8')\n", + " return IPython.display.JSON({'img_str': img_str})\n", + "\n", + "output.register_callback('notebook.run', run)" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "gt2Ti8x5UdE9", + "colab_type": "code", + "colab": {} + }, + "source": [ + "from IPython.display import display, Javascript\n", + "from google.colab.output import eval_js\n", + "\n", + "def use_cam(quality=0.8):\n", + " js = Javascript('''\n", + " async function useCam(quality) {\n", + " const div = document.createElement('div');\n", + " document.body.appendChild(div);\n", + " //video element\n", + " const video = document.createElement('video');\n", + " video.style.display = 'None';\n", + " const stream = await navigator.mediaDevices.getUserMedia({video: true});\n", + " div.appendChild(video);\n", + " video.srcObject = stream;\n", + " await video.play();\n", + " \n", + " //canvas for display. frame rate is depending on display size and jpeg quality.\n", + " display_size = 500 \n", + " const src_canvas = document.createElement('canvas');\n", + " src_canvas.width = display_size;\n", + " src_canvas.height = display_size * video.videoHeight / video.videoWidth;\n", + " const src_canvasCtx = src_canvas.getContext('2d');\n", + " src_canvasCtx.translate(src_canvas.width, 0);\n", + " src_canvasCtx.scale(-1, 1);\n", + " div.appendChild(src_canvas);\n", + "\n", + " const dst_canvas = document.createElement('canvas');\n", + " dst_canvas.width = src_canvas.width;\n", + " dst_canvas.height = src_canvas.height;\n", + " const dst_canvasCtx = dst_canvas.getContext('2d');\n", + " div.appendChild(dst_canvas);\n", + " \n", + " //exit button\n", + " const btn_div = document.createElement('div');\n", + " document.body.appendChild(btn_div);\n", + " const exit_btn = document.createElement('button');\n", + " exit_btn.textContent = 'Exit';\n", + " var exit_flg = true\n", + " exit_btn.onclick = function() {exit_flg = false};\n", + " btn_div.appendChild(exit_btn);\n", + "\n", + " // Resize the output to fit the video element.\n", + " google.colab.output.setIframeHeight(document.documentElement.scrollHeight, true);\n", + " \n", + " var send_flg = false\n", + " // loop\n", + " _canvasUpdate();\n", + " async function _canvasUpdate() {\n", + " src_canvasCtx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight, 0, 0, src_canvas.width, src_canvas.height); \n", + " if (send_flg==false){\n", + " send_flg = true\n", + " const img = src_canvas.toDataURL('image/jpeg', quality);\n", + " const result = google.colab.kernel.invokeFunction('notebook.run', [img], {});\n", + " result.then(function(value) {\n", + " parse = JSON.parse(JSON.stringify(value))[\"data\"]\n", + " parse = JSON.parse(JSON.stringify(parse))[\"application/json\"]\n", + " parse = JSON.parse(JSON.stringify(parse))[\"img_str\"]\n", + " var image = new Image()\n", + " image.src = parse;\n", + " image.onload = function(){dst_canvasCtx.drawImage(image, 0, 0)}\n", + " send_flg = false\n", + " })\n", + " }\n", + " if (exit_flg){\n", + " requestAnimationFrame(_canvasUpdate); \n", + " }else{\n", + " stream.getVideoTracks()[0].stop();\n", + " }\n", + " };\n", + " }\n", + " ''')\n", + " display(js)\n", + " data = eval_js('useCam({})'.format(quality))" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "JZu8MCn3VEXM", + "colab_type": "code", + "colab": {} + }, + "source": [ + "use_cam()" + ], + "execution_count": 0, + "outputs": [] + } + ] +} \ No newline at end of file