From ea2bba87149021e2f3ab441442d6a20c87e5bd70 Mon Sep 17 00:00:00 2001 From: "Olivier J.N. Bertrand" <olivier.bertrand@uni-bielefeld.de> Date: Sat, 12 Oct 2019 22:34:33 +0200 Subject: [PATCH] Update doc --- doc/source/index.rst | 2 +- doc/source/tests/index.rst | 2 +- doc/source/tests/moving.rst | 14 - doc/source/tutorials/database.rst | 33 - doc/source/tutorials/opticFlow_tutorial.ipynb | 625 ------------------ doc/source/tutorials/renderimage.rst | 25 - 6 files changed, 2 insertions(+), 699 deletions(-) delete mode 100644 doc/source/tests/moving.rst delete mode 100644 doc/source/tutorials/database.rst delete mode 100644 doc/source/tutorials/opticFlow_tutorial.ipynb delete mode 100644 doc/source/tutorials/renderimage.rst diff --git a/doc/source/index.rst b/doc/source/index.rst index e921c8a..b720946 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -26,7 +26,7 @@ Content tutorials/index references/index tests/index - + Indices and tables ================== diff --git a/doc/source/tests/index.rst b/doc/source/tests/index.rst index c27dd65..c386089 100644 --- a/doc/source/tests/index.rst +++ b/doc/source/tests/index.rst @@ -9,6 +9,6 @@ Tests sensors processing comparing - moving database maths + arenatools diff --git a/doc/source/tests/moving.rst b/doc/source/tests/moving.rst deleted file mode 100644 index 7edeb2d..0000000 --- a/doc/source/tests/moving.rst +++ /dev/null @@ -1,14 +0,0 @@ -Moving -====== - -Agents -~~~~~~ - -.. automodule:: navipy.moving.test_agent - :members: - -Maths -~~~~~ - -.. automodule:: navipy.moving.test_maths - :members: diff --git a/doc/source/tutorials/database.rst b/doc/source/tutorials/database.rst deleted file mode 100644 index 55a2059..0000000 --- a/doc/source/tutorials/database.rst +++ /dev/null @@ -1,33 +0,0 @@ -How to generate a database using blender ----------------------------------------- -.. literalinclude:: examples/blenddemo_beesampling.py - :lines: 7, 8 - -First we configure the rendering module - -.. literalinclude:: examples/blenddemo_beesampling.py - :lines: 11, 12 - -With the toolbox at disposition we just need to configure the \ -BeeSampling to render images on a regular 3D grid. - -.. literalinclude:: examples/blenddemo_beesampling.py - :lines: 13,16-23 - -If we want to use the distance to objects, we need to tell the \ -BeeSampling what is the maximum distance to objects in the environment.\ - Otherwise the distance can go until infinity, and since the image are \ -compressed in the database, all distances to object will be equal to \ -zero: - -.. literalinclude:: examples/blenddemo_beesampling.py - :lines: 27-28 - -Finally we can generate the database. - -.. literalinclude:: examples/blenddemo_beesampling.py - :dedent: 4 - :lines: 31-32 - -(:download:`Source code <examples/blenddemo_beesampling.py>`) -(:download:`Blender world <../../../navipy/resources/forest_world.blend>`) diff --git a/doc/source/tutorials/opticFlow_tutorial.ipynb b/doc/source/tutorials/opticFlow_tutorial.ipynb deleted file mode 100644 index 5cab175..0000000 --- a/doc/source/tutorials/opticFlow_tutorial.ipynb +++ /dev/null @@ -1,625 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Using the Optic Flow function\n", - "\n", - "This Tutorial explains how to use the optic flow function of the navipy toolbox.\n", - "\n", - "The function computes the optic for a positions with an already rendered scene.\n", - "Therefore if the optic flow of a whole trajectory is wanted, this function has to be called in a loop for each step.\n", - "\n", - "So to get the optic flow we need:\n", - "* the viewing direction (in radians)\n", - "* the already rendered scene\n", - "* velocity of the bee including the accaleration\n", - "\n", - "The constructor of the optic_flow function is the following:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'optic_flow' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[1;32m<ipython-input-1-b9f43b3f8149>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0moptic_flow\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mscene\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mviewing_directions\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mvelocity\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdistance_channel\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m3\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[1;31mNameError\u001b[0m: name 'optic_flow' is not defined" - ] - } - ], - "source": [ - "optic_flow(scene, viewing_directions, velocity, distance_channel=3)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "* scene: ibpc\n", - "* param viewing_directions: viewing direction of each pixel\n", - " (azimuth,elevation) in radians\n", - "* param velocity: pandas series\n", - " (x,y,z,alpha,beta,gamma,dx,dy,dz,dalpha,dbeta,dgamma)\n", - "* distance channel: distance; possible choices= 0,1,2,3; default :3" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The scenes must be of h x w 4 x 1 where h is the hight of image and w the width. The third dimension is needed for the different channels. We have R, G, B, D. Where R is the red, G is the green, B is the blue and D is the distance channel. Here is an example for how to initialize a random scene with 180 x 180 dimension. \n", - "\n", - "\n", - "For an example on how to get a rendered scene please refer to the other tutorials." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "import numpy as np\n", - "scene = np.random.random((180, 360, 4, 1))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To set up the viewing direction with a 180 x 180 scene, the following can be done:" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "elevation = np.arange(-np.pi/2, np.pi/2, 2*(np.pi/360))\n", - "azimuth = np.arange(0, 2*np.pi, 2*(np.pi/360))\n", - "\n", - "viewing_directions = np.zeros((180, 2))\n", - "viewing_directions[:, 0] = elevation\n", - "viewing_directions[:, 1] = azimuth[0:180]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The velocity contains the velocity of the current position as well as the acceleration (difference of velocity to the old position). The velocity must be a pandas dataframe with a multiindex, where the angles index must contain the convention to be used.\n", - "The conventions that can be used are:\n", - "'sxyz', 'sxyx', 'sxzy','sxzx', 'syzx', 'syzy',\n", - "'syxz', 'syxy', 'szxy', 'szxz', 'szyx', 'szyz',\n", - "'rzyx', 'rxyx', 'ryzx', 'rxzx', 'rxzy', 'ryzy',\n", - "'rzxy', 'ryxy', 'ryxz', 'rzxz', 'rxyz', 'rzyz'\n", - "\n", - "Here is an example on how to initilize it. In this example the bee is rotating around the x axis (yaw) and stays constant otherwise." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "import pandas as pd\n", - "\n", - "# only the yaw is changes aka the bee is tilted up\n", - "positions = np.array([[-20, -20, 2.6, 1.57079633, 0, 0],\n", - " [-20, -20, 2.6, 1.90079633, 0, 0]])\n", - "x = positions[0, 0]\n", - "y = positions[0, 1]\n", - "z = positions[0, 2]\n", - "yaw = positions[0, 3]\n", - "pitch = positions[0, 4]\n", - "roll = positions[0, 5]\n", - "\n", - "dx = positions[1, 0]-positions[0, 0]\n", - "dy = positions[1, 1]-positions[0, 1]\n", - "dz = positions[1, 2]-positions[0, 2]\n", - "dyaw = positions[1, 3]-positions[0, 3]\n", - "dpitch = positions[1, 4]-positions[0, 4]\n", - "droll = positions[1, 5]-positions[0, 5]\n", - "\n", - "tuples = [('location', 'x'), ('location', 'y'),\n", - " ('location', 'z'), ('location', 'dx'),\n", - " ('location', 'dy'), ('location', 'dz'),\n", - " ('rxyz', 'alpha_0'), ('rxyz', 'alpha_1'),\n", - " ('rxyz', 'alpha_2'), ('rxyz', 'dalpha_0'),\n", - " ('rxyz', 'dalpha_1'), ('rxyz', 'dalpha_2')]\n", - "index = pd.MultiIndex.from_tuples(tuples,\n", - " names=['position', 'orientation'])\n", - "velocity = pd.Series(index=index)\n", - "\n", - "velocity['location']['x'] = x\n", - "velocity['location']['y'] = y\n", - "velocity['location']['z'] = z\n", - "velocity['rxyz']['alpha_0'] = yaw\n", - "velocity['rxyz']['alpha_1'] = pitch\n", - "velocity['rxyz']['alpha_2'] = roll\n", - "velocity['location']['dx'] = dx\n", - "velocity['location']['dy'] = dy\n", - "velocity['location']['dz'] = dz\n", - "velocity['rxyz']['dalpha_0'] = dyaw\n", - "velocity['rxyz']['dalpha_1'] = dpitch\n", - "velocity['rxyz']['dalpha_2'] = droll" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "So then the optic flow function can be called as follows:" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "from navipy.processing import mcode\n", - "\n", - "rof, hof, vof = mcode.optic_flow(scene, viewing_directions,\n", - " velocity)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here is an example that loads a scene from the database and calculates the horizontal, vertical and rotational optic flow" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "<matplotlib.image.AxesImage at 0x7fa2a919fe48>" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "<matplotlib.figure.Figure at 0x7fa3001030f0>" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# Load the necessary modules\n", - "from navipy.processing import mcode\n", - "from navipy.database import DataBaseLoad\n", - "from matplotlib.image import imsave\n", - "import numpy as np\n", - "import os\n", - "import matplotlib.pyplot as plt\n", - "# Load the database, and specify the\n", - "# the output directory to save the list\n", - "# of images\n", - "import pkg_resources\n", - "%matplotlib inline\n", - "database = pkg_resources.resource_filename(\n", - " 'navipy',\n", - " 'resources/database.db')\n", - "mydb = DataBaseLoad(database)\n", - "\n", - "my_scene = mydb.scene(rowid=2)\n", - "rof, hof, vof = mcode.optic_flow(my_scene, viewing_directions,\n", - " velocity)\n", - "f, axarr = plt.subplots(2, 2, figsize=(15, 4))\n", - "\n", - "plt.subplot(221)\n", - "to_plot_im = my_scene[:, :, :3, 0].astype(float)\n", - "to_plot_im = my_scene[:, :, :3, 0]\n", - "to_plot_im -= to_plot_im.min()\n", - "to_plot_im /= to_plot_im.max()\n", - "to_plot_im = to_plot_im * 255\n", - " \n", - "to_plot_im = to_plot_im.astype(np.uint8)\n", - " \n", - "to_plot_dist = my_scene[:, :, 3, 0]\n", - "plt.imshow(to_plot_im)\n", - "\n", - "plt.subplot(222)\n", - "plt.imshow(hof, cmap='gray')\n", - "plt.subplot(223)\n", - "plt.imshow(vof, cmap='gray')\n", - "plt.subplot(224)\n", - "plt.imshow(rof, cmap='gray')\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "collapsed": true - }, - "source": [ - "# Example with a trajectory\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "dict_keys(['__globals__', '__version__', 'trajectory', 'cylinders', 'nests', '__header__'])\n", - "(7661, 4)\n", - "conv rzyx\n" - ] - }, - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead tr th {\n", - " text-align: left;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr>\n", - " <th></th>\n", - " <th colspan=\"3\" halign=\"left\">location</th>\n", - " <th colspan=\"3\" halign=\"left\">rzyx</th>\n", - " </tr>\n", - " <tr>\n", - " <th></th>\n", - " <th>x</th>\n", - " <th>y</th>\n", - " <th>z</th>\n", - " <th>alpha_0</th>\n", - " <th>alpha_1</th>\n", - " <th>alpha_2</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>0</th>\n", - " <td>3.056519</td>\n", - " <td>-214.990482</td>\n", - " <td>9.330593</td>\n", - " <td>2.79751</td>\n", - " <td>0</td>\n", - " <td>0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1</th>\n", - " <td>4.611665</td>\n", - " <td>-215.020314</td>\n", - " <td>8.424138</td>\n", - " <td>2.80863</td>\n", - " <td>0</td>\n", - " <td>0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>2</th>\n", - " <td>4.556650</td>\n", - " <td>-214.593236</td>\n", - " <td>9.185016</td>\n", - " <td>2.81407</td>\n", - " <td>0</td>\n", - " <td>0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>3</th>\n", - " <td>4.643091</td>\n", - " <td>-213.829769</td>\n", - " <td>10.542035</td>\n", - " <td>2.82704</td>\n", - " <td>0</td>\n", - " <td>0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>4</th>\n", - " <td>4.647302</td>\n", - " <td>-214.431592</td>\n", - " <td>7.461187</td>\n", - " <td>2.82896</td>\n", - " <td>0</td>\n", - " <td>0</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " location rzyx \n", - " x y z alpha_0 alpha_1 alpha_2\n", - "0 3.056519 -214.990482 9.330593 2.79751 0 0\n", - "1 4.611665 -215.020314 8.424138 2.80863 0 0\n", - "2 4.556650 -214.593236 9.185016 2.81407 0 0\n", - "3 4.643091 -213.829769 10.542035 2.82704 0 0\n", - "4 4.647302 -214.431592 7.461187 2.82896 0 0" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from scipy.io import loadmat\n", - "import numpy as np\n", - "import os\n", - "from navipy.trajectories import Trajectory\n", - "import pkg_resources\n", - "# Use the trafile from the resources\n", - "# You can adapt this code, by changing trajfile \n", - "# with your own trajectory file\n", - "trajfile = pkg_resources.resource_filename(\n", - " 'navipy',\n", - " 'resources/sample_experiment/Lobecke_JEB_2018/Y101_OBFlight_0001.mat')\n", - "csvtrajfile, _ = os.path.splitext(trajfile)\n", - "csvtrajfile = csvtrajfile+'.csv'\n", - "mymat = loadmat(trajfile)\n", - "# matlab files are loaded in a dictionary\n", - "# we need to identify, under which key the trajectory has been saved\n", - "print(mymat.keys())\n", - "key = 'trajectory'\n", - "# Arrays are placed in a tupple. We need to access the level\n", - "# of the array itself.\n", - "mymat = mymat[key][0][0][0]\n", - "# The array should be a numpy array, and therefore as the .shape function\n", - "# to display the array size:\n", - "print(mymat.shape)\n", - "# In this example the array has 7661 rows and 4 columns\n", - "# the columns are: x,y,z, yaw. Therefore pitch and roll were assumed to be constant (here null)\n", - "# We can therefore init a trajectory with the convention for rotation\n", - "# often yaw-pitch-roll (i.e. 'rzyx') and with indeces the number of sampling points we have \n", - "# in the trajectory\n", - "rotconvention = 'rzyx'\n", - "indeces = np.arange(0,mymat.shape[0])\n", - "mytraj = Trajectory(rotconv = rotconvention, indeces=indeces)\n", - "# We now can assign the values\n", - "mytraj.x = mymat[:,0]\n", - "mytraj.y = mymat[:,1]\n", - "mytraj.z = mymat[:,2]\n", - "mytraj.alpha_0 = mymat[:,3]\n", - "mytraj.alpha_1 = 0\n", - "mytraj.alpha_2 = 0\n", - "# We can then save mytraj as csv file for example\n", - "mytraj.to_csv(csvtrajfile)\n", - "mytraj.head()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Then we need the velocity to calculate the optic flow" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>dx</th>\n", - " <th>dy</th>\n", - " <th>dz</th>\n", - " <th>dalpha_0</th>\n", - " <th>dalpha_1</th>\n", - " <th>dalpha_2</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>0</th>\n", - " <td>NaN</td>\n", - " <td>NaN</td>\n", - " <td>NaN</td>\n", - " <td>NaN</td>\n", - " <td>NaN</td>\n", - " <td>NaN</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1</th>\n", - " <td>1.555146</td>\n", - " <td>-0.029831</td>\n", - " <td>-0.906455</td>\n", - " <td>0.01112</td>\n", - " <td>0.0</td>\n", - " <td>0.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>2</th>\n", - " <td>-0.055015</td>\n", - " <td>0.427078</td>\n", - " <td>0.760878</td>\n", - " <td>0.00544</td>\n", - " <td>0.0</td>\n", - " <td>0.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>3</th>\n", - " <td>0.086441</td>\n", - " <td>0.763467</td>\n", - " <td>1.357019</td>\n", - " <td>0.01297</td>\n", - " <td>0.0</td>\n", - " <td>0.0</td>\n", - " </tr>\n", - " <tr>\n", - " <th>4</th>\n", - " <td>0.004211</td>\n", - " <td>-0.601823</td>\n", - " <td>-3.080847</td>\n", - " <td>0.00192</td>\n", - " <td>0.0</td>\n", - " <td>0.0</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "text/plain": [ - " dx dy dz dalpha_0 dalpha_1 dalpha_2\n", - "0 NaN NaN NaN NaN NaN NaN\n", - "1 1.555146 -0.029831 -0.906455 0.01112 0.0 0.0\n", - "2 -0.055015 0.427078 0.760878 0.00544 0.0 0.0\n", - "3 0.086441 0.763467 1.357019 0.01297 0.0 0.0\n", - "4 0.004211 -0.601823 -3.080847 0.00192 0.0 0.0" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "vel = mytraj.velocity()\n", - "vel.head()\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Iterate through the trajectory to get the optic flow of each scene" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "tuples = [('location', 'x'), ('location', 'y'),\n", - " ('location', 'z'), ('location', 'dx'),\n", - " ('location', 'dy'), ('location', 'dz'),\n", - " ('rxyz', 'alpha_0'), ('rxyz', 'alpha_1'),\n", - " ('rxyz', 'alpha_2'), ('rxyz', 'dalpha_0'),\n", - " ('rxyz', 'dalpha_1'), ('rxyz', 'dalpha_2')]\n", - "index = pd.MultiIndex.from_tuples(tuples,\n", - " names=['position', 'orientation'])\n", - "\n", - "for i in range(1,10): \n", - " velocity = pd.Series(index=index)\n", - " velocity['location']['x'] = mytraj.x[i]\n", - " velocity['location']['y'] = mytraj.y[i]\n", - " velocity['location']['z'] = mytraj.z[i]\n", - " velocity['rxyz']['alpha_0'] = mytraj.alpha_0[i]\n", - " velocity['rxyz']['alpha_1'] = mytraj.alpha_1[i]\n", - " velocity['rxyz']['alpha_2'] = mytraj.alpha_2[i]\n", - " velocity['location']['dx'] = vel.dx[i]\n", - " velocity['location']['dy'] = vel.dy[i]\n", - " velocity['location']['dz'] = vel.dz[i]\n", - " velocity['rxyz']['dalpha_0'] = vel.dalpha_0[i]\n", - " velocity['rxyz']['dalpha_1'] = vel.dalpha_1[i]\n", - " velocity['rxyz']['dalpha_2'] = vel.dalpha_2[i]\n", - " \n", - " my_scene = mydb.scene(rowid=i)\n", - " rof, hof, vof = mcode.optic_flow(my_scene, viewing_directions,\n", - " velocity)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [] - } - ], - "metadata": { - "anaconda-cloud": {}, - "kernelspec": { - "display_name": "Python [Root]", - "language": "python", - "name": "Python [Root]" - }, - "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.5.2" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} diff --git a/doc/source/tutorials/renderimage.rst b/doc/source/tutorials/renderimage.rst deleted file mode 100644 index 7688636..0000000 --- a/doc/source/tutorials/renderimage.rst +++ /dev/null @@ -1,25 +0,0 @@ -Render a single image ---------------------- -.. literalinclude:: examples/blenddemo_cyberbee.py - :lines: 5 - -With the toolbox at disposition we just need to configure the \ -Cyberbee to render images at desired positions. - -.. literalinclude:: examples/blenddemo_cyberbee.py - :lines: 8-13 - -To render a scene at a given positions, we assign position orientation \ -to and then tell the cyberbee to get the scene at that point. - -.. literalinclude:: examples/blenddemo_cyberbee.py - :lines: 16-24 - -(:download:`Source code <examples/blenddemo_cyberbee.py>`) -(:download:`Blender world <../../../navipy/resources/forest_world.blend>`) - - - -Create a movie --------------- - -- GitLab