Computer_Vision/Chapter18/building_a_panoramic_view_of_images.ipynb

365 lines
1.8 MiB
Plaintext
Raw Normal View History

2024-02-13 03:34:51 +01:00
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"kernelspec": {
"name": "python3",
"display_name": "Python 3",
"language": "python"
},
"colab": {
"name": "building-a-panoramic-view-of-images.ipynb",
"provenance": [],
"include_colab_link": true
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/github/PacktPublishing/Hands-On-Computer-Vision-with-PyTorch/blob/master/Chapter18/building_a_panoramic_view_of_images.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "code",
"metadata": {
"_uuid": "8f2839f25d086af736a60e9eeb907d3b93b6e0e5",
"_cell_guid": "b1076dfc-b9ad-4769-8c92-a6c4dae69d19",
"trusted": true,
"id": "h-U2So3mvjXY",
"outputId": "c529bb58-ec02-4fd7-c616-09ee422357e3",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 625
}
},
"source": [
"!pip install torch_snippets\n",
"from torch_snippets import *\n",
"# feature_extractor = 'orb' \n",
"# feature_matching = 'bf'"
],
"execution_count": 1,
"outputs": [
{
"output_type": "stream",
"text": [
"Collecting torch_snippets\n",
" Downloading https://files.pythonhosted.org/packages/d6/56/1093531de48ccc64410a480def65c386d18c981cfac21e7e3f92c9496352/torch_snippets-0.228-py3-none-any.whl\n",
"Collecting loguru\n",
"\u001b[?25l Downloading https://files.pythonhosted.org/packages/6d/48/0a7d5847e3de329f1d0134baf707b689700b53bd3066a5a8cfd94b3c9fc8/loguru-0.5.3-py3-none-any.whl (57kB)\n",
"\u001b[K |████████████████████████████████| 61kB 2.8MB/s \n",
"\u001b[?25hRequirement already satisfied: Pillow in /usr/local/lib/python3.6/dist-packages (from torch_snippets) (7.0.0)\n",
"Requirement already satisfied: matplotlib in /usr/local/lib/python3.6/dist-packages (from torch_snippets) (3.2.2)\n",
"Collecting opencv-python-headless\n",
"\u001b[?25l Downloading https://files.pythonhosted.org/packages/e2/e2/6670da2b12544858657058a5db2f088a18c56d0144bef8d178ad4734b7a3/opencv_python_headless-4.4.0.44-cp36-cp36m-manylinux2014_x86_64.whl (36.7MB)\n",
"\u001b[K |████████████████████████████████| 36.7MB 1.3MB/s \n",
"\u001b[?25hRequirement already satisfied: tqdm in /usr/local/lib/python3.6/dist-packages (from torch_snippets) (4.41.1)\n",
"Requirement already satisfied: dill in /usr/local/lib/python3.6/dist-packages (from torch_snippets) (0.3.2)\n",
"Requirement already satisfied: pandas in /usr/local/lib/python3.6/dist-packages (from torch_snippets) (1.1.2)\n",
"Requirement already satisfied: numpy in /usr/local/lib/python3.6/dist-packages (from torch_snippets) (1.18.5)\n",
"Collecting aiocontextvars>=0.2.0; python_version < \"3.7\"\n",
" Downloading https://files.pythonhosted.org/packages/db/c1/7a723e8d988de0a2e623927396e54b6831b68cb80dce468c945b849a9385/aiocontextvars-0.2.2-py2.py3-none-any.whl\n",
"Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.6/dist-packages (from matplotlib->torch_snippets) (1.2.0)\n",
"Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.6/dist-packages (from matplotlib->torch_snippets) (0.10.0)\n",
"Requirement already satisfied: python-dateutil>=2.1 in /usr/local/lib/python3.6/dist-packages (from matplotlib->torch_snippets) (2.8.1)\n",
"Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /usr/local/lib/python3.6/dist-packages (from matplotlib->torch_snippets) (2.4.7)\n",
"Requirement already satisfied: pytz>=2017.2 in /usr/local/lib/python3.6/dist-packages (from pandas->torch_snippets) (2018.9)\n",
"Collecting contextvars==2.4; python_version < \"3.7\"\n",
" Downloading https://files.pythonhosted.org/packages/83/96/55b82d9f13763be9d672622e1b8106c85acb83edd7cc2fa5bc67cd9877e9/contextvars-2.4.tar.gz\n",
"Requirement already satisfied: six in /usr/local/lib/python3.6/dist-packages (from cycler>=0.10->matplotlib->torch_snippets) (1.15.0)\n",
"Collecting immutables>=0.9\n",
"\u001b[?25l Downloading https://files.pythonhosted.org/packages/99/e0/ea6fd4697120327d26773b5a84853f897a68e33d3f9376b00a8ff96e4f63/immutables-0.14-cp36-cp36m-manylinux1_x86_64.whl (98kB)\n",
"\u001b[K |████████████████████████████████| 102kB 10.4MB/s \n",
"\u001b[?25hBuilding wheels for collected packages: contextvars\n",
" Building wheel for contextvars (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
" Created wheel for contextvars: filename=contextvars-2.4-cp36-none-any.whl size=7666 sha256=f8a165c3ac2b22ad80f61738b271ef93036c96cd11af1335186f06598bb97516\n",
" Stored in directory: /root/.cache/pip/wheels/a5/7d/68/1ebae2668bda2228686e3c1cf16f2c2384cea6e9334ad5f6de\n",
"Successfully built contextvars\n",
"Installing collected packages: immutables, contextvars, aiocontextvars, loguru, opencv-python-headless, torch-snippets\n",
"Successfully installed aiocontextvars-0.2.2 contextvars-2.4 immutables-0.14 loguru-0.5.3 opencv-python-headless-4.4.0.44 torch-snippets-0.228\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"_uuid": "8f2839f25d086af736a60e9eeb907d3b93b6e0e5",
"_cell_guid": "b1076dfc-b9ad-4769-8c92-a6c4dae69d19",
"trusted": true,
"id": "HnNYEe9mvjXb",
"outputId": "eae81cce-c495-49c2-c528-a5d05ef20e46",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 728
}
},
"source": [
"!wget https://www.dropbox.com/s/mfg1codtc2rue84/g1.png\n",
"!wget https://www.dropbox.com/s/4yhui8s1xjndavm/g2.png"
],
"execution_count": 2,
"outputs": [
{
"output_type": "stream",
"text": [
"--2020-10-05 17:11:49-- https://www.dropbox.com/s/mfg1codtc2rue84/g1.png\n",
"Resolving www.dropbox.com (www.dropbox.com)... 162.125.5.1, 2620:100:601d:1::a27d:501\n",
"Connecting to www.dropbox.com (www.dropbox.com)|162.125.5.1|:443... connected.\n",
"HTTP request sent, awaiting response... 301 Moved Permanently\n",
"Location: /s/raw/mfg1codtc2rue84/g1.png [following]\n",
"--2020-10-05 17:11:49-- https://www.dropbox.com/s/raw/mfg1codtc2rue84/g1.png\n",
"Reusing existing connection to www.dropbox.com:443.\n",
"HTTP request sent, awaiting response... 302 Found\n",
"Location: https://uc5ae3b5e6d89a5d1f941a070eb5.dl.dropboxusercontent.com/cd/0/inline/BAtSVe1XsaaYz-dNUT8PucSdjy59J17P0-IX4lxNRncoz7CpXaFnCeJ_3ClhJ_xqjSaE8G_HWaraS8s184p7sjLBHHXf1_83whtDGgIVRo2edKrdQAlEKy5qjMY03HJmeZU/file# [following]\n",
"--2020-10-05 17:11:49-- https://uc5ae3b5e6d89a5d1f941a070eb5.dl.dropboxusercontent.com/cd/0/inline/BAtSVe1XsaaYz-dNUT8PucSdjy59J17P0-IX4lxNRncoz7CpXaFnCeJ_3ClhJ_xqjSaE8G_HWaraS8s184p7sjLBHHXf1_83whtDGgIVRo2edKrdQAlEKy5qjMY03HJmeZU/file\n",
"Resolving uc5ae3b5e6d89a5d1f941a070eb5.dl.dropboxusercontent.com (uc5ae3b5e6d89a5d1f941a070eb5.dl.dropboxusercontent.com)... 162.125.9.15, 2620:100:601d:15::a27d:50f\n",
"Connecting to uc5ae3b5e6d89a5d1f941a070eb5.dl.dropboxusercontent.com (uc5ae3b5e6d89a5d1f941a070eb5.dl.dropboxusercontent.com)|162.125.9.15|:443... connected.\n",
"HTTP request sent, awaiting response... 200 OK\n",
"Length: 277132 (271K) [image/png]\n",
"Saving to: g1.png\n",
"\n",
"g1.png 100%[===================>] 270.64K --.-KB/s in 0.07s \n",
"\n",
"2020-10-05 17:11:50 (3.86 MB/s) - g1.png saved [277132/277132]\n",
"\n",
"--2020-10-05 17:11:50-- https://www.dropbox.com/s/4yhui8s1xjndavm/g2.png\n",
"Resolving www.dropbox.com (www.dropbox.com)... 162.125.5.1, 2620:100:601f:1::a27d:901\n",
"Connecting to www.dropbox.com (www.dropbox.com)|162.125.5.1|:443... connected.\n",
"HTTP request sent, awaiting response... 301 Moved Permanently\n",
"Location: /s/raw/4yhui8s1xjndavm/g2.png [following]\n",
"--2020-10-05 17:11:50-- https://www.dropbox.com/s/raw/4yhui8s1xjndavm/g2.png\n",
"Reusing existing connection to www.dropbox.com:443.\n",
"HTTP request sent, awaiting response... 302 Found\n",
"Location: https://uc65628330652e93bcd853321184.dl.dropboxusercontent.com/cd/0/inline/BAuCQY7ifx2KBi0o8py2GUxyM83OvafOWPQ3dMQXD9Wn7FYLst90ueZBfgamB3FAxGpwSXkZM1pS-gztpoq7icc8Vg16vSaBkCymRK-48aZJj3-VwhY7sZMuNVXn4EyIcpA/file# [following]\n",
"--2020-10-05 17:11:51-- https://uc65628330652e93bcd853321184.dl.dropboxusercontent.com/cd/0/inline/BAuCQY7ifx2KBi0o8py2GUxyM83OvafOWPQ3dMQXD9Wn7FYLst90ueZBfgamB3FAxGpwSXkZM1pS-gztpoq7icc8Vg16vSaBkCymRK-48aZJj3-VwhY7sZMuNVXn4EyIcpA/file\n",
"Resolving uc65628330652e93bcd853321184.dl.dropboxusercontent.com (uc65628330652e93bcd853321184.dl.dropboxusercontent.com)... 162.125.9.15, 2620:100:601d:15::a27d:50f\n",
"Connecting to uc65628330652e93bcd853321184.dl.dropboxusercontent.com (uc65628330652e93bcd853321184.dl.dropboxusercontent.com)|162.125.9.15|:443... connected.\n",
"HTTP request sent, awaiting response... 200 OK\n",
"Length: 330008 (322K) [image/png]\n",
"Saving to: g2.png\n",
"\n",
"g2.png 100%[===================>] 322.27K --.-KB/s in 0.07s \n",
"\n",
"2020-10-05 17:11:53 (4.47 MB/s) - g2.png saved [330008/330008]\n",
"\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"_uuid": "d629ff2d2480ee46fbb7e2d37f6b5fab8052498a",
"_cell_guid": "79c7e3d0-c299-4dcb-8224-4455121ee9b0",
"trusted": true,
"id": "D1oKuroRvjXe",
"outputId": "36d8b4fe-0028-4b23-bff4-9161289eaf62",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 211
}
},
"source": [
"queryImg = read('g1.png', 1)\n",
"queryImg_gray = read('g1.png')\n",
"\n",
"trainImg = read('g2.png', 1)\n",
"trainImg_gray = read('g2.png')\n",
"\n",
"\n",
"subplots([trainImg, queryImg], nc=2, figsize=(10,5), titles = ['Query image','Training image (Image to be stitched to Query image)'])"
],
"execution_count": 3,
"outputs": [
{
"output_type": "stream",
"text": [
"2020-10-05 17:11:53.215 | INFO | torch_snippets.loader:subplots:339 - plotting 2 images in a grid of 1x2 @ (10, 5)\n"
],
"name": "stderr"
},
{
"output_type": "display_data",
"data": {
"image/png": "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
"text/plain": [
"<Figure size 720x360 with 2 Axes>"
]
},
"metadata": {
"tags": [],
"needs_background": "light"
}
}
]
},
{
"cell_type": "code",
"metadata": {
"trusted": true,
"id": "Rg0WWkqJvjXg",
"outputId": "a44bee5e-708e-496d-c148-24082e094af9",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 227
}
},
"source": [
"# Fetch the keypoints and features corresponding to the images\n",
"descriptor = cv2.ORB_create()\n",
"kpsA, featuresA = descriptor.detectAndCompute(trainImg_gray, None)\n",
"kpsB, featuresB = descriptor.detectAndCompute(queryImg_gray, None)\n",
"\n",
"# Draw the keypoints obtained on images\n",
"img_kpsA = cv2.drawKeypoints(trainImg_gray,kpsA,None,color=(0,255,0))\n",
"img_kpsB = cv2.drawKeypoints(queryImg_gray,kpsB,None,color=(0,255,0))\n",
"subplots([img_kpsB, img_kpsA], nc=2, figsize=(10,5), titles=['Query image with keypoints','Training image with keypoints'])"
],
"execution_count": 4,
"outputs": [
{
"output_type": "stream",
"text": [
"2020-10-05 17:11:53.638 | INFO | torch_snippets.loader:subplots:339 - plotting 2 images in a grid of 1x2 @ (10, 5)\n"
],
"name": "stderr"
},
{
"output_type": "display_data",
"data": {
"image/png": "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
"text/plain": [
"<Figure size 720x360 with 2 Axes>"
]
},
"metadata": {
"tags": [],
"needs_background": "light"
}
}
]
},
{
"cell_type": "code",
"metadata": {
"trusted": true,
"id": "KPrCD8JNvjXj"
},
"source": [
"bf = cv2.BFMatcher(cv2.NORM_HAMMING)\n",
"best_matches = bf.match(featuresA,featuresB)\n",
"matches = sorted(best_matches, key = lambda x:x.distance)"
],
"execution_count": 5,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"trusted": true,
"id": "yWuBz2BFvjXl",
"outputId": "d1cedcf0-bcaa-43cc-c89b-d79a0ca4450e",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 280
}
},
"source": [
"img3 = cv2.drawMatches(trainImg,kpsA,queryImg,kpsB,matches[:100], None,flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)\n",
"show(img3)"
],
"execution_count": 6,
"outputs": [
{
"output_type": "display_data",
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1440x1440 with 1 Axes>"
]
},
"metadata": {
"tags": [],
"needs_background": "light"
}
}
]
},
{
"cell_type": "code",
"metadata": {
"trusted": true,
"id": "2HQFribjvjXn"
},
"source": [
"kpsA = np.float32([kp.pt for kp in kpsA])\n",
"kpsB = np.float32([kp.pt for kp in kpsB])\n",
"ptsA = np.float32([kpsA[m.queryIdx] for m in matches])\n",
"ptsB = np.float32([kpsB[m.trainIdx] for m in matches])\n",
"\n",
"(H, status) = cv2.findHomography(ptsA, ptsB, cv2.RANSAC,4)"
],
"execution_count": 7,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"trusted": true,
"id": "U2Ly0WjVvjXq",
"outputId": "82c35d79-5426-4bd1-ea96-9156200532bf",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 372
}
},
"source": [
"width = trainImg.shape[1] + queryImg.shape[1]\n",
"height = trainImg.shape[0] + queryImg.shape[0]\n",
"\n",
"result = cv2.warpPerspective(trainImg, H, (width, height))\n",
"result[0:queryImg.shape[0], 0:queryImg.shape[1]] = queryImg\n",
"\n",
"_x = np.nonzero(result.sum(0).sum(-1) == 0)[0][0]\n",
"_y = np.nonzero(result.sum(1).sum(-1) == 0)[0][0]\n",
"\n",
"show(result[:_y,:_x])"
],
"execution_count": 8,
"outputs": [
{
"output_type": "display_data",
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAABGoAAAFjCAYAAABlgO1pAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nOy92bIkOW4oCHjEOSe3alUvpVZLuj+gV/3RfZyn+c6xMZuXsbExm5FkGrtSX3V3ZWXldpYId84DN6wk3cNPZpYU6K48EQgSBEEQAEE6HUMIcIUrXOEKV7jCFa5whStc4QpXuMIVrnCFrw/T12bgCle4whWucIUrXOEKV7jCFa5whStc4QoRromaK1zhCle4whWucIUrXOEKV7jCFa5whW8EromaK1zhCle4whWucIUrXOEKV7jCFa5whW8EromaK1zhCle4whWucIUrXOEKV7jCFa5whW8EromaK1zhCle4whWucIUrXOEKV7jCFa5whW8EromaK1zhCle4whWucIUrXOEKV7jCFa5whW8Ejq0f//v/8r8GoK/vRgREhAAJFyIOAMF6zXcpBxDrsTIIiMBwiBjrBVkvUQsZN4nvwOuFSF/yQAoqXG0z9YfyvobW4OvOeSm737lU7SeXIRq0TJwr11BK13pdak1asakGZ0HKNShZSIys1xpHcPtoyCG0WYWQPiIAghwzjeuNR9EwtFkfU1U1JSEETtuul3CJ6akgK5Or+jg4HM8CLdq9AfForRlIilvb3kpoksc0h4KYtVnPExbT/3o2TeKi7m+YVwQ3MBtYfyutheBAAW0z8+3xZU+sipqk/8h1B+yLWS/zhW2+xnByvhNaODaOLRxvL2K38mrGANkvTGjWY+XKOKeJZRk14gtNHnI52qmNvkPT17YXcdpFXjKGqbprWWUJsUyp0ZyPsh4I+lQWwYiPOH0ZjVDMBJPAwCY7FPvm6O9GvR+hpePTvK/pW+V5XuBP//HH9Hkm1q3jEL0hxlpzCYs5dy6CALDM82BhyxBrFO/3SjAqLstix4QAttx6ol4WCEtHjnJx0WhkCQGWMCrDAQgAy7z0y62AeTnvSg8gjsvSk+MaCAGWZY9+1/h+HqBnqpAz7PN83jW+W5ZldMk4BCEsEJYF+CTQswfJvyadQm+vMamUx+3NGMw7zBUqn2WZd7WzYQmwkHj29PQE739+B7OQQwjBHZBmoqYEPvoX8scJKEgQyegJglYA4QUVHJ2/GwEE4dFMBlhtAq2rec9Yhd60ItXUA1j9zoE+bU6UCcHjVPEn65ZkEBs2LgdBrUPL5ULR9zAhYwgyBvHmaq2Ls/ky2GuQygtWNCbvUK9R4zd2x8YNqiWL/Z26Y6M4zutu0KFdAu2RDowGdyM4r8xOdr7NQnsZoOzv0Hx0bF9OOpSv43Z7DMfr00Q1rSOb6Noh5qPscsU7aOIWk4Qbp80RvoZx0u859TaO7Xa+7D7KAIfJuRH8SFrBMmoJ15P9mnEklO24gCX7EBAtndwurwoyQdMCf041YwXXiFry4XhPzqwHoe/fbUwLFzgfm22ahlIOxXdaZqVNOxwm+OGv/xoApL7744oAA4maPLdaOwUWjuqvwUvISWUwYvMBSqhxNsaYbx6IH5uLpkA/5sjfsh2CXjdP05uP3H/snUD71uklorsmGeSmxFYaAFWXvX6XWbIyZl0nx7qa9HB8TssZZvgHtj6TOF+v2eEKyPPW73xN1JR/yK8tm9LCxe80aVFsm+gLXbPXiCsQb0DksJMSFiplA8JO5FMe3A2AnHPBtKFBWHz7lz/B//G//2/w+dPHYd6aiRqAaKiQCbL+E4VEA4TqJHiXdDJlzOHkOhWnd3bkKRMEQO7cbfrABxi1gijeUzkrGK27nNakpLSQfOe/VraCDlyV05ftiT56yQ0FyanJk1PB3cO4DDrzGaHqeGXH6UfuY2/H1NTBfpCDktlSz+pAj1bq10peJa4Gl1gMCkKVUVD0bVpIhWzFdlsHvxcnIjd6tdgozg05U/m2BIuZ8nbWzWhV47yTbYWfSTv1zF+/P9oBNGVTkgeGwxsYW3ZK0qCfA18aIrjEGI7rahOQ/UmfNC1KisUaLVNr9afBA6VlljT645/mkQ30NMDCrQmM+vRHT/g0/ZxDn592DczWtk/Ycpwtd6N7sWIZjxGP5/EgYxgA6kapUq0Z216bSTZNM4SAU982eQm8LbYW01PxQ6dby6KW40pO6yJbOwHAwstsooUah2jMNF82TLpu3AFwc3MLbfBjv3bJDeCajmRPW2Z5MHw00Qpvz4X9QJ6w3067lWzmsCf/zwt7xPK/lN6uSqZ0O7W111t9es+/2r6a4tz4JreYTq+2yrVs4siJxFGcPsWtabfr8e+bAIU8G3wzuXgxzEJ6o1xTgMM0wfHYTb0waJaesF5hU5wV3fVM0bsMKjJD9bMX2LS+27+5O1UsuNZLCk2/RGAVE3Jdihf1sMEDWAkVjwe7v1FqdGGUg0W26tDZjPpDZsik74La0Xwew4zqA/9xVbuZ56Fdr5EyGofDdVtlyMrS290NTMub7dGAWHFh7UxbtFC0YnSnu7ZeE78w9UXTsLZwNFAesRRNFvi2syjkjI9Hy8OhHaxagbGtcRK7Tl6MMPX10rzB4HiUZFB/MQpGPZXADroob1cX2Drd0ZFpq645TtT3DZ6i0A1ss0PjOKE3aNe75BRQ2y5EBYtVdSKxR78Lhl1C1JOtF6xjsp164yhPEJp8yN978h/rny3X9ncw+igLep7rkpN0FBfyv4hcGt6ElP5pi61FAPMqxY12m8vL9u7jdtUe3/GFvqy4oY4BQ/Yxt9cVY4ePQTZb/dknX6NPHm4BFWs32nN/uYAPK9+4F+yRrPklwNCivWXSN4COisYmIX3aJfsanf/lPsbTCbk2j3slYnMkU8PKpb7uQm7kenFrp4zAlfZJAh8h2ku6AU1DB9avJq3UZyY8gcPKs0rEODkERoucklG8SVrsOyeE03qla6d1FK+G8x2tvBGGk6NUGt7uGovJRGAHIa+XXc5HWBkx8po7ms3TDLCukYL2bshlcuc7oTtDaHOXZS834lS5oYHYQwMdPdpEpUNnBb9ezNUr20ohmnVHg7BLJTTQkHrs7Dn0cxS6z68DWIngWAdM+9OGHfrKfeoFbewTELeIrNkRHSo1ol+ezXUn1nohfEWNrSD53nBs2FvM5YU8AsZECE4QnzIYfzSg5Xd6046dyBkZn2YZvXy3fxlcFFxYaKuNDRv9oKwTAv+lS3PFHG7Dfqspc+m0iXRDR9EJ3gf1ZNgK7+ESBvzAkK+4dKp9NcsoI7PQNI96dxzdXfVtpyc02LZ2g80Gdi5tM6VvwodZQAfnkkBa0lpBam18nZsawcnWtI5JbuK//DoQD2f4Omm/c1LFaCmQMpoV7S1V+06yQ8lU4JCQD6xMpu/HAt5jrs3nSFboFYK9oRVCgMN0XL2+7t5Rk4lnDvSxoHy8J/j1jCRKlbBKH6osIKVlP/PeUJDuOXlRDRCCKqfrtU/QWHzxaWGf9llPq19vhJb1PZh9HBkPtx4CwOKPN93dbNnJEdXJzUlcr56Ju1D0NKvbkpd+BIoTU+Ws5OTAmFm4VeMocOOqiragR4A5YtvIKr5MMna/V8nL4ZvLECAvWuMnSmsyefBxuR7/PoqzzC8fNNR9FH2Kux5e18cmQ6Uly4Iqw363UCOdHNQTGfSgocBj9h7UeFu0dh3ItbTKVxIsbaFFxxCxBFHLMsPpfIbzOV5eeTgc4ObmBoCuQnv0HeAmwJ7vXrKmlcDJp2gDLAJHx3EQjLijb2uRVLPsPSjcsO1Yo3MN/cKECwYPFl9QFhOX+hg7FllLy4wppWwsWZjyoijBF8gj+jvDBQTNxcFAnGU1vGEta7VwKYGd27f82Gjdkd+99ghG2YEROmNg3Tj6LCPQi+tY34YVsN0kAISVi9/daMmDATvx4YE65Wjabz7fEVIM18FVW8pj1EwfQdtbC+fZabN90T/qY1rt9fuHjf7ZfFlrtfUvC4jxRLSRur0thyD6lwkXZ
"text/plain": [
"<Figure size 1440x1440 with 1 Axes>"
]
},
"metadata": {
"tags": [],
"needs_background": "light"
}
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "nNFkhfnLvzNg"
},
"source": [
""
],
"execution_count": null,
"outputs": []
}
]
}