{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "HAyy6GyLGXcB" }, "source": [ "# Performing landscape level predictions" ] }, { "cell_type": "markdown", "metadata": { "id": "bZPXVnSG8UZ6" }, "source": [ "Mount drive, install package\n" ] }, { "cell_type": "markdown", "source": [], "metadata": { "id": "vR4HxtPIneU3" } }, { "cell_type": "code", "source": [ "import sys\n", "print(\"Python version\")\n", "print(sys.version)" ], "metadata": { "id": "xoNfSu7hWryz", "outputId": "368b44fc-279a-450e-ce95-9b15b28f2b55", "colab": { "base_uri": "https://localhost:8080/" } }, "execution_count": null, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Python version\n", "3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0]\n" ] } ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "CBxnNgct8T84", "outputId": "2c910ebf-3efe-4776-d2bd-02f0c23083a0" }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Collecting git+https://github.com/PatBall1/detectree2.git\n", " Cloning https://github.com/PatBall1/detectree2.git to /tmp/pip-req-build-vztr3c29\n", " Running command git clone --filter=blob:none --quiet https://github.com/PatBall1/detectree2.git /tmp/pip-req-build-vztr3c29\n", " Resolved https://github.com/PatBall1/detectree2.git to commit 2f29886bafcb63743a7f3ab596c5c3796ca4a243\n", " Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n", "Collecting detectron2@ git+https://github.com/facebookresearch/detectron2.git (from detectree2==1.0.8)\n", " Cloning https://github.com/facebookresearch/detectron2.git to /tmp/pip-install-3kcq93pe/detectron2_814ab9c3956248cf876dae13021793d0\n", " Running command git clone --filter=blob:none --quiet https://github.com/facebookresearch/detectron2.git /tmp/pip-install-3kcq93pe/detectron2_814ab9c3956248cf876dae13021793d0\n", " Resolved https://github.com/facebookresearch/detectron2.git to commit 0df2d73d0013db7de629602c23cc120219b4f2b8\n", " Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n", "Requirement already satisfied: pyyaml>=5.1 in /usr/local/lib/python3.10/dist-packages (from detectree2==1.0.8) (6.0.1)\n", "Requirement already satisfied: GDAL>=1.11 in /usr/local/lib/python3.10/dist-packages (from detectree2==1.0.8) (3.6.4)\n", "Requirement already satisfied: numpy in /usr/local/lib/python3.10/dist-packages (from detectree2==1.0.8) (1.25.2)\n", "Requirement already satisfied: rtree in /usr/local/lib/python3.10/dist-packages (from detectree2==1.0.8) (1.2.0)\n", "Requirement already satisfied: proj in /usr/local/lib/python3.10/dist-packages (from detectree2==1.0.8) (0.2.0)\n", "Requirement already satisfied: geos in /usr/local/lib/python3.10/dist-packages (from detectree2==1.0.8) (0.2.3)\n", "Requirement already satisfied: pypng in /usr/local/lib/python3.10/dist-packages (from detectree2==1.0.8) (0.20220715.0)\n", "Requirement already satisfied: pygeos in /usr/local/lib/python3.10/dist-packages (from detectree2==1.0.8) (0.14)\n", "Requirement already satisfied: shapely in /usr/local/lib/python3.10/dist-packages (from detectree2==1.0.8) (2.0.4)\n", "Requirement already satisfied: geopandas in /usr/local/lib/python3.10/dist-packages (from detectree2==1.0.8) (0.13.2)\n", "Requirement already satisfied: rasterio==1.3a3 in /usr/local/lib/python3.10/dist-packages (from detectree2==1.0.8) (1.3a3)\n", "Requirement already satisfied: fiona in /usr/local/lib/python3.10/dist-packages (from detectree2==1.0.8) (1.9.6)\n", "Requirement already satisfied: pycrs in /usr/local/lib/python3.10/dist-packages (from detectree2==1.0.8) (1.0.2)\n", "Requirement already satisfied: descartes in /usr/local/lib/python3.10/dist-packages (from detectree2==1.0.8) (1.1.0)\n", "Requirement already satisfied: affine in /usr/local/lib/python3.10/dist-packages (from rasterio==1.3a3->detectree2==1.0.8) (2.4.0)\n", "Requirement already satisfied: attrs in /usr/local/lib/python3.10/dist-packages (from rasterio==1.3a3->detectree2==1.0.8) (23.2.0)\n", "Requirement already satisfied: certifi in /usr/local/lib/python3.10/dist-packages (from rasterio==1.3a3->detectree2==1.0.8) (2024.2.2)\n", "Requirement already satisfied: click>=4.0 in /usr/local/lib/python3.10/dist-packages (from rasterio==1.3a3->detectree2==1.0.8) (8.1.7)\n", "Requirement already satisfied: cligj>=0.5 in /usr/local/lib/python3.10/dist-packages (from rasterio==1.3a3->detectree2==1.0.8) (0.7.2)\n", "Requirement already satisfied: snuggs>=1.4.1 in /usr/local/lib/python3.10/dist-packages (from rasterio==1.3a3->detectree2==1.0.8) (1.4.7)\n", "Requirement already satisfied: click-plugins in /usr/local/lib/python3.10/dist-packages (from rasterio==1.3a3->detectree2==1.0.8) (1.1.1)\n", "Requirement already satisfied: setuptools in /usr/local/lib/python3.10/dist-packages (from rasterio==1.3a3->detectree2==1.0.8) (67.7.2)\n", "Requirement already satisfied: matplotlib in /usr/local/lib/python3.10/dist-packages (from descartes->detectree2==1.0.8) (3.7.1)\n", "Requirement already satisfied: Pillow>=7.1 in /usr/local/lib/python3.10/dist-packages (from detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (9.4.0)\n", "Requirement already satisfied: pycocotools>=2.0.2 in /usr/local/lib/python3.10/dist-packages (from detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (2.0.7)\n", "Requirement already satisfied: termcolor>=1.1 in /usr/local/lib/python3.10/dist-packages (from detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (2.4.0)\n", "Requirement already satisfied: yacs>=0.1.8 in /usr/local/lib/python3.10/dist-packages (from detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (0.1.8)\n", "Requirement already satisfied: tabulate in /usr/local/lib/python3.10/dist-packages (from detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (0.9.0)\n", "Requirement already satisfied: cloudpickle in /usr/local/lib/python3.10/dist-packages (from detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (2.2.1)\n", "Requirement already satisfied: tqdm>4.29.0 in /usr/local/lib/python3.10/dist-packages (from detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (4.66.4)\n", "Requirement already satisfied: tensorboard in /usr/local/lib/python3.10/dist-packages (from detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (2.15.2)\n", "Requirement already satisfied: fvcore<0.1.6,>=0.1.5 in /usr/local/lib/python3.10/dist-packages (from detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (0.1.5.post20221221)\n", "Requirement already satisfied: iopath<0.1.10,>=0.1.7 in /usr/local/lib/python3.10/dist-packages (from detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (0.1.9)\n", "Requirement already satisfied: omegaconf<2.4,>=2.1 in /usr/local/lib/python3.10/dist-packages (from detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (2.3.0)\n", "Requirement already satisfied: hydra-core>=1.1 in /usr/local/lib/python3.10/dist-packages (from detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (1.3.2)\n", "Requirement already satisfied: black in /usr/local/lib/python3.10/dist-packages (from detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (24.4.2)\n", "Requirement already satisfied: packaging in /usr/local/lib/python3.10/dist-packages (from detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (24.0)\n", "Requirement already satisfied: six in /usr/local/lib/python3.10/dist-packages (from fiona->detectree2==1.0.8) (1.16.0)\n", "Requirement already satisfied: pandas>=1.1.0 in /usr/local/lib/python3.10/dist-packages (from geopandas->detectree2==1.0.8) (2.0.3)\n", "Requirement already satisfied: pyproj>=3.0.1 in /usr/local/lib/python3.10/dist-packages (from geopandas->detectree2==1.0.8) (3.6.1)\n", "Requirement already satisfied: flask in /usr/local/lib/python3.10/dist-packages (from geos->detectree2==1.0.8) (2.2.5)\n", "Requirement already satisfied: lxml in /usr/local/lib/python3.10/dist-packages (from geos->detectree2==1.0.8) (4.9.4)\n", "Requirement already satisfied: arrow>=0.15.6 in /usr/local/lib/python3.10/dist-packages (from proj->detectree2==1.0.8) (1.3.0)\n", "Requirement already satisfied: python-dateutil>=2.7.0 in /usr/local/lib/python3.10/dist-packages (from arrow>=0.15.6->proj->detectree2==1.0.8) (2.8.2)\n", "Requirement already satisfied: types-python-dateutil>=2.8.10 in /usr/local/lib/python3.10/dist-packages (from arrow>=0.15.6->proj->detectree2==1.0.8) (2.9.0.20240316)\n", "Requirement already satisfied: antlr4-python3-runtime==4.9.* in /usr/local/lib/python3.10/dist-packages (from hydra-core>=1.1->detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (4.9.3)\n", "Requirement already satisfied: portalocker in /usr/local/lib/python3.10/dist-packages (from iopath<0.1.10,>=0.1.7->detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (2.8.2)\n", "Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/dist-packages (from pandas>=1.1.0->geopandas->detectree2==1.0.8) (2023.4)\n", "Requirement already satisfied: tzdata>=2022.1 in /usr/local/lib/python3.10/dist-packages (from pandas>=1.1.0->geopandas->detectree2==1.0.8) (2024.1)\n", "Requirement already satisfied: contourpy>=1.0.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib->descartes->detectree2==1.0.8) (1.2.1)\n", "Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.10/dist-packages (from matplotlib->descartes->detectree2==1.0.8) (0.12.1)\n", "Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.10/dist-packages (from matplotlib->descartes->detectree2==1.0.8) (4.51.0)\n", "Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib->descartes->detectree2==1.0.8) (1.4.5)\n", "Requirement already satisfied: pyparsing>=2.3.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib->descartes->detectree2==1.0.8) (3.1.2)\n", "Requirement already satisfied: mypy-extensions>=0.4.3 in /usr/local/lib/python3.10/dist-packages (from black->detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (1.0.0)\n", "Requirement already satisfied: pathspec>=0.9.0 in /usr/local/lib/python3.10/dist-packages (from black->detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (0.12.1)\n", "Requirement already satisfied: platformdirs>=2 in /usr/local/lib/python3.10/dist-packages (from black->detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (4.2.2)\n", "Requirement already satisfied: tomli>=1.1.0 in /usr/local/lib/python3.10/dist-packages (from black->detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (2.0.1)\n", "Requirement already satisfied: typing-extensions>=4.0.1 in /usr/local/lib/python3.10/dist-packages (from black->detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (4.11.0)\n", "Requirement already satisfied: Werkzeug>=2.2.2 in /usr/local/lib/python3.10/dist-packages (from flask->geos->detectree2==1.0.8) (3.0.3)\n", "Requirement already satisfied: Jinja2>=3.0 in /usr/local/lib/python3.10/dist-packages (from flask->geos->detectree2==1.0.8) (3.1.4)\n", "Requirement already satisfied: itsdangerous>=2.0 in /usr/local/lib/python3.10/dist-packages (from flask->geos->detectree2==1.0.8) (2.2.0)\n", "Requirement already satisfied: absl-py>=0.4 in /usr/local/lib/python3.10/dist-packages (from tensorboard->detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (1.4.0)\n", "Requirement already satisfied: grpcio>=1.48.2 in /usr/local/lib/python3.10/dist-packages (from tensorboard->detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (1.64.0)\n", "Requirement already satisfied: google-auth<3,>=1.6.3 in /usr/local/lib/python3.10/dist-packages (from tensorboard->detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (2.27.0)\n", "Requirement already satisfied: google-auth-oauthlib<2,>=0.5 in /usr/local/lib/python3.10/dist-packages (from tensorboard->detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (1.2.0)\n", "Requirement already satisfied: markdown>=2.6.8 in /usr/local/lib/python3.10/dist-packages (from tensorboard->detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (3.6)\n", "Requirement already satisfied: protobuf!=4.24.0,>=3.19.6 in /usr/local/lib/python3.10/dist-packages (from tensorboard->detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (3.20.3)\n", "Requirement already satisfied: requests<3,>=2.21.0 in /usr/local/lib/python3.10/dist-packages (from tensorboard->detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (2.31.0)\n", "Requirement already satisfied: tensorboard-data-server<0.8.0,>=0.7.0 in /usr/local/lib/python3.10/dist-packages (from tensorboard->detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (0.7.2)\n", "Requirement already satisfied: cachetools<6.0,>=2.0.0 in /usr/local/lib/python3.10/dist-packages (from google-auth<3,>=1.6.3->tensorboard->detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (5.3.3)\n", "Requirement already satisfied: pyasn1-modules>=0.2.1 in /usr/local/lib/python3.10/dist-packages (from google-auth<3,>=1.6.3->tensorboard->detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (0.4.0)\n", "Requirement already satisfied: rsa<5,>=3.1.4 in /usr/local/lib/python3.10/dist-packages (from google-auth<3,>=1.6.3->tensorboard->detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (4.9)\n", "Requirement already satisfied: requests-oauthlib>=0.7.0 in /usr/local/lib/python3.10/dist-packages (from google-auth-oauthlib<2,>=0.5->tensorboard->detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (1.3.1)\n", "Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/lib/python3.10/dist-packages (from Jinja2>=3.0->flask->geos->detectree2==1.0.8) (2.1.5)\n", "Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2.21.0->tensorboard->detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (3.3.2)\n", "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2.21.0->tensorboard->detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (3.7)\n", "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2.21.0->tensorboard->detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (2.0.7)\n", "Requirement already satisfied: pyasn1<0.7.0,>=0.4.6 in /usr/local/lib/python3.10/dist-packages (from pyasn1-modules>=0.2.1->google-auth<3,>=1.6.3->tensorboard->detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (0.6.0)\n", "Requirement already satisfied: oauthlib>=3.0.0 in /usr/local/lib/python3.10/dist-packages (from requests-oauthlib>=0.7.0->google-auth-oauthlib<2,>=0.5->tensorboard->detectron2@ git+https://github.com/facebookresearch/detectron2.git->detectree2==1.0.8) (3.2.2)\n" ] } ], "source": [ "from google.colab import drive\n", "# drive.mount('/content/drive')\n", "!pip install git+https://github.com/PatBall1/detectree2.git" ] }, { "cell_type": "markdown", "metadata": { "id": "cZfxTuOxnXKQ" }, "source": [ "## Tiling\n", "Tile up the entire orthomosaic to make predictions" ] }, { "cell_type": "markdown", "metadata": { "id": "hvKTOryJQR0v" }, "source": [ "## Create full site predictions\n", "\n", "### Access pre-trained model" ] }, { "cell_type": "markdown", "source": [ "Download pre-trained model" ], "metadata": { "id": "4CnWRxJB9eA3" } }, { "cell_type": "markdown", "source": [ "There might be a cleaner way to do it with `pkg_resources` but I haven't figured this out yet" ], "metadata": { "id": "cpHMH39aELgb" } }, { "cell_type": "markdown", "metadata": { "id": "JeT66YPmreRv" }, "source": [ "Combine predictions into full output" ] }, { "cell_type": "code", "source": [ "import cv2\n", "from PIL import Image\n", "import os\n", "import numpy as np\n", "import urllib.request\n", "import glob\n", "\n", "# intake library and plugin\n", "# import intake\n", "# from intake_zenodo_fetcher import download_zenodo_files_for_entry\n", "\n", "# geospatial libraries\n", "import geopandas as gpd\n", "\n", "from rasterio.transform import from_origin\n", "import rasterio.features\n", "\n", "import fiona\n", "\n", "from shapely.geometry import shape, mapping, box\n", "from shapely.geometry.multipolygon import MultiPolygon\n", "\n", "# machine learning libraries\n", "from detectron2 import model_zoo\n", "from detectron2.engine import DefaultPredictor\n", "from detectron2.utils.visualizer import Visualizer, ColorMode\n", "from detectron2.config import get_cfg\n", "from detectron2.engine import DefaultTrainer\n", "\n", "# visualisation\n", "import holoviews as hv\n", "from IPython.display import display\n", "# import geoviews.tile_sources as gts\n", "\n", "# import hvplot.pandas\n", "# import hvplot.xarray\n", "\n", "# hv.extension('bokeh', width=100)" ], "metadata": { "id": "lftCpCayrPR5" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "%matplotlib inline" ], "metadata": { "id": "fpHuk_s3uAXz" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "filepath = '/content/DJI_20240504221329_0168_D.JPG'\n", "im = cv2.imread(filepath)\n", "display(Image.fromarray(im))" ], "metadata": { "id": "g0YQ1U2trbI5", "colab": { "base_uri": "https://localhost:8080/", "height": 297 }, "outputId": "c766edda-6deb-4eae-e5bf-8c55104316f1" }, "execution_count": null, "outputs": [ { "output_type": "error", "ename": "AttributeError", "evalue": "'NoneType' object has no attribute '__array_interface__'", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mfilepath\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'/content/DJI_20240504221329_0168_D.JPG'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mim\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcv2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mimread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfilepath\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mdisplay\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mImage\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfromarray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mim\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/PIL/Image.py\u001b[0m in \u001b[0;36mfromarray\u001b[0;34m(obj, mode)\u001b[0m\n\u001b[1;32m 3067\u001b[0m \u001b[0;34m.\u001b[0m\u001b[0;34m.\u001b[0m \u001b[0mversionadded\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m1.1\u001b[0m\u001b[0;36m.6\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3068\u001b[0m \"\"\"\n\u001b[0;32m-> 3069\u001b[0;31m \u001b[0marr\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mobj\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__array_interface__\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3070\u001b[0m \u001b[0mshape\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0marr\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"shape\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3071\u001b[0m \u001b[0mndim\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mAttributeError\u001b[0m: 'NoneType' object has no attribute '__array_interface__'" ] } ] }, { "cell_type": "code", "source": [ "import matplotlib.pyplot as plt\n" ], "metadata": { "id": "D8YtfLmluG3e" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "plt.imshow(im)" ], "metadata": { "id": "fqHOtxxvuDnl" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "# Define the project main folder\n", "data_folder = './forest-modelling-detectree'\n", "\n", "# Set the folder structure\n", "config = {\n", " 'in_geotiff': os.path.join(data_folder, 'input','tiff'),\n", " 'in_png': os.path.join(data_folder, 'input','png'),\n", " 'model': os.path.join(data_folder, 'model'),\n", " 'out_geotiff': os.path.join(data_folder, 'output','raster'),\n", " 'out_shapefile': os.path.join(data_folder, 'output','vector'),\n", "}\n", "\n", "# List comprehension for the folder structure code\n", "[os.makedirs(val) for key, val in config.items() if not os.path.exists(val)]" ], "metadata": { "id": "_cPnLA53sNWi" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "# define the URL to retrieve the model\n", "fn = 'model_final.pth'\n", "url = f'https://zenodo.org/record/5515408/files/{fn}?download=1'\n", "\n", "urllib.request.urlretrieve(url, config['model'] + '/' + fn)" ], "metadata": { "id": "SazYGXJWr6rW" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [], "metadata": { "id": "Yu6ixAMoObsv" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "cfg = get_cfg()\n", "\n", "# if you want to make predictions using a CPU, run the following line. If using GPU, hash it out.\n", "cfg.MODEL.DEVICE='cuda'\n", "\n", "# model and hyperparameter selection\n", "cfg.merge_from_file(model_zoo.get_config_file(\"COCO-InstanceSegmentation/mask_rcnn_R_101_FPN_3x.yaml\"))\n", "cfg.DATALOADER.NUM_WORKERS = 2\n", "cfg.SOLVER.IMS_PER_BATCH = 2\n", "cfg.MODEL.ROI_HEADS.NUM_CLASSES = 1\n", "\n", "### path to the saved pre-trained model weights\n", "cfg.MODEL.WEIGHTS = config['model'] + '/model_final.pth'\n", "\n", "# set confidence threshold at which we predict\n", "cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.15\n", "\n", "#### Settings for predictions using detectron config\n", "\n", "predictor = DefaultPredictor(cfg)" ], "metadata": { "id": "ibJGEKdmsZmq" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "outputs = predictor(im)\n", "v = Visualizer(im[:, :, ::-1], scale=1.5, instance_mode=ColorMode.IMAGE_BW) # remove the colors of unsegmented pixels\n", "v = v.draw_instance_predictions(outputs[\"instances\"].to(\"cpu\"))\n", "image = cv2.cvtColor(v.get_image()[:, :, :], cv2.COLOR_BGR2RGB)\n", "display(Image.fromarray(image))" ], "metadata": { "id": "zH-Okks_sVBF" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "\n", "plt.imshow(image)" ], "metadata": { "id": "ZH3jAypEsqdG" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "mask_array = outputs['instances'].pred_masks.cpu().numpy()\n", "\n", "# get confidence scores too\n", "mask_array_scores = outputs['instances'].scores.cpu().numpy()" ], "metadata": { "id": "ewUypuTCSYSL" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "\n", "num_instances = mask_array.shape[0]\n", "mask_array_instance = []\n", "output = np.zeros_like(mask_array)\n", "\n", "mask_array_instance.append(mask_array)\n", "output = np.where(mask_array_instance[0] == True, 255, output)\n", "fresh_output = output.astype(np.float)\n", "x_scaling = 140/fresh_output.shape[1]\n", "y_scaling = 140/fresh_output.shape[2]\n", "# this is an affine transform. This needs to be altered significantly.\n", "transform = from_origin(int(filepath[-17:-11])-20, int(filepath[-10:-4])+120, y_scaling, x_scaling)" ], "metadata": { "id": "i_25LDd9ShHj" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "mask_array = outputs['instances'].pred_masks.numpy()\n", "\n", "# get confidence scores too\n", "mask_array_scores = outputs['instances'].scores.numpy()\n", "\n", "num_instances = mask_array.shape[0]\n", "mask_array_instance = []\n", "output = np.zeros_like(mask_array)\n", "\n", "mask_array_instance.append(mask_array)\n", "output = np.where(mask_array_instance[0] == True, 255, output)\n", "fresh_output = output.astype(np.float)\n", "x_scaling = 140/fresh_output.shape[1]\n", "y_scaling = 140/fresh_output.shape[2]\n", "# this is an affine transform. This needs to be altered significantly.\n", "transform = from_origin(int(filepath[-17:-11])-20, int(filepath[-10:-4])+120, y_scaling, x_scaling)\n", "\n", "output_raster = config['out_geotiff'] + '/' + 'predicted_rasters_' + filepath[-17:-4]+ '.tif'\n", "\n", "new_dataset = rasterio.open(output_raster, 'w', driver='GTiff',\n", " height = fresh_output.shape[1], width = fresh_output.shape[2], count = fresh_output.shape[0],\n", " dtype=str(fresh_output.dtype),\n", " crs='+proj=utm +zone=50 +datum=WGS84 +units=m +no_defs',\n", " transform=transform)\n", "\n", "new_dataset.write(fresh_output)\n", "new_dataset.close()" ], "metadata": { "id": "juM3wDRLvZ4m" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "print(outputs)" ], "metadata": { "id": "u0hdjykMSNX8" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "mask_array = outputs['instances'].pred_masks.cpu.numpy()\n", "\n", "# get confidence scores too\n", "mask_array_scores = outputs['instances'].scores.cpu.numpy()\n", "\n", "num_instances = mask_array.shape[0]\n", "mask_array_instance = []\n", "output = np.zeros_like(mask_array)\n", "\n", "mask_array_instance.append(mask_array)\n", "output = np.where(mask_array_instance[0] == True, 255, output)\n", "fresh_output = output.astype(np.float)" ], "metadata": { "id": "Jg0r8IgQD_W8" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "# # Read input band with Rasterio\n", "\n", "# with rasterio.open(output_raster) as src:\n", "# shp_schema = {'geometry': 'MultiPolygon','properties': {'pixelvalue': 'int', 'score': 'float'}}\n", "\n", "# crs = src.crs\n", "# for i in range(src.count):\n", "# src_band = src.read(i+1)\n", "# src_band = np.float32(src_band)\n", "# conf = mask_array_scores[i]\n", "# # Keep track of unique pixel values in the input band\n", "# unique_values = np.unique(src_band)\n", "# # Polygonize with Rasterio. `shapes()` returns an iterable\n", "# # of (geom, value) as tuples\n", "# shapes = list(rasterio.features.shapes(src_band, transform=src.transform))\n", "\n", "# if i == 0:\n", "# with fiona.open(config['out_shapefile'] + '/predicted_polygons_' + filepath[-17:-4] + '_' + str(0) + '.shp', 'w', 'ESRI Shapefile',\n", "# shp_schema) as shp:\n", "# polygons = [shape(geom) for geom, value in shapes if value == 255.0]\n", "# multipolygon = MultiPolygon(polygons)\n", "# # simplify not needed here\n", "# #multipolygon = multipolygon_a.simplify(0.1, preserve_topology=False)\n", "# shp.write({\n", "# 'geometry': mapping(multipolygon),\n", "# 'properties': {'pixelvalue': int(unique_values[1]), 'score': float(conf)}\n", "# })\n", "# else:\n", "# with fiona.open(config['out_shapefile'] + '/predicted_polygons_' + filepath[-17:-4] + '_' + str(0)+'.shp', 'a', 'ESRI Shapefile',\n", "# shp_schema) as shp:\n", "# polygons = [shape(geom) for geom, value in shapes if value == 255.0]\n", "# multipolygon = MultiPolygon(polygons)\n", "# # simplify not needed here\n", "# #multipolygon = multipolygon_a.simplify(0.1, preserve_topology=False)\n", "# shp.write({\n", "# 'geometry': mapping(multipolygon),\n", "# 'properties': {'pixelvalue': int(unique_values[1]), 'score': float(conf)}\n", "# })" ], "metadata": { "id": "-Enr0Hg7vbtr" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "# load and plot polygons\n", "in_shp = glob.glob(config['out_shapefile'] + '/*.shp')\n", "\n", "poly_df = gpd.read_file(in_shp[0])\n", "\n", "plot_vector = poly_df.hvplot(hover_cols=['score'], legend=False).opts(fill_color=None,line_color=None,alpha=0.5, width=800, height=600)\n", "\n", "plot_vector" ], "metadata": { "id": "DWve5Kc8vI5s" }, "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "KW3j29mJGjO5" }, "source": [ "Remove invalid geometries before cleaning. Might be a way to fix them rather than remove all together but I think the ones with invalid geometries tend to be bad crowns anyway." ] }, { "cell_type": "markdown", "metadata": { "id": "zF0qy7vpGmem" }, "source": [ "Clean overlapping crowns. For significant overlaps, the most confident crown is selected. IoU can be varied based on how strict you want the filtering to be." ] } ], "metadata": { "accelerator": "GPU", "colab": { "provenance": [], "gpuType": "T4" }, "kernelspec": { "display_name": "Python 3", "name": "python3" }, "language_info": { "name": "python" } }, "nbformat": 4, "nbformat_minor": 0 }