From bbbf084fde6ddd14c4c292e4c77899fd9aa5ab5b Mon Sep 17 00:00:00 2001 From: lcharleux Date: Fri, 6 Apr 2018 08:45:09 +0200 Subject: [PATCH] added sandbox --- ...ruco_calibration_rotation-checkpoint.ipynb | 2 + .../Aruco/aruco_calibration_rotation.ipynb | 2 + .../Aruco/data/calib_webcam/calibHonor.csv | 3 + .../data/calib_webcam/calib_dist_Honor.csv | 14 + .../data/calib_webcam/calib_dist_alpha500.csv | 14 + .../data/calib_webcam/calib_dist_webcam.csv | 14 + .../data/calib_webcam/calib_mtx_Honor.csv | 3 + .../data/calib_webcam/calib_mtx_alpha5000.csv | 3 + .../data/calib_webcam/calib_mtx_webcam.csv | 3 + ...ruco_calibration_rotation-checkpoint.ipynb | 7118 +++++++++++++++++ .../ludovic/aruco_calibration_rotation.ipynb | 7000 ++++++++++++++++ 11 files changed, 14176 insertions(+) create mode 100644 doc/notebooks/Aruco/data/calib_webcam/calibHonor.csv create mode 100644 doc/notebooks/Aruco/data/calib_webcam/calib_dist_Honor.csv create mode 100644 doc/notebooks/Aruco/data/calib_webcam/calib_dist_alpha500.csv create mode 100644 doc/notebooks/Aruco/data/calib_webcam/calib_dist_webcam.csv create mode 100644 doc/notebooks/Aruco/data/calib_webcam/calib_mtx_Honor.csv create mode 100644 doc/notebooks/Aruco/data/calib_webcam/calib_mtx_alpha5000.csv create mode 100644 doc/notebooks/Aruco/data/calib_webcam/calib_mtx_webcam.csv create mode 100644 doc/notebooks/Aruco/sandbox/ludovic/.ipynb_checkpoints/aruco_calibration_rotation-checkpoint.ipynb create mode 100644 doc/notebooks/Aruco/sandbox/ludovic/aruco_calibration_rotation.ipynb diff --git a/doc/notebooks/Aruco/.ipynb_checkpoints/aruco_calibration_rotation-checkpoint.ipynb b/doc/notebooks/Aruco/.ipynb_checkpoints/aruco_calibration_rotation-checkpoint.ipynb index 0457fe3..8ea1e9b 100644 --- a/doc/notebooks/Aruco/.ipynb_checkpoints/aruco_calibration_rotation-checkpoint.ipynb +++ b/doc/notebooks/Aruco/.ipynb_checkpoints/aruco_calibration_rotation-checkpoint.ipynb @@ -1619,6 +1619,8 @@ "source": [ "datadir = \"./data/\"\n", "images = [datadir + f for f in os.listdir(datadir) if f.endswith(\".jpg\") ]\n", + "order = np.argsort([int(p.split(\".\")[-2].split(\"_\")[-1]) for p in images])\n", + "images = images[order]\n", "im = PIL.Image.open(images[0])\n", "fig = plt.figure()\n", "ax = fig.add_subplot(1,1,1)\n", diff --git a/doc/notebooks/Aruco/aruco_calibration_rotation.ipynb b/doc/notebooks/Aruco/aruco_calibration_rotation.ipynb index 0457fe3..8ea1e9b 100644 --- a/doc/notebooks/Aruco/aruco_calibration_rotation.ipynb +++ b/doc/notebooks/Aruco/aruco_calibration_rotation.ipynb @@ -1619,6 +1619,8 @@ "source": [ "datadir = \"./data/\"\n", "images = [datadir + f for f in os.listdir(datadir) if f.endswith(\".jpg\") ]\n", + "order = np.argsort([int(p.split(\".\")[-2].split(\"_\")[-1]) for p in images])\n", + "images = images[order]\n", "im = PIL.Image.open(images[0])\n", "fig = plt.figure()\n", "ax = fig.add_subplot(1,1,1)\n", diff --git a/doc/notebooks/Aruco/data/calib_webcam/calibHonor.csv b/doc/notebooks/Aruco/data/calib_webcam/calibHonor.csv new file mode 100644 index 0000000..e000c93 --- /dev/null +++ b/doc/notebooks/Aruco/data/calib_webcam/calibHonor.csv @@ -0,0 +1,3 @@ +1.590858715762278052e+03 0.000000000000000000e+00 1.008206750217759691e+03 +0.000000000000000000e+00 1.594169947150725875e+03 5.462130872032349771e+02 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 diff --git a/doc/notebooks/Aruco/data/calib_webcam/calib_dist_Honor.csv b/doc/notebooks/Aruco/data/calib_webcam/calib_dist_Honor.csv new file mode 100644 index 0000000..c273041 --- /dev/null +++ b/doc/notebooks/Aruco/data/calib_webcam/calib_dist_Honor.csv @@ -0,0 +1,14 @@ +2.305745068374976725e+00 +-1.146564413962530438e+02 +-1.001572793821985628e-03 +3.797055545421817654e-03 +5.620192195841833609e+02 +2.064439151665715233e+00 +-1.113398964574677450e+02 +5.481991678906149446e+02 +0.000000000000000000e+00 +0.000000000000000000e+00 +0.000000000000000000e+00 +0.000000000000000000e+00 +0.000000000000000000e+00 +0.000000000000000000e+00 diff --git a/doc/notebooks/Aruco/data/calib_webcam/calib_dist_alpha500.csv b/doc/notebooks/Aruco/data/calib_webcam/calib_dist_alpha500.csv new file mode 100644 index 0000000..03ffd3c --- /dev/null +++ b/doc/notebooks/Aruco/data/calib_webcam/calib_dist_alpha500.csv @@ -0,0 +1,14 @@ +-8.821857461698886027e+01 +2.642325706544063451e+03 +-2.235731234660711785e-03 +-3.472367417271127448e-03 +2.769658945777098779e+03 +-8.826491823401900660e+01 +2.645265940513953865e+03 +2.608034825049014671e+03 +0.000000000000000000e+00 +0.000000000000000000e+00 +0.000000000000000000e+00 +0.000000000000000000e+00 +0.000000000000000000e+00 +0.000000000000000000e+00 diff --git a/doc/notebooks/Aruco/data/calib_webcam/calib_dist_webcam.csv b/doc/notebooks/Aruco/data/calib_webcam/calib_dist_webcam.csv new file mode 100644 index 0000000..17afa5d --- /dev/null +++ b/doc/notebooks/Aruco/data/calib_webcam/calib_dist_webcam.csv @@ -0,0 +1,14 @@ +-7.869163904064436110e+00 +-2.753229267351832021e+01 +3.078006362917749469e-02 +-1.433685780203987348e-02 +6.635688199491378327e+02 +-8.250538100891361637e+00 +-2.166238301591351956e+01 +6.388060151969392564e+02 +0.000000000000000000e+00 +0.000000000000000000e+00 +0.000000000000000000e+00 +0.000000000000000000e+00 +0.000000000000000000e+00 +0.000000000000000000e+00 diff --git a/doc/notebooks/Aruco/data/calib_webcam/calib_mtx_Honor.csv b/doc/notebooks/Aruco/data/calib_webcam/calib_mtx_Honor.csv new file mode 100644 index 0000000..0ca050e --- /dev/null +++ b/doc/notebooks/Aruco/data/calib_webcam/calib_mtx_Honor.csv @@ -0,0 +1,3 @@ +1.567189503342848866e+03 0.000000000000000000e+00 9.902670836836547323e+02 +0.000000000000000000e+00 1.570546506977959780e+03 5.553998461015821704e+02 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 diff --git a/doc/notebooks/Aruco/data/calib_webcam/calib_mtx_alpha5000.csv b/doc/notebooks/Aruco/data/calib_webcam/calib_mtx_alpha5000.csv new file mode 100644 index 0000000..c22eb50 --- /dev/null +++ b/doc/notebooks/Aruco/data/calib_webcam/calib_mtx_alpha5000.csv @@ -0,0 +1,3 @@ +1.376665680047565274e+03 0.000000000000000000e+00 7.098847132128643125e+02 +0.000000000000000000e+00 1.837233074596459119e+03 5.199231643394018647e+02 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 diff --git a/doc/notebooks/Aruco/data/calib_webcam/calib_mtx_webcam.csv b/doc/notebooks/Aruco/data/calib_webcam/calib_mtx_webcam.csv new file mode 100644 index 0000000..cd4f267 --- /dev/null +++ b/doc/notebooks/Aruco/data/calib_webcam/calib_mtx_webcam.csv @@ -0,0 +1,3 @@ +5.405828689280267554e+02 0.000000000000000000e+00 3.104286084534308543e+02 +0.000000000000000000e+00 5.582209578402930674e+02 3.380796623343913438e+02 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 diff --git a/doc/notebooks/Aruco/sandbox/ludovic/.ipynb_checkpoints/aruco_calibration_rotation-checkpoint.ipynb b/doc/notebooks/Aruco/sandbox/ludovic/.ipynb_checkpoints/aruco_calibration_rotation-checkpoint.ipynb new file mode 100644 index 0000000..f3d7f84 --- /dev/null +++ b/doc/notebooks/Aruco/sandbox/ludovic/.ipynb_checkpoints/aruco_calibration_rotation-checkpoint.ipynb @@ -0,0 +1,7118 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Camera calibration using CHARUCO" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import cv2, PIL, os\n", + "from cv2 import aruco\n", + "from mpl_toolkits.mplot3d import Axes3D\n", + "import matplotlib.pyplot as plt\n", + "import matplotlib as mpl\n", + "import pandas as pd\n", + "%matplotlib nbagg\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "## 2. Camera pose estimation using CHARUCO chessboard\n", + "\n", + "First, let's create the board." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " this.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width);\n", + " canvas.attr('height', height);\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "datadir = \"../../data/calib_webcam/\"\n", + "images = [datadir + f for f in os.listdir(datadir) if f.endswith(\".jpg\") ]\n", + "\n", + "im = PIL.Image.open(images[0])\n", + "fig = plt.figure()\n", + "ax = fig.add_subplot(1,1,1)\n", + "plt.imshow(im)\n", + "#ax.axis('off')\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['../../data/calib_webcam/image_0.jpg',\n", + " '../../data/calib_webcam/image_1.jpg',\n", + " '../../data/calib_webcam/image_10.jpg',\n", + " '../../data/calib_webcam/image_11.jpg',\n", + " '../../data/calib_webcam/image_12.jpg',\n", + " '../../data/calib_webcam/image_13.jpg',\n", + " '../../data/calib_webcam/image_14.jpg',\n", + " '../../data/calib_webcam/image_15.jpg',\n", + " '../../data/calib_webcam/image_16.jpg',\n", + " '../../data/calib_webcam/image_17.jpg',\n", + " '../../data/calib_webcam/image_18.jpg',\n", + " '../../data/calib_webcam/image_19.jpg',\n", + " '../../data/calib_webcam/image_2.jpg',\n", + " '../../data/calib_webcam/image_20.jpg',\n", + " '../../data/calib_webcam/image_21.jpg',\n", + " '../../data/calib_webcam/image_22.jpg',\n", + " '../../data/calib_webcam/image_23.jpg',\n", + " '../../data/calib_webcam/image_24.jpg',\n", + " '../../data/calib_webcam/image_25.jpg',\n", + " '../../data/calib_webcam/image_26.jpg',\n", + " '../../data/calib_webcam/image_27.jpg',\n", + " '../../data/calib_webcam/image_28.jpg',\n", + " '../../data/calib_webcam/image_29.jpg',\n", + " '../../data/calib_webcam/image_3.jpg',\n", + " '../../data/calib_webcam/image_30.jpg',\n", + " '../../data/calib_webcam/image_31.jpg',\n", + " '../../data/calib_webcam/image_32.jpg',\n", + " '../../data/calib_webcam/image_33.jpg',\n", + " '../../data/calib_webcam/image_34.jpg',\n", + " '../../data/calib_webcam/image_35.jpg',\n", + " '../../data/calib_webcam/image_36.jpg',\n", + " '../../data/calib_webcam/image_37.jpg',\n", + " '../../data/calib_webcam/image_38.jpg',\n", + " '../../data/calib_webcam/image_39.jpg',\n", + " '../../data/calib_webcam/image_4.jpg',\n", + " '../../data/calib_webcam/image_40.jpg',\n", + " '../../data/calib_webcam/image_41.jpg',\n", + " '../../data/calib_webcam/image_42.jpg',\n", + " '../../data/calib_webcam/image_43.jpg',\n", + " '../../data/calib_webcam/image_44.jpg',\n", + " '../../data/calib_webcam/image_45.jpg',\n", + " '../../data/calib_webcam/image_46.jpg',\n", + " '../../data/calib_webcam/image_47.jpg',\n", + " '../../data/calib_webcam/image_48.jpg',\n", + " '../../data/calib_webcam/image_49.jpg',\n", + " '../../data/calib_webcam/image_5.jpg',\n", + " '../../data/calib_webcam/image_50.jpg',\n", + " '../../data/calib_webcam/image_51.jpg',\n", + " '../../data/calib_webcam/image_52.jpg',\n", + " '../../data/calib_webcam/image_53.jpg',\n", + " '../../data/calib_webcam/image_54.jpg',\n", + " '../../data/calib_webcam/image_55.jpg',\n", + " '../../data/calib_webcam/image_56.jpg',\n", + " '../../data/calib_webcam/image_57.jpg',\n", + " '../../data/calib_webcam/image_58.jpg',\n", + " '../../data/calib_webcam/image_59.jpg',\n", + " '../../data/calib_webcam/image_6.jpg',\n", + " '../../data/calib_webcam/image_60.jpg',\n", + " '../../data/calib_webcam/image_61.jpg',\n", + " '../../data/calib_webcam/image_62.jpg',\n", + " '../../data/calib_webcam/image_63.jpg',\n", + " '../../data/calib_webcam/image_64.jpg',\n", + " '../../data/calib_webcam/image_65.jpg',\n", + " '../../data/calib_webcam/image_66.jpg',\n", + " '../../data/calib_webcam/image_67.jpg',\n", + " '../../data/calib_webcam/image_68.jpg',\n", + " '../../data/calib_webcam/image_69.jpg',\n", + " '../../data/calib_webcam/image_7.jpg',\n", + " '../../data/calib_webcam/image_70.jpg',\n", + " '../../data/calib_webcam/image_71.jpg',\n", + " '../../data/calib_webcam/image_72.jpg',\n", + " '../../data/calib_webcam/image_73.jpg',\n", + " '../../data/calib_webcam/image_74.jpg',\n", + " '../../data/calib_webcam/image_75.jpg',\n", + " '../../data/calib_webcam/image_76.jpg',\n", + " '../../data/calib_webcam/image_77.jpg',\n", + " '../../data/calib_webcam/image_78.jpg',\n", + " '../../data/calib_webcam/image_79.jpg',\n", + " '../../data/calib_webcam/image_8.jpg',\n", + " '../../data/calib_webcam/image_80.jpg',\n", + " '../../data/calib_webcam/image_81.jpg',\n", + " '../../data/calib_webcam/image_82.jpg',\n", + " '../../data/calib_webcam/image_83.jpg',\n", + " '../../data/calib_webcam/image_84.jpg',\n", + " '../../data/calib_webcam/image_85.jpg',\n", + " '../../data/calib_webcam/image_86.jpg',\n", + " '../../data/calib_webcam/image_87.jpg',\n", + " '../../data/calib_webcam/image_88.jpg',\n", + " '../../data/calib_webcam/image_89.jpg',\n", + " '../../data/calib_webcam/image_9.jpg',\n", + " '../../data/calib_webcam/image_90.jpg',\n", + " '../../data/calib_webcam/image_91.jpg',\n", + " '../../data/calib_webcam/image_92.jpg',\n", + " '../../data/calib_webcam/image_93.jpg',\n", + " '../../data/calib_webcam/image_94.jpg',\n", + " '../../data/calib_webcam/image_95.jpg',\n", + " '../../data/calib_webcam/image_96.jpg',\n", + " '../../data/calib_webcam/image_97.jpg',\n", + " '../../data/calib_webcam/image_98.jpg',\n", + " '../../data/calib_webcam/image_99.jpg']" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sorted(images)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, the camera calibration can be done using all the images of the chessboard. Two functions are necessary:\n", + "\n", + "* The first will detect markers on all the images and.\n", + "* The second will proceed the detected markers to estimage the camera calibration data." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def read_chessboards(images):\n", + " \"\"\"\n", + " Charuco base pose estimation.\n", + " \"\"\"\n", + " print(\"POSE ESTIMATION STARTS:\")\n", + " allCorners = []\n", + " allIds = []\n", + " decimator = 0\n", + " # SUB PIXEL CORNER DETECTION CRITERION\n", + " criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.0001)\n", + "\n", + " for im in images:\n", + " print(\"=> Processing image {0}\".format(im))\n", + " frame = cv2.imread(im)\n", + " gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)\n", + " corners, ids, rejectedImgPoints = cv2.aruco.detectMarkers(gray, aruco_dict)\n", + " \n", + " if len(corners)>0:\n", + " # SUB PIXEL DETECTION\n", + " for corner in corners:\n", + " cv2.cornerSubPix(gray, corner, \n", + " winSize = (20,20), \n", + " zeroZone = (-1,-1), \n", + " criteria = criteria)\n", + " res2 = cv2.aruco.interpolateCornersCharuco(corners,ids,gray,board) \n", + " if res2[1] is not None and res2[2] is not None and len(res2[1])>3 and decimator%1==0:\n", + " allCorners.append(res2[1])\n", + " allIds.append(res2[2]) \n", + " \n", + " decimator+=1 \n", + "\n", + " imsize = gray.shape\n", + " return allCorners,allIds,imsize" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "POSE ESTIMATION STARTS:\n", + "=> Processing image ../../data/calib_webcam/image_91.jpg\n", + "=> Processing image ../../data/calib_webcam/image_9.jpg\n", + "=> Processing image ../../data/calib_webcam/image_82.jpg\n", + "=> Processing image ../../data/calib_webcam/image_98.jpg\n", + "=> Processing image ../../data/calib_webcam/image_83.jpg\n", + "=> Processing image ../../data/calib_webcam/image_46.jpg\n", + "=> Processing image ../../data/calib_webcam/image_21.jpg\n", + "=> Processing image ../../data/calib_webcam/image_60.jpg\n", + "=> Processing image ../../data/calib_webcam/image_80.jpg\n", + "=> Processing image ../../data/calib_webcam/image_66.jpg\n", + "=> Processing image ../../data/calib_webcam/image_14.jpg\n", + "=> Processing image ../../data/calib_webcam/image_48.jpg\n", + "=> Processing image ../../data/calib_webcam/image_53.jpg\n", + "=> Processing image ../../data/calib_webcam/image_13.jpg\n", + "=> Processing image ../../data/calib_webcam/image_12.jpg\n", + "=> Processing image ../../data/calib_webcam/image_38.jpg\n", + "=> Processing image ../../data/calib_webcam/image_71.jpg\n", + "=> Processing image ../../data/calib_webcam/image_33.jpg\n", + "=> Processing image ../../data/calib_webcam/image_72.jpg\n", + "=> Processing image ../../data/calib_webcam/image_42.jpg\n", + "=> Processing image ../../data/calib_webcam/image_0.jpg\n", + "=> Processing image ../../data/calib_webcam/image_97.jpg\n", + "=> Processing image ../../data/calib_webcam/image_47.jpg\n", + "=> Processing image ../../data/calib_webcam/image_26.jpg\n", + "=> Processing image ../../data/calib_webcam/image_16.jpg\n", + "=> Processing image ../../data/calib_webcam/image_45.jpg\n", + "=> Processing image ../../data/calib_webcam/image_49.jpg\n", + "=> Processing image ../../data/calib_webcam/image_78.jpg\n", + "=> Processing image ../../data/calib_webcam/image_59.jpg\n", + "=> Processing image ../../data/calib_webcam/image_79.jpg\n", + "=> Processing image ../../data/calib_webcam/image_8.jpg\n", + "=> Processing image ../../data/calib_webcam/image_67.jpg\n", + "=> Processing image ../../data/calib_webcam/image_64.jpg\n", + "=> Processing image ../../data/calib_webcam/image_36.jpg\n", + "=> Processing image ../../data/calib_webcam/image_25.jpg\n", + "=> Processing image ../../data/calib_webcam/image_18.jpg\n", + "=> Processing image ../../data/calib_webcam/image_31.jpg\n", + "=> Processing image ../../data/calib_webcam/image_58.jpg\n", + "=> Processing image ../../data/calib_webcam/image_88.jpg\n", + "=> Processing image ../../data/calib_webcam/image_63.jpg\n", + "=> Processing image ../../data/calib_webcam/image_4.jpg\n", + "=> Processing image ../../data/calib_webcam/image_30.jpg\n", + "=> Processing image ../../data/calib_webcam/image_87.jpg\n", + "=> Processing image ../../data/calib_webcam/image_77.jpg\n", + "=> Processing image ../../data/calib_webcam/image_69.jpg\n", + "=> Processing image ../../data/calib_webcam/image_27.jpg\n", + "=> Processing image ../../data/calib_webcam/image_43.jpg\n", + "=> Processing image ../../data/calib_webcam/image_11.jpg\n", + "=> Processing image ../../data/calib_webcam/image_50.jpg\n", + "=> Processing image ../../data/calib_webcam/image_22.jpg\n", + "=> Processing image ../../data/calib_webcam/image_15.jpg\n", + "=> Processing image ../../data/calib_webcam/image_3.jpg\n", + "=> Processing image ../../data/calib_webcam/image_6.jpg\n", + "=> Processing image ../../data/calib_webcam/image_41.jpg\n", + "=> Processing image ../../data/calib_webcam/image_99.jpg\n", + "=> Processing image ../../data/calib_webcam/image_89.jpg\n", + "=> Processing image ../../data/calib_webcam/image_10.jpg\n", + "=> Processing image ../../data/calib_webcam/image_2.jpg\n", + "=> Processing image ../../data/calib_webcam/image_96.jpg\n", + "=> Processing image ../../data/calib_webcam/image_54.jpg\n", + "=> Processing image ../../data/calib_webcam/image_90.jpg\n", + "=> Processing image ../../data/calib_webcam/image_86.jpg\n", + "=> Processing image ../../data/calib_webcam/image_29.jpg\n", + "=> Processing image ../../data/calib_webcam/image_32.jpg\n", + "=> Processing image ../../data/calib_webcam/image_35.jpg\n", + "=> Processing image ../../data/calib_webcam/image_70.jpg\n", + "=> Processing image ../../data/calib_webcam/image_75.jpg\n", + "=> Processing image ../../data/calib_webcam/image_73.jpg\n", + "=> Processing image ../../data/calib_webcam/image_57.jpg\n", + "=> Processing image ../../data/calib_webcam/image_51.jpg\n", + "=> Processing image ../../data/calib_webcam/image_1.jpg\n", + "=> Processing image ../../data/calib_webcam/image_55.jpg\n", + "=> Processing image ../../data/calib_webcam/image_5.jpg\n", + "=> Processing image ../../data/calib_webcam/image_39.jpg\n", + "=> Processing image ../../data/calib_webcam/image_7.jpg\n", + "=> Processing image ../../data/calib_webcam/image_20.jpg\n", + "=> Processing image ../../data/calib_webcam/image_40.jpg\n", + "=> Processing image ../../data/calib_webcam/image_76.jpg\n", + "=> Processing image ../../data/calib_webcam/image_81.jpg\n", + "=> Processing image ../../data/calib_webcam/image_52.jpg\n", + "=> Processing image ../../data/calib_webcam/image_19.jpg\n", + "=> Processing image ../../data/calib_webcam/image_94.jpg\n", + "=> Processing image ../../data/calib_webcam/image_24.jpg\n", + "=> Processing image ../../data/calib_webcam/image_17.jpg\n", + "=> Processing image ../../data/calib_webcam/image_93.jpg\n", + "=> Processing image ../../data/calib_webcam/image_44.jpg\n", + "=> Processing image ../../data/calib_webcam/image_61.jpg\n", + "=> Processing image ../../data/calib_webcam/image_84.jpg\n", + "=> Processing image ../../data/calib_webcam/image_92.jpg\n", + "=> Processing image ../../data/calib_webcam/image_62.jpg\n", + "=> Processing image ../../data/calib_webcam/image_85.jpg\n", + "=> Processing image ../../data/calib_webcam/image_74.jpg\n", + "=> Processing image ../../data/calib_webcam/image_37.jpg\n", + "=> Processing image ../../data/calib_webcam/image_23.jpg\n", + "=> Processing image ../../data/calib_webcam/image_95.jpg\n", + "=> Processing image ../../data/calib_webcam/image_56.jpg\n", + "=> Processing image ../../data/calib_webcam/image_34.jpg\n", + "=> Processing image ../../data/calib_webcam/image_28.jpg\n", + "=> Processing image ../../data/calib_webcam/image_68.jpg\n", + "=> Processing image ../../data/calib_webcam/image_65.jpg\n" + ] + } + ], + "source": [ + "allCorners,allIds,imsize=read_chessboards(images)" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def calibrate_camera(allCorners,allIds,imsize): \n", + " \"\"\"\n", + " Calibrates the camera using the dected corners.\n", + " \"\"\"\n", + " print(\"CAMERA CALIBRATION\")\n", + " \n", + " cameraMatrixInit = np.array([[ 2000., 0., imsize[0]/2.],\n", + " [ 0., 2000., imsize[1]/2.],\n", + " [ 0., 0., 1.]])\n", + "\n", + " distCoeffsInit = np.zeros((5,1))\n", + " flags = (cv2.CALIB_USE_INTRINSIC_GUESS + cv2.CALIB_RATIONAL_MODEL) \n", + " (ret, camera_matrix, distortion_coefficients0, \n", + " rotation_vectors, translation_vectors,\n", + " stdDeviationsIntrinsics, stdDeviationsExtrinsics, \n", + " perViewErrors) = cv2.aruco.calibrateCameraCharucoExtended(\n", + " charucoCorners=allCorners,\n", + " charucoIds=allIds,\n", + " board=board,\n", + " imageSize=imsize,\n", + " cameraMatrix=cameraMatrixInit,\n", + " distCoeffs=distCoeffsInit,\n", + " flags=flags,\n", + " criteria=(cv2.TERM_CRITERIA_EPS & cv2.TERM_CRITERIA_COUNT, 10000, 1e-9))\n", + "\n", + " return ret, camera_matrix, distortion_coefficients0, rotation_vectors, translation_vectors" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CAMERA CALIBRATION\n", + "CPU times: user 160 ms, sys: 164 ms, total: 324 ms\n", + "Wall time: 402 ms\n" + ] + } + ], + "source": [ + "%time ret, mtx, dist, rvecs, tvecs = calibrate_camera(allCorners,allIds,imsize)" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1.512203200242096" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ret" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[3.01517523e+03, 0.00000000e+00, 1.24206092e+03],\n", + " [0.00000000e+00, 3.02160964e+03, 1.66722492e+03],\n", + " [0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mtx" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[-3.44790638e+01],\n", + " [ 4.37856121e+02],\n", + " [-7.92991416e-04],\n", + " [ 2.52049107e-03],\n", + " [-9.02894797e+02],\n", + " [-3.44658908e+01],\n", + " [ 4.37364785e+02],\n", + " [-9.03429203e+02],\n", + " [ 0.00000000e+00],\n", + " [ 0.00000000e+00],\n", + " [ 0.00000000e+00],\n", + " [ 0.00000000e+00],\n", + " [ 0.00000000e+00],\n", + " [ 0.00000000e+00]])" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dist" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Check calibration results" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " this.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width);\n", + " canvas.attr('height', height);\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "\n", + "frame = cv2.imread(images[0])\n", + "#frame = cv2.undistort(src = frame, cameraMatrix = mtx, distCoeffs = dist)\n", + "plt.figure()\n", + "plt.imshow(frame, interpolation = \"nearest\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Post processing" + ] + }, + { + "cell_type": "code", + "execution_count": 125, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[array([[[1047.402 , 1677.9854],\n", + " [1283.8707, 1680.0746],\n", + " [1276.6002, 1916.945 ],\n", + " [1038.5194, 1915.0704]]], dtype=float32),\n", + " array([[[1643.643 , 1108.2988],\n", + " [1872.287 , 1112.7354],\n", + " [1869.3154, 1340.0709],\n", + " [1640.2269, 1336.1356]]], dtype=float32),\n", + " array([[[1361.5458 , 816.6207 ],\n", + " [1590.9443 , 822.59094],\n", + " [1587.4158 , 1049.6078 ],\n", + " [1357.7041 , 1044.2266 ]]], dtype=float32),\n", + " array([[[2507., 850.],\n", + " [2721., 852.],\n", + " [2725., 1064.],\n", + " [2506., 1063.]]], dtype=float32),\n", + " array([[[2209.549 , 1693.0295],\n", + " [2437.6775, 1696.974 ],\n", + " [2437.3079, 1928.5906],\n", + " [2209.134 , 1925.7533]]], dtype=float32),\n", + " array([[[1634.5605, 1684.4054],\n", + " [1864.5225, 1686.7997],\n", + " [1862.7523, 1921.8263],\n", + " [1630.348 , 1919.4214]]], dtype=float32),\n", + " array([[[2497.2854, 1410.262 ],\n", + " [2726.4668, 1414.9214],\n", + " [2723.777 , 1644.2507],\n", + " [2495.574 , 1639.5747]]], dtype=float32),\n", + " array([[[1926.3191, 1399.1171],\n", + " [2154.1187, 1403.0922],\n", + " [2152.2625, 1633.4531],\n", + " [1922.9907, 1628.7273]]], dtype=float32),\n", + " array([[[1350.1337, 1389.171 ],\n", + " [1581.7115, 1393.2401],\n", + " [1577.6371, 1624.9827],\n", + " [1344.7365, 1621.3724]]], dtype=float32),\n", + " array([[[ 755.51526, 1380.8232 ],\n", + " [ 995.99176, 1384.0219 ],\n", + " [ 989.3362 , 1617.9678 ],\n", + " [ 749.1104 , 1616.1603 ]]], dtype=float32),\n", + " array([[[2214.076 , 1119.7678],\n", + " [2441.4485, 1124.6108],\n", + " [2439.671 , 1351.1348],\n", + " [2211.813 , 1346.1644]]], dtype=float32),\n", + " array([[[1075., 1106.],\n", + " [1287., 1111.],\n", + " [1282., 1319.],\n", + " [1068., 1314.]]], dtype=float32),\n", + " array([[[1933.5463, 831.5169],\n", + " [2160.6843, 835.7145],\n", + " [2157.5535, 1061.4719],\n", + " [1930.9468, 1056.8634]]], dtype=float32),\n", + " array([[[ 772.1637 , 797.4331 ],\n", + " [1010.6842 , 805.75104],\n", + " [1005.5871 , 1035.5946 ],\n", + " [ 765.15216, 1028.7201 ]]], dtype=float32),\n", + " array([[[2222.741 , 553.483 ],\n", + " [2447.1362 , 560.27136],\n", + " [2444.5088 , 784.8565 ],\n", + " [2218.7124 , 779.3621 ]]], dtype=float32),\n", + " array([[[1652.8452 , 538.9495 ],\n", + " [1881.1671 , 544.9499 ],\n", + " [1876.5771 , 772.5404 ],\n", + " [1649.0568 , 766.74243]]], dtype=float32),\n", + " array([[[1076.1353 , 520.23083],\n", + " [1307.8397 , 527.73737],\n", + " [1304.233 , 756.5825 ],\n", + " [1071.4615 , 749.1797 ]]], dtype=float32)]" + ] + }, + "execution_count": 125, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\n", + "gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)\n", + "aruco_dict = aruco.Dictionary_get(aruco.DICT_6X6_250)\n", + "parameters = aruco.DetectorParameters_create()\n", + "corners, ids, rejectedImgPoints = aruco.detectMarkers(gray, aruco_dict, \n", + " parameters=parameters)\n", + "# SUB PIXEL DETECTION\n", + "criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.0001)\n", + "for corner in corners:\n", + " cv2.cornerSubPix(gray, corner, winSize = (5,5), zeroZone = (-1,-1), criteria = criteria)\n", + " \n", + "frame_markers = aruco.drawDetectedMarkers(frame.copy(), corners, ids)\n", + "\n", + "corners" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Very fast processing !\n", + "\n", + "## Results" + ] + }, + { + "cell_type": "code", + "execution_count": 126, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " this.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width);\n", + " canvas.attr('height', height);\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure()\n", + "plt.imshow(imaxis)\n", + "plt.grid()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 131, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
rxryrz
marker
0-0.371357-7.21271121.281644
13.729082-7.21035821.666903
27.852785-7.17267321.919437
3-2.425268-5.13237520.729973
41.647591-5.20384521.507475
55.781509-5.17977421.844798
610.426066-5.38555023.163378
7-0.492406-3.47913223.108578
83.674880-3.16068821.639878
97.781394-3.09290621.788969
10-2.517106-1.14287120.523918
111.558780-1.12555921.249342
125.659621-1.07111921.533334
139.741386-0.99236221.646158
14-0.5523670.87985820.547612
153.5244170.94484521.036113
167.6217731.01370221.392528
\n", + "
" + ], + "text/plain": [ + " rx ry rz\n", + "marker \n", + "0 -0.371357 -7.212711 21.281644\n", + "1 3.729082 -7.210358 21.666903\n", + "2 7.852785 -7.172673 21.919437\n", + "3 -2.425268 -5.132375 20.729973\n", + "4 1.647591 -5.203845 21.507475\n", + "5 5.781509 -5.179774 21.844798\n", + "6 10.426066 -5.385550 23.163378\n", + "7 -0.492406 -3.479132 23.108578\n", + "8 3.674880 -3.160688 21.639878\n", + "9 7.781394 -3.092906 21.788969\n", + "10 -2.517106 -1.142871 20.523918\n", + "11 1.558780 -1.125559 21.249342\n", + "12 5.659621 -1.071119 21.533334\n", + "13 9.741386 -0.992362 21.646158\n", + "14 -0.552367 0.879858 20.547612\n", + "15 3.524417 0.944845 21.036113\n", + "16 7.621773 1.013702 21.392528" + ] + }, + "execution_count": 131, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data = pd.DataFrame(data = tvecs.reshape(len(tvecs),3), columns = [\"tx\", \"ty\", \"tz\"], \n", + " index = ids.flatten())\n", + "data.index.name = \"marker\"\n", + "data.sort_index(inplace= True)\n", + "datar = pd.DataFrame(data = tvecs.reshape(len(rvecs),3), columns = [\"rx\", \"ry\", \"rz\"], \n", + " index = ids.flatten())\n", + "datar.index.name = \"marker\"\n", + "datar.sort_index(inplace= True)\n", + "np.degrees(datar)" + ] + }, + { + "cell_type": "code", + "execution_count": 116, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([0.07247715, 0.07235671, 0.07102116])" + ] + }, + "execution_count": 116, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "v = data.loc[3:6].values\n", + "((v[1:] - v[:-1])**2).sum(axis = 1)**.5" + ] + }, + { + "cell_type": "code", + "execution_count": 139, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(array([[ 0.99362566, 0.02736779, -0.10935749],\n", + " [ 0.00425153, -0.97849066, -0.20624733],\n", + " [-0.11264982, 0.2044677 , -0.97236977]]),\n", + " array([[ 0.00367594, -0.0625552 , 0.01774466, 0.05511376, -0.2054306 ,\n", + " 0.97575197, 0.03450362, -0.9747257 , -0.20896037],\n", + " [-0.01076324, 0.67264604, 0.07054117, 0.67358929, 0.00914596,\n", + " -0.02950556, -0.0695149 , -0.04626453, -0.00167504],\n", + " [ 0.07557143, -0.06627069, 0.67005951, 0.06729696, 0.01156224,\n", + " -0.05346701, 0.66911627, 0.06420195, -0.06401741]]))" + ] + }, + "execution_count": 139, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cv2.Rodrigues(rvecs[0], np.zeros((3,3)))" + ] + }, + { + "cell_type": "code", + "execution_count": 117, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " this.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width);\n", + " canvas.attr('height', height);\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "workdir = \"./workdir/\"\n", + "aruco_dict = aruco.Dictionary_get(aruco.DICT_6X6_250)\n", + "board = aruco.CharucoBoard_create(7, 5, 1, .8, aruco_dict)\n", + "imboard = board.draw((2000, 2000))\n", + "cv2.imwrite(workdir + \"chessboard.tiff\", imboard)\n", + "fig = plt.figure()\n", + "ax = fig.add_subplot(1,1,1)\n", + "plt.imshow(imboard, cmap = mpl.cm.gray, interpolation = \"nearest\")\n", + "ax.axis(\"off\")\n", + "plt.show()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And take photos of it from multiple angles, for example:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " this.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width);\n", + " canvas.attr('height', height);\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "i=0 # select image id\n", + "plt.figure()\n", + "frame = cv2.imread(images[i])\n", + "img_undist = cv2.undistort(frame,mtx,dist,None)\n", + "plt.subplot(1,2,1)\n", + "plt.imshow(frame)\n", + "plt.title(\"Raw image\")\n", + "plt.axis(\"off\")\n", + "plt.subplot(1,2,2)\n", + "plt.imshow(img_undist)\n", + "plt.title(\"Corrected image\")\n", + "plt.axis(\"off\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3 . Use of camera calibration to estimate 3D translation and rotation of each marker on a scene" + ] + }, + { + "cell_type": "code", + "execution_count": 124, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " this.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width);\n", + " canvas.attr('height', height);\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure()\n", + "plt.imshow(frame_markers, interpolation = \"nearest\")\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Add local axis on each marker" + ] + }, + { + "cell_type": "code", + "execution_count": 127, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "size_of_marker = 0.0285 # side lenght of the marker in meter\n", + "rvecs,tvecs = aruco.estimatePoseSingleMarkers(corners, size_of_marker , mtx, dist)" + ] + }, + { + "cell_type": "code", + "execution_count": 128, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "length_of_axis = 0.02\n", + "imaxis = aruco.drawDetectedMarkers(frame.copy(), corners, ids)\n", + "for i in range(len(tvecs)):\n", + " imaxis = aruco.drawAxis(imaxis, mtx, dist, rvecs[i], tvecs[i], length_of_axis)" + ] + }, + { + "cell_type": "code", + "execution_count": 130, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " this.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width);\n", + " canvas.attr('height', height);\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig = plt.figure()\n", + "#ax = fig.add_subplot(111, projection='3d')\n", + "ax = fig.add_subplot(1,2,1)\n", + "ax.set_aspect(\"equal\")\n", + "plt.plot(data.tx, data.ty, \"or-\")\n", + "plt.grid()\n", + "ax = fig.add_subplot(1,2,2)\n", + "plt.imshow(imaxis, origin = \"lower\")\n", + "plt.plot(np.array(corners)[:, 0, 0,0], np.array(corners)[:, 0, 0,1], \"or\")\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,\n", + " 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,\n", + " 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49])" + ] + }, + "execution_count": 66, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "a = np.arange(50)\n", + "a" + ] + }, + { + "cell_type": "code", + "execution_count": 291, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import pickle" + ] + }, + { + "cell_type": "code", + "execution_count": 273, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "f = open(\"truc.pckl\", \"wb\")\n", + "pickle.dump(a, f)\n", + "f.close()" + ] + }, + { + "cell_type": "code", + "execution_count": 274, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ True, True, True, True, True, True, True, True, True,\n", + " True, True, True, True, True, True, True, True, True,\n", + " True, True, True, True, True, True, True, True, True,\n", + " True, True, True, True, True, True, True, True, True,\n", + " True, True, True, True, True, True, True, True, True,\n", + " True, True, True, True, True], dtype=bool)" + ] + }, + "execution_count": 274, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "f = open(\"truc.pckl\", \"rb\")\n", + "b = pickle.load(f)\n", + "b == a" + ] + }, + { + "cell_type": "code", + "execution_count": 137, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
pxpy
0177.324295222.723907
1174.117722448.426971
5165.1674351385.455933
6292.872223348.533112
7290.211761572.901550
8286.861359800.593140
9285.0438231029.405640
10284.0549321261.753418
11406.743347250.763550
12405.577484469.121307
13402.066681691.525330
14398.973602918.603577
16397.4761051371.831177
17514.600769374.230682
18512.135010590.534302
19509.453247809.594849
20507.9595951029.593262
21507.5210881253.295044
22615.594482280.054901
23614.357056490.602081
24613.074951704.512085
25611.417297922.586426
26611.0856321139.391602
27611.0362551359.634644
28716.764465397.975067
29716.205688606.338318
30714.187927817.897095
31713.4941411029.665405
32713.1557621244.999390
33811.479309305.960754
34811.358704509.836670
35810.507996716.540955
36810.085144926.713257
37810.0136111135.423462
38810.0147711347.564697
39906.448242420.143951
40906.174988621.917664
41905.748413825.513733
42906.0839231029.803955
43906.3878781237.707520
\n", + "
" + ], + "text/plain": [ + " px py\n", + "0 177.324295 222.723907\n", + "1 174.117722 448.426971\n", + "5 165.167435 1385.455933\n", + "6 292.872223 348.533112\n", + "7 290.211761 572.901550\n", + "8 286.861359 800.593140\n", + "9 285.043823 1029.405640\n", + "10 284.054932 1261.753418\n", + "11 406.743347 250.763550\n", + "12 405.577484 469.121307\n", + "13 402.066681 691.525330\n", + "14 398.973602 918.603577\n", + "16 397.476105 1371.831177\n", + "17 514.600769 374.230682\n", + "18 512.135010 590.534302\n", + "19 509.453247 809.594849\n", + "20 507.959595 1029.593262\n", + "21 507.521088 1253.295044\n", + "22 615.594482 280.054901\n", + "23 614.357056 490.602081\n", + "24 613.074951 704.512085\n", + "25 611.417297 922.586426\n", + "26 611.085632 1139.391602\n", + "27 611.036255 1359.634644\n", + "28 716.764465 397.975067\n", + "29 716.205688 606.338318\n", + "30 714.187927 817.897095\n", + "31 713.494141 1029.665405\n", + "32 713.155762 1244.999390\n", + "33 811.479309 305.960754\n", + "34 811.358704 509.836670\n", + "35 810.507996 716.540955\n", + "36 810.085144 926.713257\n", + "37 810.013611 1135.423462\n", + "38 810.014771 1347.564697\n", + "39 906.448242 420.143951\n", + "40 906.174988 621.917664\n", + "41 905.748413 825.513733\n", + "42 906.083923 1029.803955\n", + "43 906.387878 1237.707520" + ] + }, + "execution_count": 137, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "corners = np.array(corners)\n", + "data2 = pd.DataFrame({\"px\": corners[:, 0, 0, 1], \n", + " \"py\": corners[:, 0, 0, 0]}, index = ids.flatten())\n", + "data2.sort_index(inplace=True)\n", + "data2" + ] + }, + { + "cell_type": "code", + "execution_count": 321, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.043476117957396747" + ] + }, + "execution_count": 321, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "m0 = data2.loc[0]\n", + "m43 = data2.loc[43]\n", + "d01 = ((m0 - m43).values**2).sum()**.5\n", + "d = 42.5e-3 * (3.5**2 + 4.5**2)**.5\n", + "factor = d / d01\n", + "data2[\"x\"] = data2.px * factor\n", + "data2[\"y\"] = data2.py * factor\n", + "((data2[[\"x\", \"y\"]].loc[11] - data2[[\"x\", \"y\"]].loc[0]).values**2).sum()**.5\n" + ] + }, + { + "cell_type": "code", + "execution_count": 347, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 138.33575835, 143.00113377, 142.012097 , 140.69699432,\n", + " 146.66782406, 144.02442319, 138.67845434, 142.33812925,\n", + " 143.00229095, 140.33926025, 140.35356753, 146.66786569,\n", + " 139.34054504, 146.67222201, 140.03570454, 148.01939184,\n", + " 143.35647769, 142.67236143, 147.01931296, 148.02127735,\n", + " 137.67392157, 135.35308209, 141.00354688, 143.67946992,\n", + " 137.67149733, 138.67392207, 145.00112611, 142.33454105,\n", + " 138.3466791 , 143.00234925, 139.0035972 , 143.00115739,\n", + " 143.6865917 , 144.67964727, 144.33446711, 141.67253496,\n", + " 143.67117097, 147.67232772, 150.35663387, 141.70034559,\n", + " 149.01342342, 146.01949591, 144.34013329, 150.35333222])" + ] + }, + "execution_count": 347, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\n", + "c = np.array(corners).astype(np.float64).reshape(44,4,2)\n", + "(((c[:, 1:] - c[:, :-1])**2).sum(axis = 2)**.5).mean(axis =1)" + ] + }, + { + "cell_type": "code", + "execution_count": 343, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[[ 2406., 1940.],\n", + " [ 2546., 1940.],\n", + " [ 2545., 2075.],\n", + " [ 2405., 2076.]],\n", + "\n", + " [[ 1991., 1938.],\n", + " [ 2138., 1939.],\n", + " [ 2138., 2076.],\n", + " [ 1993., 2076.]],\n", + "\n", + " [[ 1584., 1936.],\n", + " [ 1728., 1936.],\n", + " [ 1731., 2073.],\n", + " [ 1586., 2072.]],\n", + "\n", + " [[ 2619., 1735.],\n", + " [ 2759., 1735.],\n", + " [ 2754., 1878.],\n", + " [ 2615., 1877.]],\n", + "\n", + " [[ 2198., 1734.],\n", + " [ 2347., 1734.],\n", + " [ 2346., 1878.],\n", + " [ 2199., 1878.]],\n", + "\n", + " [[ 973., 1733.],\n", + " [ 1117., 1731.],\n", + " [ 1121., 1874.],\n", + " [ 976., 1875.]],\n", + "\n", + " [[ 572., 1732.],\n", + " [ 710., 1732.],\n", + " [ 713., 1874.],\n", + " [ 577., 1873.]],\n", + "\n", + " [[ 2410., 1533.],\n", + " [ 2554., 1533.],\n", + " [ 2552., 1672.],\n", + " [ 2408., 1672.]],\n", + "\n", + " [[ 1373., 1326.],\n", + " [ 1519., 1325.],\n", + " [ 1519., 1463.],\n", + " [ 1374., 1464.]],\n", + "\n", + " [[ 1785., 1326.],\n", + " [ 1926., 1324.],\n", + " [ 1927., 1463.],\n", + " [ 1786., 1463.]],\n", + "\n", + " [[ 2627., 1323.],\n", + " [ 2767., 1324.],\n", + " [ 2763., 1464.],\n", + " [ 2622., 1464.]],\n", + "\n", + " [[ 2200., 1324.],\n", + " [ 2350., 1324.],\n", + " [ 2349., 1463.],\n", + " [ 2198., 1463.]],\n", + "\n", + " [[ 760., 1128.],\n", + " [ 901., 1127.],\n", + " [ 903., 1265.],\n", + " [ 764., 1266.]],\n", + "\n", + " [[ 1988., 1123.],\n", + " [ 2138., 1121.],\n", + " [ 2138., 1261.],\n", + " [ 1988., 1262.]],\n", + "\n", + " [[ 547., 920.],\n", + " [ 687., 918.],\n", + " [ 692., 1058.],\n", + " [ 552., 1059.]],\n", + "\n", + " [[ 2203., 910.],\n", + " [ 2354., 908.],\n", + " [ 2351., 1050.],\n", + " [ 2200., 1052.]],\n", + "\n", + " [[ 2631., 908.],\n", + " [ 2775., 906.],\n", + " [ 2771., 1050.],\n", + " [ 2629., 1050.]],\n", + "\n", + " [[ 750., 708.],\n", + " [ 890., 707.],\n", + " [ 892., 855.],\n", + " [ 752., 855.]],\n", + "\n", + " [[ 2419., 695.],\n", + " [ 2565., 693.],\n", + " [ 2563., 842.],\n", + " [ 2417., 845.]],\n", + "\n", + " [[ 946., 494.],\n", + " [ 1093., 491.],\n", + " [ 1096., 642.],\n", + " [ 950., 643.]],\n", + "\n", + " [[ 1181., 1936.],\n", + " [ 1319., 1935.],\n", + " [ 1321., 2073.],\n", + " [ 1184., 2072.]],\n", + "\n", + " [[ 780., 1935.],\n", + " [ 916., 1935.],\n", + " [ 920., 2070.],\n", + " [ 785., 2070.]],\n", + "\n", + " [[ 1788., 1731.],\n", + " [ 1928., 1732.],\n", + " [ 1929., 1876.],\n", + " [ 1790., 1875.]],\n", + "\n", + " [[ 1378., 1731.],\n", + " [ 1521., 1730.],\n", + " [ 1524., 1873.],\n", + " [ 1379., 1874.]],\n", + "\n", + " [[ 771., 1533.],\n", + " [ 909., 1533.],\n", + " [ 911., 1671.],\n", + " [ 774., 1671.]],\n", + "\n", + " [[ 1176., 1533.],\n", + " [ 1315., 1532.],\n", + " [ 1317., 1669.],\n", + " [ 1177., 1670.]],\n", + "\n", + " [[ 1989., 1532.],\n", + " [ 2137., 1532.],\n", + " [ 2137., 1671.],\n", + " [ 1989., 1670.]],\n", + "\n", + " [[ 1581., 1531.],\n", + " [ 1726., 1531.],\n", + " [ 1727., 1669.],\n", + " [ 1583., 1669.]],\n", + "\n", + " [[ 560., 1329.],\n", + " [ 700., 1328.],\n", + " [ 703., 1465.],\n", + " [ 565., 1466.]],\n", + "\n", + " [[ 966., 1328.],\n", + " [ 1112., 1327.],\n", + " [ 1113., 1465.],\n", + " [ 968., 1465.]],\n", + "\n", + " [[ 1169., 1127.],\n", + " [ 1309., 1126.],\n", + " [ 1310., 1264.],\n", + " [ 1171., 1265.]],\n", + "\n", + " [[ 1579., 1124.],\n", + " [ 1723., 1123.],\n", + " [ 1723., 1263.],\n", + " [ 1578., 1263.]],\n", + "\n", + " [[ 2415., 1120.],\n", + " [ 2560., 1119.],\n", + " [ 2556., 1261.],\n", + " [ 2412., 1261.]],\n", + "\n", + " [[ 956., 919.],\n", + " [ 1103., 918.],\n", + " [ 1106., 1058.],\n", + " [ 959., 1059.]],\n", + "\n", + " [[ 1367., 917.],\n", + " [ 1514., 916.],\n", + " [ 1514., 1056.],\n", + " [ 1368., 1056.]],\n", + "\n", + " [[ 1784., 914.],\n", + " [ 1926., 912.],\n", + " [ 1926., 1053.],\n", + " [ 1784., 1054.]],\n", + "\n", + " [[ 1160., 706.],\n", + " [ 1302., 706.],\n", + " [ 1304., 854.],\n", + " [ 1163., 854.]],\n", + "\n", + " [[ 1574., 703.],\n", + " [ 1722., 702.],\n", + " [ 1722., 850.],\n", + " [ 1575., 852.]],\n", + "\n", + " [[ 1991., 699.],\n", + " [ 2142., 697.],\n", + " [ 2138., 847.],\n", + " [ 1988., 848.]],\n", + "\n", + " [[ 539., 499.],\n", + " [ 677., 496.],\n", + " [ 681., 644.],\n", + " [ 542., 646.]],\n", + "\n", + " [[ 1360., 490.],\n", + " [ 1508., 488.],\n", + " [ 1510., 639.],\n", + " [ 1362., 641.]],\n", + "\n", + " [[ 1784., 486.],\n", + " [ 1928., 483.],\n", + " [ 1926., 635.],\n", + " [ 1784., 637.]],\n", + "\n", + " [[ 2637., 479.],\n", + " [ 2778., 480.],\n", + " [ 2776., 630.],\n", + " [ 2634., 629.]],\n", + "\n", + " [[ 2207., 481.],\n", + " [ 2356., 478.],\n", + " [ 2356., 629.],\n", + " [ 2205., 632.]]])" + ] + }, + "execution_count": 343, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "c" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Help on built-in function detectMarkers:\n", + "\n", + "detectMarkers(...)\n", + " detectMarkers(image, dictionary[, corners[, ids[, parameters[, rejectedImgPoints]]]]) -> corners, ids, rejectedImgPoints\n", + "\n" + ] + } + ], + "source": [ + "help(cv2.aruco.detectMarkers)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "anaconda-cloud": {}, + "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.6.1" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +}