{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    },
    "colab": {
      "name": "HelloPyBullet.ipynb",
      "provenance": [],
      "toc_visible": true,
      "include_colab_link": true
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/bulletphysics/bullet3/blob/master/examples/pybullet/notebooks/HelloPyBullet.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "NTwYntjmAJOg"
      },
      "source": [
        "# Hello PyBullet!\n",
        "\n",
        "This notebook shows how to install and create a simple application on PyBullet."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "AAAUJ8y0BjBs"
      },
      "source": [
        "## Setup\n",
        "\n",
        "First, let's install the [PyBullet](https://pybullet.org/wordpress/) module.\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "xyDqmV_YitDg"
      },
      "source": [
        "# Install the PyBullet module.\n",
        "!pip install -U pybullet"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "INLvCOjvEfSl"
      },
      "source": [
        "## Hello PyBullet World!\n",
        "\n",
        "This is based on the\n",
        "[PyBullet Quickstart Guide](https://docs.google.com/document/d/10sXEhzFRSnvFcl3XxNGhnD4N2SedqwdAvK3dsihxVUA/edit?usp=sharing).\n",
        "\n",
        "After importing the PyBullet module, the first thing to do is 'connecting' to the physics simulation.\n",
        "PyBullet is designed around a client-server driven API, with a client sending commands and a physics server returning the status.\n",
        "\n",
        "PyBullet has some built-in physics servers: `DIRECT` and `GUI`.\n",
        "Both `GUI` and `DIRECT` connections will execute the physics simulation and rendering in the same process as PyBullet.\n",
        "\n",
        "In this example, we'll use the `DIRECT` mode to do the calculations independently of rendering."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "ZgNi0AkOipoQ",
        "outputId": "0504f7c7-b028-4388-a2d0-7b224d348561",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 34
        }
      },
      "source": [
        "import pybullet as p\n",
        "\n",
        "p.connect(p.DIRECT)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "0"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 3
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "V1nNu07MG7kR"
      },
      "source": [
        "We want to access the example\n",
        "[Bullet data](https://github.com/bulletphysics/bullet3/tree/master/data)\n",
        "files.\n",
        "Fortunately, we can specify a new search path in PyBullet and point it to the `py_bullet_data.getDataPath()`."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "FW-AXeioHrU4"
      },
      "source": [
        "import pybullet_data\n",
        "\n",
        "p.setAdditionalSearchPath(pybullet_data.getDataPath())"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "6fb-HzCsH6Fs"
      },
      "source": [
        "Now, we can load models from the example data in the\n",
        "[Unified Robot Description Format (URDF)](https://wiki.ros.org/urdf) format.\n",
        "\n",
        "Let's load a `plane` to serve as our simulation floor plane,\n",
        "and an [R2D2 droid](https://en.wikipedia.org/wiki/R2-D2).\n",
        "\n",
        "In Bullet Physics, you can use whatever units you want as long as you are consistent.\n",
        "For this example, we'll use the\n",
        "[metric system](https://en.wikipedia.org/wiki/Metric_system)."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "4UHhYcEgipoX",
        "outputId": "eff70421-0b77-4ba0-e8a9-5777e1519f5c",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 34
        }
      },
      "source": [
        "# First, let's make sure we start with a fresh new simulation.\n",
        "# Otherwise, we can keep adding objects by running this cell over again.\n",
        "p.resetSimulation()\n",
        "\n",
        "# Load our simulation floor plane at the origin (0, 0, 0).\n",
        "p.loadURDF('plane.urdf')\n",
        "\n",
        "# Load an R2D2 droid at the position at 0.5 meters height in the z-axis.\n",
        "r2d2 = p.loadURDF('r2d2.urdf', [0, 0, 0.5])\n",
        "\n",
        "# We can check the number of bodies we have in the simulation.\n",
        "p.getNumBodies()"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "2"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 5
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "5mafnqVkJu67"
      },
      "source": [
        "### Joint information\n",
        "\n",
        "Now that we've populated our simulation with those two objects,\n",
        "we can analyze them to see what's inside.\n",
        "\n",
        "The [`getJointInfo()`](https://docs.google.com/document/d/10sXEhzFRSnvFcl3XxNGhnD4N2SedqwdAvK3dsihxVUA/edit?usp=sharing#heading=h.la294ocbo43o)\n",
        "function returns a list of all the information from the selected joint."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "TkIm1cG-ipof",
        "outputId": "7d4c394c-2f1c-437f-d836-4c370b9a45a1",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 309
        }
      },
      "source": [
        "# First let's define a class for the JointInfo.\n",
        "from dataclasses import dataclass\n",
        "\n",
        "@dataclass\n",
        "class Joint:\n",
        "  index: int\n",
        "  name: str\n",
        "  type: int\n",
        "  gIndex: int\n",
        "  uIndex: int\n",
        "  flags: int\n",
        "  damping: float\n",
        "  friction: float\n",
        "  lowerLimit: float\n",
        "  upperLimit: float\n",
        "  maxForce: float\n",
        "  maxVelocity: float\n",
        "  linkName: str\n",
        "  axis: tuple\n",
        "  parentFramePosition: tuple\n",
        "  parentFrameOrientation: tuple\n",
        "  parentIndex: int\n",
        "\n",
        "  def __post_init__(self):\n",
        "    self.name = str(self.name, 'utf-8')\n",
        "    self.linkName = str(self.linkName, 'utf-8')\n",
        "\n",
        "# Let's analyze the R2D2 droid!\n",
        "print(f\"r2d2 unique ID: {r2d2}\")\n",
        "for i in range(p.getNumJoints(r2d2)):\n",
        "  joint = Joint(*p.getJointInfo(r2d2, i))\n",
        "  print(joint)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "r2d2 unique ID: 1\n",
            "Joint(index=0, name='base_to_right_leg', type=4, gIndex=-1, uIndex=-1, flags=0, damping=0.0, friction=0.0, lowerLimit=0.0, upperLimit=-1.0, maxForce=0.0, maxVelocity=0.0, linkName='right_leg', axis=(0.0, 0.0, 0.0), parentFramePosition=(0.22, 0.0, 0.25), parentFrameOrientation=(0.0, -0.7070904020014416, 0.0, 0.7071231599922604), parentIndex=-1)\n",
            "Joint(index=1, name='right_base_joint', type=4, gIndex=-1, uIndex=-1, flags=0, damping=0.0, friction=0.0, lowerLimit=0.0, upperLimit=-1.0, maxForce=0.0, maxVelocity=0.0, linkName='right_base', axis=(0.0, 0.0, 0.0), parentFramePosition=(0.2999999996780742, 0.0, -1.3898038463944216e-05), parentFrameOrientation=(0.0, 0.7070904020014416, 0.0, 0.7071231599922604), parentIndex=0)\n",
            "Joint(index=2, name='right_front_wheel_joint', type=0, gIndex=7, uIndex=6, flags=1, damping=0.0, friction=0.0, lowerLimit=0.0, upperLimit=-1.0, maxForce=100.0, maxVelocity=100.0, linkName='right_front_wheel', axis=(0.0, 0.0, 1.0), parentFramePosition=(0.0, 0.133333333333, -0.085), parentFrameOrientation=(0.0, -0.7070904020014416, 0.0, 0.7071231599922604), parentIndex=1)\n",
            "Joint(index=3, name='right_back_wheel_joint', type=0, gIndex=8, uIndex=7, flags=1, damping=0.0, friction=0.0, lowerLimit=0.0, upperLimit=-1.0, maxForce=100.0, maxVelocity=100.0, linkName='right_back_wheel', axis=(0.0, 0.0, 1.0), parentFramePosition=(0.0, -0.133333333333, -0.085), parentFrameOrientation=(0.0, -0.7070904020014416, 0.0, 0.7071231599922604), parentIndex=1)\n",
            "Joint(index=4, name='base_to_left_leg', type=4, gIndex=-1, uIndex=-1, flags=0, damping=0.0, friction=0.0, lowerLimit=0.0, upperLimit=-1.0, maxForce=0.0, maxVelocity=0.0, linkName='left_leg', axis=(0.0, 0.0, 0.0), parentFramePosition=(-0.22, 0.0, 0.25), parentFrameOrientation=(0.0, -0.7070904020014416, 0.0, 0.7071231599922604), parentIndex=-1)\n",
            "Joint(index=5, name='left_base_joint', type=4, gIndex=-1, uIndex=-1, flags=0, damping=0.0, friction=0.0, lowerLimit=0.0, upperLimit=-1.0, maxForce=0.0, maxVelocity=0.0, linkName='left_base', axis=(0.0, 0.0, 0.0), parentFramePosition=(0.2999999996780742, 0.0, -1.3898038463944216e-05), parentFrameOrientation=(0.0, 0.7070904020014416, 0.0, 0.7071231599922604), parentIndex=4)\n",
            "Joint(index=6, name='left_front_wheel_joint', type=0, gIndex=9, uIndex=8, flags=1, damping=0.0, friction=0.0, lowerLimit=0.0, upperLimit=-1.0, maxForce=100.0, maxVelocity=100.0, linkName='left_front_wheel', axis=(0.0, 0.0, 1.0), parentFramePosition=(0.0, 0.133333333333, -0.085), parentFrameOrientation=(0.0, -0.7070904020014416, 0.0, 0.7071231599922604), parentIndex=5)\n",
            "Joint(index=7, name='left_back_wheel_joint', type=0, gIndex=10, uIndex=9, flags=1, damping=0.0, friction=0.0, lowerLimit=0.0, upperLimit=-1.0, maxForce=100.0, maxVelocity=100.0, linkName='left_back_wheel', axis=(0.0, 0.0, 1.0), parentFramePosition=(0.0, -0.133333333333, -0.085), parentFrameOrientation=(0.0, -0.7070904020014416, 0.0, 0.7071231599922604), parentIndex=5)\n",
            "Joint(index=8, name='gripper_extension', type=1, gIndex=11, uIndex=10, flags=1, damping=0.0, friction=0.0, lowerLimit=-0.38, upperLimit=0.0, maxForce=1000.0, maxVelocity=0.5, linkName='gripper_pole', axis=(1.0, 0.0, 0.0), parentFramePosition=(0.0, 0.19, 0.2), parentFrameOrientation=(0.0, 0.0, -0.7070904020014416, 0.7071231599922604), parentIndex=-1)\n",
            "Joint(index=9, name='left_gripper_joint', type=0, gIndex=12, uIndex=11, flags=1, damping=0.0, friction=0.0, lowerLimit=0.0, upperLimit=0.548, maxForce=1000.0, maxVelocity=0.5, linkName='left_gripper', axis=(0.0, 0.0, 1.0), parentFramePosition=(0.2, 0.02, 0.0), parentFrameOrientation=(0.0, 0.0, 0.0, 1.0), parentIndex=8)\n",
            "Joint(index=10, name='left_tip_joint', type=4, gIndex=-1, uIndex=-1, flags=0, damping=0.0, friction=0.0, lowerLimit=0.0, upperLimit=-1.0, maxForce=0.0, maxVelocity=0.0, linkName='left_tip', axis=(0.0, 0.0, 0.0), parentFramePosition=(0.0, 0.0, 0.0), parentFrameOrientation=(0.0, 0.0, 0.0, 1.0), parentIndex=9)\n",
            "Joint(index=11, name='right_gripper_joint', type=0, gIndex=13, uIndex=12, flags=1, damping=0.0, friction=0.0, lowerLimit=0.0, upperLimit=0.548, maxForce=1000.0, maxVelocity=0.5, linkName='right_gripper', axis=(0.0, 0.0, -1.0), parentFramePosition=(0.2, -0.02, 0.0), parentFrameOrientation=(0.0, 0.0, 0.0, 1.0), parentIndex=8)\n",
            "Joint(index=12, name='right_tip_joint', type=4, gIndex=-1, uIndex=-1, flags=0, damping=0.0, friction=0.0, lowerLimit=0.0, upperLimit=-1.0, maxForce=0.0, maxVelocity=0.0, linkName='right_tip', axis=(0.0, 0.0, 0.0), parentFramePosition=(0.0, 0.0, 0.0), parentFrameOrientation=(0.0, 0.0, 0.0, 1.0), parentIndex=11)\n",
            "Joint(index=13, name='head_swivel', type=0, gIndex=14, uIndex=13, flags=1, damping=0.0, friction=0.0, lowerLimit=-0.38, upperLimit=0.0, maxForce=1000.0, maxVelocity=0.5, linkName='head', axis=(0.0, 0.0, 1.0), parentFramePosition=(0.0, 0.0, 0.3), parentFrameOrientation=(0.0, 0.0, 0.0, 1.0), parentIndex=-1)\n",
            "Joint(index=14, name='tobox', type=4, gIndex=-1, uIndex=-1, flags=0, damping=0.0, friction=0.0, lowerLimit=0.0, upperLimit=-1.0, maxForce=0.0, maxVelocity=0.0, linkName='box', axis=(0.0, 0.0, 0.0), parentFramePosition=(0.0, 0.1214, 0.1214), parentFrameOrientation=(0.0, 0.0, 0.0, 1.0), parentIndex=13)\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "lTxQQmc_Vrue"
      },
      "source": [
        "To start the simulation, first we must set the gravity.\n",
        "We'll use [Earth's gravity](http://www.geophys.ac.cn/infowin/Gravity.asp) for convenience, so we'll set it up to `-9.807` m/s<sup>2</sup>."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "RMZKELbripoh",
        "outputId": "83e73cf7-05d0-48bc-ca81-43ecee066918",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 357
        }
      },
      "source": [
        "# Set the gravity to Earth's gravity.\n",
        "p.setGravity(0, 0, -9.807)\n",
        "\n",
        "# Run the simulation for a fixed amount of steps.\n",
        "for i in range(20):\n",
        "    position, orientation = p.getBasePositionAndOrientation(r2d2)\n",
        "    x, y, z = position\n",
        "    roll, pitch, yaw = p.getEulerFromQuaternion(orientation)\n",
        "    print(f\"{i:3}: x={x:0.10f}, y={y:0.10f}, z={z:0.10f}), roll={roll:0.10f}, pitch={pitch:0.10f}, yaw={yaw:0.10f}\")\n",
        "    p.stepSimulation()"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "  0: x=0.0000000000, y=0.0000000000, z=0.5000000000), roll=0.0000000000, pitch=-0.0000000000, yaw=0.0000000000\n",
            "  1: x=-0.0000000000, y=0.0000000000, z=0.4998297396), roll=0.0000000000, pitch=-0.0000000000, yaw=-0.0000000000\n",
            "  2: x=-0.0000000000, y=0.0000000000, z=0.4994892187), roll=0.0000000000, pitch=-0.0000000000, yaw=-0.0000000000\n",
            "  3: x=-0.0000000000, y=0.0000000000, z=0.4989784375), roll=0.0000000000, pitch=-0.0000000000, yaw=-0.0000000000\n",
            "  4: x=-0.0000000000, y=0.0000000000, z=0.4982973958), roll=0.0000000000, pitch=-0.0000000000, yaw=-0.0000000000\n",
            "  5: x=-0.0000000000, y=0.0000000000, z=0.4974460937), roll=0.0000000000, pitch=-0.0000000000, yaw=-0.0000000000\n",
            "  6: x=-0.0000000000, y=0.0000000000, z=0.4964245312), roll=0.0000000000, pitch=-0.0000000000, yaw=-0.0000000000\n",
            "  7: x=-0.0000000000, y=0.0000000000, z=0.4952327083), roll=0.0000000000, pitch=-0.0000000000, yaw=-0.0000000000\n",
            "  8: x=-0.0000000000, y=0.0000000000, z=0.4938706250), roll=0.0000000000, pitch=-0.0000000000, yaw=-0.0000000000\n",
            "  9: x=-0.0000000000, y=0.0000000000, z=0.4923382813), roll=0.0000000000, pitch=-0.0000000000, yaw=-0.0000000000\n",
            " 10: x=-0.0000000000, y=0.0000000000, z=0.4906356771), roll=0.0000000000, pitch=-0.0000000000, yaw=-0.0000000000\n",
            " 11: x=-0.0000000000, y=0.0000000000, z=0.4887628125), roll=0.0000000000, pitch=-0.0000000000, yaw=-0.0000000000\n",
            " 12: x=-0.0000000000, y=0.0000000000, z=0.4867196875), roll=0.0000000000, pitch=-0.0000000000, yaw=-0.0000000000\n",
            " 13: x=-0.0000000000, y=0.0000000000, z=0.4845063021), roll=0.0000000000, pitch=-0.0000000000, yaw=-0.0000000000\n",
            " 14: x=-0.0000000000, y=0.0000000000, z=0.4821226563), roll=0.0000000000, pitch=-0.0000000000, yaw=-0.0000000000\n",
            " 15: x=-0.0000000000, y=0.0000000000, z=0.4795687500), roll=0.0000000000, pitch=-0.0000000000, yaw=-0.0000000000\n",
            " 16: x=-0.0000000000, y=0.0000000000, z=0.4768445833), roll=0.0000000000, pitch=-0.0000000000, yaw=-0.0000000000\n",
            " 17: x=-0.0000000000, y=0.0000000000, z=0.4739501562), roll=0.0000000000, pitch=-0.0000000000, yaw=-0.0000000000\n",
            " 18: x=-0.0000000000, y=0.0000000000, z=0.4708854687), roll=0.0000000000, pitch=-0.0000000000, yaw=-0.0000000000\n",
            " 19: x=0.0000001305, y=-0.0000077238, z=0.4708941546), roll=0.0000021144, pitch=0.0000002247, yaw=0.0000001176\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "y8fiKPz8-aOp"
      },
      "source": [
        "### Rendering\n",
        "\n",
        "The [`getCameraImage`](https://docs.google.com/document/d/10sXEhzFRSnvFcl3XxNGhnD4N2SedqwdAvK3dsihxVUA/edit?usp=sharing#heading=h.u1jisfnt6984)\n",
        "API will return a RGB image, a depth buffer and a segmentation mask buffer with body unique ids of visible objects for each pixel"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "tHb7uAveipon",
        "outputId": "a24111c3-a1da-4bf3-b3f0-403661114c7d",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 685
        }
      },
      "source": [
        "import numpy as np\n",
        "from PIL import Image\n",
        "from IPython.display import display\n",
        "\n",
        "width = 320\n",
        "height = 200\n",
        "img_arr = p.getCameraImage(\n",
        "    width,\n",
        "    height,\n",
        "    viewMatrix=p.computeViewMatrixFromYawPitchRoll(\n",
        "        cameraTargetPosition=[0, 0, 0],\n",
        "        distance=4,\n",
        "        yaw=60,\n",
        "        pitch=-10,\n",
        "        roll=0,\n",
        "        upAxisIndex=2,\n",
        "    ),\n",
        "    projectionMatrix=p.computeProjectionMatrixFOV(\n",
        "        fov=60,\n",
        "        aspect=width/height,\n",
        "        nearVal=0.01,\n",
        "        farVal=100,\n",
        "    ),\n",
        "    shadow=True,\n",
        "    lightDirection=[1, 1, 1],\n",
        ")\n",
        "\n",
        "width, height, rgba, depth, mask = img_arr\n",
        "print(f\"rgba shape={rgba.shape}, dtype={rgba.dtype}\")\n",
        "display(Image.fromarray(rgba, 'RGBA'))\n",
        "print(f\"depth shape={depth.shape}, dtype={depth.dtype}, as values from 0.0 (near) to 1.0 (far)\")\n",
        "display(Image.fromarray((depth*255).astype('uint8')))\n",
        "print(f\"mask shape={mask.shape}, dtype={mask.dtype}, as unique values from 0 to N-1 entities, and -1 as None\")\n",
        "display(Image.fromarray(np.interp(mask, (-1, mask.max()), (0, 255)).astype('uint8')))"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "image size: 320x200\n",
            "rgba shape=(200, 320, 4) dtype=uint8\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<PIL.Image.Image image mode=RGBA size=320x200 at 0x7FDFE435C3C8>"
            ]
          },
          "metadata": {
            "tags": []
          }
        },
        {
          "output_type": "stream",
          "text": [
            "depth shape=(200, 320) dtype=float32 as values from 0.0 (near) to 1.0 (far)\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "iVBORw0KGgoAAAANSUhEUgAAAUAAAADICAAAAAC8b2d3AAACIUlEQVR4nO3bwWqDQBRAUS35/0+u\nXQQKxYaWXInPcM7CrcPlzcgsXLeF4uPsBVydgJGAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJGAkYCR\ngJGAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJGA\nkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJGA0e3sBfxhW5Z1W5ZlWc9eyQOzA27fj7FGb+HZ6e4mB7xC\nv8kBf/SbegRODngNAkbr1INmv66Zu9gERtcJOHMAxwbc7+Bt5mEz+yayM+9WN3UCfzdwCK81gaNm\n7+5aEziQgNG1tvB/D8EXbvXzbiJnvfjguIcEHPhxfM4TcfcB36bGwR7EXT9fu4y34yscCRgJGAkY\nCRgJGAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJ\nGAkYCRgJGAkYCRgJGN38V9OYwEjASMBIwEjASMBIwEjASMBIwEjASMBIwEjASMBIwEjASMBIwEjA\nSMBIwEjASMBIwEjASMBIwEjASMBIwEjASMBIwEjASMBIwEjASMBIwEjASMBIwEjASMBIwEjAyP/C\nkQmMBIwEjASMBIwEjASMBIwEjASMBIwEjASMBIwEjASMBIwEjASMBIwEjASMBIwEjASMBIwEjASM\nBIwEjASMBIwEjL4AhNEaimX6vcQAAAAASUVORK5CYII=\n",
            "text/plain": [
              "<PIL.Image.Image image mode=L size=320x200 at 0x7FDFE435C358>"
            ]
          },
          "metadata": {
            "tags": []
          }
        },
        {
          "output_type": "stream",
          "text": [
            "mask shape=(200, 320) dtype=int32 as unique values from 0 to N-1 entities, and -1 as None\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "iVBORw0KGgoAAAANSUhEUgAAAUAAAADICAAAAAC8b2d3AAACCElEQVR4nO3Z0UobURRA0Wvxvzv9\n8vRBtC1p1LhT5ly61oMRmcBhc4+ZJGsBAAAAAAAAAAAAAAAAAAAAAAB81tPZA3zgstbTZa25g06d\n68Xl169TB/129gDvuXx8yekmB9yh3+SAf/SbusGTA+5BwGjsalz/A5w5qhMY7RNw5gGcOtZfb2FG\nzvp89gD3mfeubp8VXmvkrfVeJ3DU2Xux1wkcSMBorxVe3z932Y9/O8Xvzgv4yRZfesZ7Vz447kMC\n3t/iRA+Oex1wqxoP9oW4z/9zr7vcCOVVOBIwEjASMBIwEjASMBIwEjASMBIwEjCa+IHqcfYA95h4\nAo87/36qiQFvOo6zJ7i2VcCJBIxGBjzWWuuYuLDXRga86Th7gGsTb2PeXi1eH95+DDQz4GuuDbZ4\nmxWe2vJp+teax9jlfTE+4HTbrPBUAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJG\nAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJGAkYC\nRgJGAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJG\nAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJGAkYCRgJGPwGEfx6iKd+uFgAAAABJ\nRU5ErkJggg==\n",
            "text/plain": [
              "<PIL.Image.Image image mode=L size=320x200 at 0x7FDFE435C2E8>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    }
  ]
}
