From df5d3de9bd294781e9290352993a0774def771f2 Mon Sep 17 00:00:00 2001 From: lmoehlenbrock <120418910+lmoehlenbrock@users.noreply.github.com> Date: Thu, 2 Feb 2023 11:02:21 -0600 Subject: [PATCH 1/3] Add files via upload --- .../geospatial_predictions.ipynb | 1563 +++++++++++++++++ 1 file changed, 1563 insertions(+) create mode 100644 examples/prediction_upload/geospatial_predictions.ipynb diff --git a/examples/prediction_upload/geospatial_predictions.ipynb b/examples/prediction_upload/geospatial_predictions.ipynb new file mode 100644 index 000000000..1cf2017d2 --- /dev/null +++ b/examples/prediction_upload/geospatial_predictions.ipynb @@ -0,0 +1,1563 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "provenance": [], + "collapsed_sections": [ + "RgBYFUxa-VGT", + "6FZyvnrqSGuc", + "viFHCnBeTD1Y", + "T-ZHWWI3JgmX" + ] + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "a6a048e8-b5fe-418b-aec4-829b5b6802e5" + }, + "source": [ + "\n", + " \n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "51cf1362-1cde-4749-aac7-5fb94473baa7" + }, + "source": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "" + ] + }, + { + "cell_type": "markdown", + "source": [ + "# Geospatial Prediction Import \n", + "* This notebook walks you through the process of uploading model predictions to a Model Run. This notebook provides an example for each supported prediction type for tiled imagery assets.\n", + "\n", + "A Model Run is a container for the predictions, annotations and metrics of a specific experiment in your ML model development cycle.\n", + "\n", + "**Supported annotations that can be uploaded through the SDK**\n", + "- Bounding box\n", + "- Point\n", + "- Polygons \n", + "- Polyline\n", + "- Free form text classifications\n", + "- Classification - radio\n", + "- Classification - checklist\n", + "\n", + "**NOT** supported:\n", + "- Segmentation masks\n", + "\n", + "\n", + "Please note that this list of unsupported annotations only refers to limitations for importing annotations. For example, when using the Labelbox editor, segmentation masks can be created and edited on video assets.\n" + ], + "metadata": { + "id": "9znxMjDYGi0Y" + } + }, + { + "cell_type": "markdown", + "source": [ + "## Setup" + ], + "metadata": { + "id": "UtJHIuE8HDRI" + } + }, + { + "cell_type": "code", + "source": [ + "!pip install -q 'labelbox[data]'" + ], + "metadata": { + "id": "cm8xMaLbGb7v", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "213df0ab-7b5c-4915-e814-688f17646de6" + }, + "execution_count": 2, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\u001b[?25l \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m0.0/185.5 KB\u001b[0m \u001b[31m?\u001b[0m eta \u001b[36m-:--:--\u001b[0m\r\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m185.5/185.5 KB\u001b[0m \u001b[31m14.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25h Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m7.8/7.8 MB\u001b[0m \u001b[31m60.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25h Building wheel for pygeotile (setup.py) ... \u001b[?25l\u001b[?25hdone\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "import os\n", + "\n", + "import uuid\n", + "import numpy as np\n", + "from PIL import Image\n", + "import cv2\n", + "import ndjson\n", + "import gdal\n", + "\n", + "import labelbox as lb\n", + "import labelbox.data.annotation_types as lb_types\n", + "import labelbox.schema.queue_mode as lb_queue_mode\n", + "\n", + "from labelbox.data.serialization.ndjson.converter import NDJsonConverter\n", + "from labelbox.data.annotation_types.data.tiled_image import TiledBounds, TiledImageData, TileLayer, EPSG, EPSGTransformer" + ], + "metadata": { + "id": "NIq-6M9kHKSs" + }, + "execution_count": 26, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "## Replace with your API Key \n", + "Guides on [Create an API key](https://docs.labelbox.com/docs/create-an-api-key)" + ], + "metadata": { + "id": "pZ2rBqY8HQoe" + } + }, + { + "cell_type": "code", + "source": [ + "API_KEY = \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJjbGJwZ3hmYWVod3c2MDc2dGVkbzVland4Iiwib3JnYW5pemF0aW9uSWQiOiJjbGJvNTl6YTUwbDR5MDd6cWMyaHAxdGFkIiwiYXBpS2V5SWQiOiJjbGJwaDB2cHo2bGFrMDd3dGh0ZnJhbXd3Iiwic2VjcmV0IjoiOGNiMzkwMDcxMDVmMjBhZjcyZDgzMDIzMjAyMWMyN2QiLCJpYXQiOjE2NzExMzIzMDAsImV4cCI6MjMwMjI4NDMwMH0.P6a_kLqFiciEvpvFk0biqBbbIQsDFF-uw7CYtles9hQ\"\n", + "client = lb.Client(API_KEY)" + ], + "metadata": { + "id": "z7ZLKLYLHP__" + }, + "execution_count": 4, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "## Supported Predictions\n", + "- Each cell shows the python annotation and the NDJson annotation for each annotation type." + ], + "metadata": { + "id": "RgBYFUxa-VGT" + } + }, + { + "cell_type": "code", + "source": [ + "####### Point #######\n", + "\n", + "# Python Annotation\n", + "point_prediction = lb_types.ObjectAnnotation(\n", + " name = \"point_geo\",\n", + " confidence = 0.5,\n", + " value = lb_types.Point(x=-122.31741025134123, y=37.87355669249922),\n", + ")\n", + "\n", + "# NDJSON\n", + "point_prediction_ndjson = {\n", + " \"name\": \"point_geo\",\n", + " \"confidence\": 0.5,\n", + " \"point\": {\n", + " \"x\": -122.31741025134123,\n", + " \"y\": 37.87355669249922\n", + " }\n", + "}" + ], + "metadata": { + "id": "3mQh-yQ2TLmd" + }, + "execution_count": 21, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "####### Polyline #######\n", + "# Coordinates\n", + "coords = [ \n", + " [\n", + " -122.31757789012927,\n", + " 37.87396317833991\n", + " ],\n", + " [\n", + " -122.31639782443663,\n", + " 37.87396741226917\n", + " ],\n", + " [\n", + " -122.31638977853417,\n", + " 37.87277872707839\n", + " ]\n", + " ]\n", + "\n", + "line_points = []\n", + "line_points_ndjson = []\n", + "\n", + "for sub in coords: \n", + " line_points.append(lb_types.Point(x=sub[0], y=sub[1]))\n", + " line_points_ndjson.append({\"x\":sub[0], \"y\":sub[1]})\n", + "\n", + "# Python Annotation \n", + "polyline_prediction = lb_types.ObjectAnnotation(\n", + " name = \"polyline_geo\",\n", + " confidence = 0.5,\n", + " value = lb_types.Line(points=line_points),\n", + ")\n", + "\n", + "\n", + "# NDJSON \n", + "polyline_prediction_ndjson = {\n", + " \"name\": \"polyline_geo\",\n", + " \"confidence\": 0.5,\n", + " \"line\": line_points_ndjson\n", + "}" + ], + "metadata": { + "id": "f3OoBByTTYda" + }, + "execution_count": 5, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "####### Polygon #######\n", + "# Coordinates in the desired EPSG coordinate system\n", + "coords_polygon = [\n", + " [\n", + " -122.31691812612837,\n", + " 37.873289980495024\n", + " ],\n", + " [\n", + " -122.31710184090099,\n", + " 37.87304335144298\n", + " ],\n", + " [\n", + " -122.31680146054286,\n", + " 37.87303594197371\n", + " ],\n", + " [\n", + " -122.31691812612837,\n", + " 37.873289980495024\n", + " ]\n", + "]\n", + "\n", + "polygon_points = []\n", + "polygon_points_ndjson = []\n", + "\n", + "for sub in coords_polygon: \n", + " polygon_points.append(lb_types.Point(x=sub[0], y=sub[1]))\n", + " polygon_points_ndjson.append({\"x\":sub[0], \"y\":sub[1]})\n", + "\n", + "# Python Annotation \n", + "polygon_prediction = lb_types.ObjectAnnotation(\n", + " name = \"polygon_geo\",\n", + " confidence = 0.5,\n", + " value = lb_types.Polygon(points=polygon_points),\n", + ")\n", + "\n", + "# NDJSON \n", + "polygon_prediction_ndjson = {\n", + " \"name\": \"polygon_geo\",\n", + " \"confidence\": 0.5,\n", + " \"polygon\": polygon_points_ndjson\n", + "}" + ], + "metadata": { + "id": "BSjRhlFvTdfS" + }, + "execution_count": 6, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "####### Bounding Box #######\n", + "coord_object = {\n", + " \"coordinates\": [\n", + " [\n", + " [\n", + " -122.31734455895823,\n", + " 37.873713376083884\n", + " ],\n", + " [\n", + " -122.31734455895823,\n", + " 37.87385944699745\n", + " ],\n", + " [\n", + " -122.31673038840458,\n", + " 37.87385944699745\n", + " ],\n", + " [\n", + " -122.31673038840458,\n", + " 37.873713376083884\n", + " ],\n", + " [\n", + " -122.31734455895823,\n", + " 37.873713376083884\n", + " ]\n", + " ]\n", + " ] \n", + " }\n", + "\n", + "\n", + "bbox_top_left = lb_types.Point(x=-122.31734455895823, y=37.873713376083884)\n", + "bbox_bottom_right = lb_types.Point(x=-122.31673038840458, y=37.87385944699745)\n", + "\n", + "# Python Annotation\n", + "bbox_prediction = lb_types.ObjectAnnotation(\n", + " name = \"bbox_geo\",\n", + " confidence = 0.5,\n", + " value = lb_types.Rectangle(start=bbox_top_left, end=bbox_bottom_right)\n", + ")\n", + "\n", + "\n", + "# NDJSON\n", + "bbox_prediction_ndjson = {\n", + " \"name\" : \"bbox_geo\",\n", + " \"confidence\": 0.5,\n", + " \"bbox\" : {\n", + " 'top': coord_object[\"coordinates\"][0][1][1],\n", + " 'left': coord_object[\"coordinates\"][0][1][0],\n", + " 'height': coord_object[\"coordinates\"][0][3][1] - coord_object[\"coordinates\"][0][1][1], \n", + " 'width': coord_object[\"coordinates\"][0][3][0] - coord_object[\"coordinates\"][0][1][0]\n", + " }\n", + "}\n" + ], + "metadata": { + "id": "oLX3adDOTmYS" + }, + "execution_count": 7, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "####### Classification - radio (single choice) #######\n", + "\n", + "# Python Annotation \n", + "radio_prediction = lb_types.ClassificationAnnotation(\n", + " name=\"radio_question_geo\", \n", + " confidence = 0.5,\n", + " value=lb_types.Radio(answer=lb_types.ClassificationAnswer(name=\"first_radio_answer\"))\n", + ")\n", + "\n", + "# NDJSON \n", + "radio_prediction_ndjson = {\n", + " \"name\": \"radio_question_geo\",\n", + " \"confidence\": 0.5,\n", + " \"answer\": { \"name\": \"first_radio_answer\"}\n", + "}" + ], + "metadata": { + "id": "OsWf8Y_mTxLm" + }, + "execution_count": 8, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "####### Classification - Checklist (multi-choice) #######\n", + "\n", + "coord_object_checklist = {\n", + " \"coordinates\": [\n", + " [\n", + " [\n", + " -122.31711256877092,\n", + " 37.87340218056304\n", + " ],\n", + " [\n", + " -122.31711256877092,\n", + " 37.87360752741479\n", + " ],\n", + " [\n", + " -122.31665529331502,\n", + " 37.87360752741479\n", + " ],\n", + " [\n", + " -122.31665529331502,\n", + " 37.87340218056304\n", + " ],\n", + " [\n", + " -122.31711256877092,\n", + " 37.87340218056304\n", + " ]\n", + " ]\n", + " ] \n", + "}\n", + "\n", + "# Python Annotation\n", + "bbox_with_checklist_subclass = lb_types.ObjectAnnotation(\n", + " name=\"bbox_checklist_geo\",\n", + " confidence = 0.5,\n", + " value=lb_types.Rectangle(\n", + " start=lb_types.Point(x=-122.31711256877092, y=37.87340218056304), # Top left\n", + " end=lb_types.Point(x=-122.31665529331502, y=37.87360752741479), # Bottom right\n", + " ),\n", + " classifications=[\n", + " lb_types.ClassificationAnnotation(\n", + " name=\"checklist_class_name\",\n", + " value=lb_types.Checklist(\n", + " answer=[lb_types.ClassificationAnswer(name=\"first_checklist_answer\", confidence = 0.5)]\n", + " )\n", + " )\n", + " ]\n", + ")\n", + "\n", + "\n", + "# NDJSON \n", + "bbox_with_checklist_subclass_ndjson = {\n", + " \"name\": \"bbox_checklist_geo\", \n", + " \"confidence\": 0.5,\n", + " \"classifications\": [{\n", + " \"name\": \"checklist_class_name\",\n", + " \"answer\": [\n", + " { \"name\":\"first_checklist_answer\", \"confidence\": 0.5 }\n", + " ] \n", + " }],\n", + " \"bbox\": {\n", + " 'top': coord_object_checklist[\"coordinates\"][0][1][1],\n", + " 'left': coord_object_checklist[\"coordinates\"][0][1][0],\n", + " 'height': coord_object_checklist[\"coordinates\"][0][3][1] - coord_object_checklist[\"coordinates\"][0][1][1], \n", + " 'width': coord_object_checklist[\"coordinates\"][0][3][0] - coord_object_checklist[\"coordinates\"][0][1][0]\n", + " }\n", + "}" + ], + "metadata": { + "id": "2IZXIWP2UcOJ" + }, + "execution_count": 9, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "####### Classification free form text with bbox #######\n", + "\n", + "coord_object_text ={\n", + " \"coordinates\": [\n", + " [\n", + " [\n", + " -122.31750814315438,\n", + " 37.87318201423049\n", + " ],\n", + " [\n", + " -122.31750814315438,\n", + " 37.87337992476082\n", + " ],\n", + " [\n", + " -122.31710049991725,\n", + " 37.87337992476082\n", + " ],\n", + " [\n", + " -122.31710049991725,\n", + " 37.87318201423049\n", + " ],\n", + " [\n", + " -122.31750814315438,\n", + " 37.87318201423049\n", + " ]\n", + " ]\n", + " ]\n", + "}\n", + "# Python Annotation\n", + "bbox_with_free_text_subclass = lb_types.ObjectAnnotation(\n", + " name=\"bbox_text_geo\",\n", + " value=lb_types.Rectangle(\n", + " start=lb_types.Point(x=-122.31750814315438, y=37.87318201423049), # Top left\n", + " end=lb_types.Point(x=-122.31710049991725, y=37.87337992476082), # Bottom right\n", + " ),\n", + " classifications=[\n", + " lb_types.ClassificationAnnotation(\n", + " name=\"free_text_geo\",\n", + " value=lb_types.Text(answer=\"sample text\")\n", + " )\n", + " ]\n", + ")\n", + "\n", + "# NDJSON \n", + "bbox_with_free_text_subclass_ndjson = {\n", + " \"name\":\"bbox_text_geo\",\n", + " \"classifications\": [{\n", + " \"name\": \"free_text_geo\",\n", + " \"answer\": \"sample text\"\n", + " }],\n", + " \"bbox\": {\n", + " 'top': coord_object_text[\"coordinates\"][0][1][1],\n", + " 'left': coord_object_text[\"coordinates\"][0][1][0],\n", + " 'height': coord_object_text[\"coordinates\"][0][3][1] - coord_object_text[\"coordinates\"][0][1][1], \n", + " 'width': coord_object_text[\"coordinates\"][0][3][0] - coord_object_text[\"coordinates\"][0][1][0]\n", + " }\n", + "}" + ], + "metadata": { + "id": "bnjcIB7FU21R" + }, + "execution_count": 10, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "####### Classification - Checklist (multi-choice) #######\n", + "\n", + "# Python Annotation\n", + "checklist_prediction = lb_types.ClassificationAnnotation(\n", + " name=\"checklist_question_geo\",\n", + " confidence = 0.5,\n", + " value=lb_types.Checklist(answer = [\n", + " lb_types.ClassificationAnswer(name = \"first_checklist_answer\", confidence = 0.5),\n", + " lb_types.ClassificationAnswer(name = \"second_checklist_answer\", confidence = 0.5),\n", + " lb_types.ClassificationAnswer(name = \"third_checklist_answer\", confidence = 0.5)\n", + " ])\n", + " )\n", + "\n", + "\n", + "# NDJSON\n", + "checklist_prediction_ndjson = {\n", + " 'name': 'checklist_question_geo',\n", + " \"confidence\": 0.5,\n", + " 'answer': [\n", + " {'name': 'first_checklist_answer', \"confidence\": 0.5},\n", + " {'name': 'second_checklist_answer', \"confidence\": 0.5},\n", + " {'name': 'third_checklist_answer', \"confidence\": 0.5},\n", + " ]\n", + "}" + ], + "metadata": { + "id": "hIkLI1q7glMi" + }, + "execution_count": 11, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "## Step 1: Import data rows into Catalog" + ], + "metadata": { + "id": "U-o15yu9IPDo" + } + }, + { + "cell_type": "code", + "source": [ + "top_left_bound = lb_types.Point(x=-122.31764674186705, y=37.87276155898985)\n", + "bottom_right_bound = lb_types.Point(x=-122.31635199317932, y=37.87398109727749)\n", + "\n", + "epsg = EPSG.EPSG4326\n", + "bounds = TiledBounds(epsg=epsg, bounds=[top_left_bound, bottom_right_bound])\n", + "\n", + "tile_layer = TileLayer(\n", + " url=\"https://api.mapbox.com/styles/v1/mapbox/satellite-streets-v11/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw\"\n", + ")\n", + "\n", + "tiled_image_data = TiledImageData(tile_layer=tile_layer,\n", + " tile_bounds=bounds,\n", + " zoom_levels=[17, 23])\n", + "\n", + "asset = {\n", + " \"row_data\": tiled_image_data.asdict(),\n", + " \"global_key\": str(uuid.uuid4()),\n", + " \"media_type\": \"TMS_GEO\"\n", + "}\n", + "\n", + "dataset = client.create_dataset(name=\"geo_demo_dataset\")\n", + "data_row = dataset.create_data_row(asset)\n", + "print(data_row)" + ], + "metadata": { + "id": "HjH9gTV8IBG9", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "29abe6b9-b699-4f47-8dc1-0702df392fee" + }, + "execution_count": 14, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "## Step 2: Create/select an Ontology for your model predictions\n", + "Your project should have the correct ontology setup with all the tools and classifications supported for your annotations, and the tool names and classification instructions should match the name/instructions fields in your annotations to ensure the correct feature schemas are matched.\n" + ], + "metadata": { + "id": "oy0umzuNIceP" + } + }, + { + "cell_type": "code", + "source": [ + "ontology_builder = lb.OntologyBuilder(\n", + " tools=[\n", + " lb.Tool(tool=lb.Tool.Type.POINT, name=\"point_geo\"),\n", + " lb.Tool(tool=lb.Tool.Type.LINE, name=\"polyline_geo\"),\n", + " lb.Tool(tool=lb.Tool.Type.POLYGON, name=\"polygon_geo\"),\n", + " lb.Tool(tool=lb.Tool.Type.POLYGON, name=\"polygon_geo_2\"),\n", + " lb.Tool(tool=lb.Tool.Type.BBOX, name=\"bbox_geo\"), \n", + " lb.Tool( \n", + " tool=lb.Tool.Type.BBOX, \n", + " name=\"bbox_checklist_geo\",\n", + " classifications=[\n", + " lb.Classification(\n", + " class_type=lb.Classification.Type.CHECKLIST,\n", + " instructions=\"checklist_class_name\",\n", + " options=[\n", + " lb.Option(value=\"first_checklist_answer\")\n", + " ]\n", + " ),\n", + " ]\n", + " ),\n", + " lb.Tool( \n", + " tool=lb.Tool.Type.BBOX, \n", + " name=\"bbox_text_geo\",\n", + " classifications=[\n", + " lb.Classification(\n", + " class_type=lb.Classification.Type.TEXT,\n", + " instructions=\"free_text_geo\"\n", + " ),\n", + " ]\n", + " ) \n", + " ],\n", + " classifications = [\n", + " lb.Classification(\n", + " class_type=lb.Classification.Type.CHECKLIST, \n", + " instructions=\"checklist_question_geo\",\n", + " options=[\n", + " lb.Option(value=\"first_checklist_answer\"),\n", + " lb.Option(value=\"second_checklist_answer\"), \n", + " lb.Option(value=\"third_checklist_answer\")\n", + " ]\n", + " ), \n", + " lb.Classification(\n", + " class_type=lb.Classification.Type.RADIO, \n", + " instructions=\"radio_question_geo\",\n", + " options=[\n", + " lb.Option(value=\"first_radio_answer\")\n", + " ]\n", + " )\n", + " \n", + " ]\n", + ")\n", + "\n", + "ontology = client.create_ontology(\"Ontology Geospatial Annotations\", ontology_builder.asdict())" + ], + "metadata": { + "id": "Kt4XWWqgIiWk" + }, + "execution_count": 16, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "## Step 3: Create a Model and Model Run" + ], + "metadata": { + "id": "ZjN8jxHvIvHP" + } + }, + { + "cell_type": "code", + "source": [ + "# create Model\n", + "model = client.create_model(name=\"geospatial_model_run_\" + str(uuid.uuid4()), \n", + " ontology_id=ontology.uid)\n", + "# create Model Run\n", + "model_run = model.create_model_run(\"iteration 1\")" + ], + "metadata": { + "id": "8n-AvzdiOR6d" + }, + "execution_count": 17, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "## Step 4: Send data rows to the Model Run" + ], + "metadata": { + "id": "NX6L0axRJN5J" + } + }, + { + "cell_type": "code", + "source": [ + "model_run.upsert_data_rows([data_row.uid])" + ], + "metadata": { + "id": "6sngCgIwJSae", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "6a1f9ed0-9f77-4ceb-f463-fa9e4b34f6ba" + }, + "execution_count": 18, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "True" + ] + }, + "metadata": {}, + "execution_count": 18 + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "## Step 5. Create the predictions payload\n", + "\n", + "Create the annotations payload using the snippets in the **Supported Predictions Section**. \n", + "\n", + "The resulting label_ndjson should have exactly the same content for annotations that are supported by both (with exception of the uuid strings that are generated)" + ], + "metadata": { + "id": "6FZyvnrqSGuc" + } + }, + { + "cell_type": "code", + "source": [ + " ## Lets create another polygon annotation with python annotation tools that draws the image using cv2 and PIL python libraries\n", + "\n", + "from PIL import Image\n", + "import cv2\n", + "\n", + "hsv = cv2.cvtColor(tiled_image_data.value, cv2.COLOR_RGB2HSV)\n", + "mask = cv2.inRange(hsv, (10, 25, 25), (100, 150, 255))\n", + "kernel = np.ones((15, 20), np.uint8)\n", + "mask = cv2.erode(mask, kernel)\n", + "mask = cv2.dilate(mask, kernel)\n", + "mask_annotation = lb_types.MaskData.from_2D_arr(mask)\n", + "mask_data = lb_types.Mask(mask=mask_annotation, color=[255, 255, 255])\n", + "h, w, _ = tiled_image_data.value.shape\n", + "pixel_bounds = TiledBounds(epsg=EPSG.SIMPLEPIXEL,\n", + " bounds=[lb_types.Point(x=0, y=0),\n", + " lb_types.Point(x=w, y=h)])\n", + "transformer = EPSGTransformer.create_pixel_to_geo_transformer(\n", + " src_epsg=pixel_bounds.epsg,\n", + " pixel_bounds=pixel_bounds,\n", + " geo_bounds=tiled_image_data.tile_bounds,\n", + " zoom=23)\n", + "pixel_polygons = mask_data.shapely.simplify(3)\n", + "list_of_polygons = [transformer(lb_types.Polygon.from_shapely(p)) for p in pixel_polygons.geoms]\n", + "polygon_prediction_two = lb_types.ObjectAnnotation(value=list_of_polygons[0], name=\"polygon_geo_2\", confidence=0.5)\n", + "\n", + "\n", + "# Here is the NDJSON representation of the resulting polygon:\n", + "polygon_prediction_two_ndjson = {\n", + " \"name\": \"polygon_geo\",\n", + " \"confidence\": 0.5,\n", + " \"polygon\": [\n", + " {'x': -122.31703039689702, 'y': 37.87397804081582},\n", + " {'x': -122.31702351036107, 'y': 37.87393525033866},\n", + " {'x': -122.31698907768116, 'y': 37.87389857276706},\n", + " {'x': -122.3169787478772, 'y': 37.87385883871054},\n", + " {'x': -122.31695808826926, 'y': 37.87385578224377},\n", + " {'x': -122.31695464500127, 'y': 37.873816048164166},\n", + " {'x': -122.31692021232138, 'y': 37.873779370533214},\n", + " {'x': -122.31690988251741, 'y': 37.87373352346883},\n", + " {'x': -122.3168857796415, 'y': 37.873696845796786},\n", + " {'x': -122.3168547902296, 'y': 37.873684619902065},\n", + " {'x': -122.31682035754969, 'y': 37.873611264491025},\n", + " {'x': -122.31676526526188, 'y': 37.87355013492598},\n", + " {'x': -122.3167583787259, 'y': 37.87351651364362},\n", + " {'x': -122.31671017297403, 'y': 37.87348900531027},\n", + " {'x': -122.31671017297403, 'y': 37.873452327516496},\n", + " {'x': -122.31667918356217, 'y': 37.87344010158117},\n", + " {'x': -122.31663442107829, 'y': 37.87335451997715},\n", + " {'x': -122.31660343166638, 'y': 37.87334840700161},\n", + " {'x': -122.31659998839841, 'y': 37.873320898605485},\n", + " {'x': -122.31654489611057, 'y': 37.87329033370888},\n", + " {'x': -122.31652767977064, 'y': 37.87319863894286},\n", + " {'x': -122.31648980382273, 'y': 37.8731833564708},\n", + " {'x': -122.31648980382273, 'y': 37.873161961004534},\n", + " {'x': -122.31641749519497, 'y': 37.87309166157168},\n", + " {'x': -122.316410608659, 'y': 37.873054983580076},\n", + " {'x': -122.31639683558704, 'y': 37.873039701078184},\n", + " {'x': -122.31635551637117, 'y': 37.873039701078184},\n", + " {'x': -122.31635551637117, 'y': 37.87398109727749},\n", + " {'x': -122.31703039689702, 'y': 37.87397804081582}\n", + " ]\n", + "}" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "dr1dEPzM_tHW", + "outputId": "e367b87f-f8cb-4f2f-f74e-5df5aaf60efa" + }, + "execution_count": 34, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "WARNING:labelbox.data.annotation_types.data.tiled_image:Unexpected tile size (512, 512, 3).\n", + "WARNING:labelbox.data.annotation_types.data.tiled_image:Unexpected tile size (512, 512, 3).\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "\n", + "tiled_image_data_row_id = next(dataset.export_data_rows()).uid\n", + "\n", + "label = lb_types.Label(\n", + " data=TiledImageData(\n", + " uid=tiled_image_data_row_id ,\n", + " tile_layer=tile_layer,\n", + " tile_bounds=bounds,\n", + " zoom_levels=[17, 23]\n", + " ),\n", + " annotations = [\n", + " point_prediction,\n", + " polyline_prediction,\n", + " polygon_prediction,\n", + " bbox_prediction,\n", + " radio_prediction,\n", + " bbox_with_checklist_subclass, \n", + " bbox_with_free_text_subclass,\n", + " checklist_prediction,\n", + " polygon_prediction_two\n", + " ]\n", + ")\n", + "# Convert our label from a Labelbox class object to the underlying NDJSON format required for upload \n", + "label_ndjson = list(NDJsonConverter.serialize([label]))\n", + "label_ndjson" + ], + "metadata": { + "id": "F-Y7sSyAV3tn", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "a3da2fa9-3611-436d-91f2-b26dbffb133d" + }, + "execution_count": 24, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[{'confidence': 0.5,\n", + " 'uuid': '9fcc2949-4636-43de-8574-12088b71b480',\n", + " 'dataRow': {'id': 'cldnb9fqj02rz07284krw8s8e'},\n", + " 'name': 'point_geo',\n", + " 'classifications': [],\n", + " 'point': {'x': -122.31741025134123, 'y': 37.87355669249922}},\n", + " {'confidence': 0.5,\n", + " 'uuid': 'ddf8a5c9-c01e-4236-840a-c2c699b5b51f',\n", + " 'dataRow': {'id': 'cldnb9fqj02rz07284krw8s8e'},\n", + " 'name': 'polyline_geo',\n", + " 'classifications': [],\n", + " 'line': [{'x': -122.31757789012927, 'y': 37.87396317833991},\n", + " {'x': -122.31639782443663, 'y': 37.87396741226917},\n", + " {'x': -122.31638977853417, 'y': 37.87277872707839}]},\n", + " {'confidence': 0.5,\n", + " 'uuid': 'b0a101bd-e376-4c27-87cd-24460ae32c13',\n", + " 'dataRow': {'id': 'cldnb9fqj02rz07284krw8s8e'},\n", + " 'name': 'polygon_geo',\n", + " 'classifications': [],\n", + " 'polygon': [{'x': -122.31691812612837, 'y': 37.873289980495024},\n", + " {'x': -122.31710184090099, 'y': 37.87304335144298},\n", + " {'x': -122.31680146054286, 'y': 37.87303594197371},\n", + " {'x': -122.31691812612837, 'y': 37.873289980495024}]},\n", + " {'confidence': 0.5,\n", + " 'uuid': '5f79cb0d-b48b-4f2f-9532-72db6805fa1e',\n", + " 'dataRow': {'id': 'cldnb9fqj02rz07284krw8s8e'},\n", + " 'name': 'bbox_geo',\n", + " 'classifications': [],\n", + " 'bbox': {'top': 37.873713376083884,\n", + " 'left': -122.31734455895823,\n", + " 'height': 0.0001460709135656657,\n", + " 'width': 0.0006141705536464315}},\n", + " {'name': 'radio_question_geo',\n", + " 'answer': {'name': 'first_radio_answer'},\n", + " 'uuid': '912917fa-5c99-4c3b-981e-1825155ff8db',\n", + " 'dataRow': {'id': 'cldnb9fqj02rz07284krw8s8e'}},\n", + " {'confidence': 0.5,\n", + " 'uuid': '553377cb-9347-45ca-b8b9-c6ddcd145a0a',\n", + " 'dataRow': {'id': 'cldnb9fqj02rz07284krw8s8e'},\n", + " 'name': 'bbox_checklist_geo',\n", + " 'classifications': [{'name': 'checklist_class_name',\n", + " 'answer': [{'confidence': 0.5, 'name': 'first_checklist_answer'}]}],\n", + " 'bbox': {'top': 37.87340218056304,\n", + " 'left': -122.31711256877092,\n", + " 'height': 0.00020534685175022105,\n", + " 'width': 0.0004572754559006853}},\n", + " {'uuid': '67f9337f-61dd-4488-bbc2-fb45b6a85cff',\n", + " 'dataRow': {'id': 'cldnb9fqj02rz07284krw8s8e'},\n", + " 'name': 'bbox_text_geo',\n", + " 'classifications': [{'name': 'free_text_geo', 'answer': 'sample text'}],\n", + " 'bbox': {'top': 37.87318201423049,\n", + " 'left': -122.31750814315438,\n", + " 'height': 0.00019791053033202388,\n", + " 'width': 0.00040764323713915473}},\n", + " {'name': 'checklist_question_geo',\n", + " 'uuid': 'dfab5e8a-a290-4809-a87d-9b4288ddb7cd',\n", + " 'dataRow': {'id': 'cldnb9fqj02rz07284krw8s8e'},\n", + " 'answer': [{'confidence': 0.5, 'name': 'first_checklist_answer'},\n", + " {'confidence': 0.5, 'name': 'second_checklist_answer'},\n", + " {'confidence': 0.5, 'name': 'third_checklist_answer'}]},\n", + " {'confidence': 0.5,\n", + " 'uuid': 'ba93e801-b49c-45ac-bd94-df2f8d94cb1d',\n", + " 'dataRow': {'id': 'cldnb9fqj02rz07284krw8s8e'},\n", + " 'name': 'polygon_geo',\n", + " 'classifications': [],\n", + " 'polygon': [{'x': -122.31703039689702, 'y': 37.87397804081582},\n", + " {'x': -122.31702351036107, 'y': 37.87393525033866},\n", + " {'x': -122.31698907768116, 'y': 37.87389857276706},\n", + " {'x': -122.3169787478772, 'y': 37.87385883871054},\n", + " {'x': -122.31695808826926, 'y': 37.87385578224377},\n", + " {'x': -122.31695464500127, 'y': 37.873816048164166},\n", + " {'x': -122.31692021232138, 'y': 37.873779370533214},\n", + " {'x': -122.31690988251741, 'y': 37.87373352346883},\n", + " {'x': -122.3168857796415, 'y': 37.873696845796786},\n", + " {'x': -122.3168547902296, 'y': 37.873684619902065},\n", + " {'x': -122.31682035754969, 'y': 37.873611264491025},\n", + " {'x': -122.31676526526188, 'y': 37.87355013492598},\n", + " {'x': -122.3167583787259, 'y': 37.87351651364362},\n", + " {'x': -122.31671017297403, 'y': 37.87348900531027},\n", + " {'x': -122.31671017297403, 'y': 37.873452327516496},\n", + " {'x': -122.31667918356217, 'y': 37.87344010158117},\n", + " {'x': -122.31663442107829, 'y': 37.87335451997715},\n", + " {'x': -122.31660343166638, 'y': 37.87334840700161},\n", + " {'x': -122.31659998839841, 'y': 37.873320898605485},\n", + " {'x': -122.31654489611057, 'y': 37.87329033370888},\n", + " {'x': -122.31652767977064, 'y': 37.87319863894286},\n", + " {'x': -122.31648980382273, 'y': 37.8731833564708},\n", + " {'x': -122.31648980382273, 'y': 37.873161961004534},\n", + " {'x': -122.31641749519497, 'y': 37.87309166157168},\n", + " {'x': -122.316410608659, 'y': 37.873054983580076},\n", + " {'x': -122.31639683558704, 'y': 37.873039701078184},\n", + " {'x': -122.31635551637117, 'y': 37.873039701078184},\n", + " {'x': -122.31635551637117, 'y': 37.87398109727749},\n", + " {'x': -122.31703039689702, 'y': 37.87397804081582}]}]" + ] + }, + "metadata": {}, + "execution_count": 24 + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "# If using NDJSON" + ], + "metadata": { + "id": "dXRQbo4co8Vh" + } + }, + { + "cell_type": "code", + "source": [ + "label_ndjson_method_2 = []\n", + "for prediction in [\n", + " radio_prediction_ndjson,\n", + " checklist_prediction_ndjson,\n", + " bbox_with_free_text_subclass_ndjson, \n", + " bbox_with_checklist_subclass_ndjson,\n", + " bbox_prediction_ndjson,\n", + " point_prediction_ndjson,\n", + " polyline_prediction_ndjson, \n", + " polygon_prediction_ndjson,\n", + " polygon_prediction_two_ndjson\n", + "]:\n", + " prediction.update({\n", + " 'uuid': str(uuid.uuid4()),\n", + " 'dataRow': {'id': data_row.uid},\n", + " })\n", + " label_ndjson_method_2.append(prediction)" + ], + "metadata": { + "id": "mwu3iXn-oofV" + }, + "execution_count": 26, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "## Step 6. Upload the predictions payload to the Model Run " + ], + "metadata": { + "id": "viFHCnBeTD1Y" + } + }, + { + "cell_type": "code", + "source": [ + "# Upload the prediction label to the Model Run\n", + "upload_job_prediction = model_run.add_predictions(\n", + " name=\"prediction_upload_job\"+str(uuid.uuid4()),\n", + " predictions=label_ndjson)\n", + "\n", + "# Errors will appear for annotation uploads that failed.\n", + "print(\"Errors:\", upload_job_prediction.errors)" + ], + "metadata": { + "id": "uCI8pLTITQNG", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "90720cd6-4fa0-4d3b-c36d-14f3b3e1c072" + }, + "execution_count": 25, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Errors: []\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "## Step 7: Send annotations to the Model Run \n", + "To send annotations to a Model Run, we must first import them into a project, create a label payload and then send them to the Model Run." + ], + "metadata": { + "id": "T-ZHWWI3JgmX" + } + }, + { + "cell_type": "markdown", + "source": [ + "##### 7.1. Create a labelbox project" + ], + "metadata": { + "id": "CYRiqHr2O_aL" + } + }, + { + "cell_type": "code", + "source": [ + "# Create a Labelbox project\n", + "project = client.create_project(name=\"geospatial_prediction_demo\", \n", + " queue_mode=lb_queue_mode.QueueMode.Batch,\n", + " # Quality Settings setup \n", + " auto_audit_percentage=1,\n", + " auto_audit_number_of_labels=1,\n", + " media_type=lb.MediaType.Geospatial_Tile)\n", + "project.setup_editor(ontology)" + ], + "metadata": { + "id": "jEtoDiDrPFvI" + }, + "execution_count": 27, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "##### 7.2. Create a batch to send to the project " + ], + "metadata": { + "id": "7FEyC-nBPPuD" + } + }, + { + "cell_type": "code", + "source": [ + "project.create_batch(\n", + " \"batch_geospatial_prediction_demo\", # Each batch in a project must have a unique name\n", + " dataset.export_data_rows(), # A list of data rows or data row ids\n", + " 5 # priority between 1(Highest) - 5(lowest)\n", + ")" + ], + "metadata": { + "id": "WRr5tdVEPXXy", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "fee3c579-b151-4b29-d016-244ac976a072" + }, + "execution_count": 28, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": {}, + "execution_count": 28 + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "##### 7.3 Create the annotations payload" + ], + "metadata": { + "id": "FTGAI730UlZ3" + } + }, + { + "cell_type": "code", + "source": [ + "####### Point #######\n", + "\n", + "point_annotation_ndjson = {\n", + " \"name\": \"point_geo\",\n", + " \"point\": {\n", + " \"x\": -122.31741025134123,\n", + " \"y\": 37.87355669249922\n", + " }\n", + "}\n", + "\n", + "####### Polyline #######\n", + "# Coordinates\n", + "coords = [ \n", + " [\n", + " -122.31757789012927,\n", + " 37.87396317833991\n", + " ],\n", + " [\n", + " -122.31639782443663,\n", + " 37.87396741226917\n", + " ],\n", + " [\n", + " -122.31638977853417,\n", + " 37.87277872707839\n", + " ]\n", + " ]\n", + "\n", + "line_points_ndjson = []\n", + "\n", + "for sub in coords: \n", + " line_points_ndjson.append({\"x\":sub[0], \"y\":sub[1]})\n", + "\n", + "\n", + "polyline_annotation_ndjson = {\n", + " \"name\": \"polyline_geo\",\n", + " \"line\": line_points_ndjson\n", + "}\n", + "\n", + "####### Polygon #######\n", + "# Coordinates in the desired EPSG coordinate system\n", + "coords_polygon = [\n", + " [\n", + " -122.31691812612837,\n", + " 37.873289980495024\n", + " ],\n", + " [\n", + " -122.31710184090099,\n", + " 37.87304335144298\n", + " ],\n", + " [\n", + " -122.31680146054286,\n", + " 37.87303594197371\n", + " ],\n", + " [\n", + " -122.31691812612837,\n", + " 37.873289980495024\n", + " ]\n", + "]\n", + "\n", + "polygon_points_ndjson = []\n", + "\n", + "for sub in coords_polygon: \n", + " polygon_points_ndjson.append({\"x\":sub[0], \"y\":sub[1]})\n", + "\n", + "polygon_annotation_ndjson = {\n", + " \"name\": \"polygon_geo\",\n", + " \"polygon\": polygon_points_ndjson\n", + "}\n", + "\n", + "polygon_annotation_two_ndjson = {\n", + " \"name\": \"polygon_geo\",\n", + " \"polygon\": [\n", + " {'x': -122.31703039689702, 'y': 37.87397804081582},\n", + " {'x': -122.31702351036107, 'y': 37.87393525033866},\n", + " {'x': -122.31698907768116, 'y': 37.87389857276706},\n", + " {'x': -122.3169787478772, 'y': 37.87385883871054},\n", + " {'x': -122.31695808826926, 'y': 37.87385578224377},\n", + " {'x': -122.31695464500127, 'y': 37.873816048164166},\n", + " {'x': -122.31692021232138, 'y': 37.873779370533214},\n", + " {'x': -122.31690988251741, 'y': 37.87373352346883},\n", + " {'x': -122.3168857796415, 'y': 37.873696845796786},\n", + " {'x': -122.3168547902296, 'y': 37.873684619902065},\n", + " {'x': -122.31682035754969, 'y': 37.873611264491025},\n", + " {'x': -122.31676526526188, 'y': 37.87355013492598},\n", + " {'x': -122.3167583787259, 'y': 37.87351651364362},\n", + " {'x': -122.31671017297403, 'y': 37.87348900531027},\n", + " {'x': -122.31671017297403, 'y': 37.873452327516496},\n", + " {'x': -122.31667918356217, 'y': 37.87344010158117},\n", + " {'x': -122.31663442107829, 'y': 37.87335451997715},\n", + " {'x': -122.31660343166638, 'y': 37.87334840700161},\n", + " {'x': -122.31659998839841, 'y': 37.873320898605485},\n", + " {'x': -122.31654489611057, 'y': 37.87329033370888},\n", + " {'x': -122.31652767977064, 'y': 37.87319863894286},\n", + " {'x': -122.31648980382273, 'y': 37.8731833564708},\n", + " {'x': -122.31648980382273, 'y': 37.873161961004534},\n", + " {'x': -122.31641749519497, 'y': 37.87309166157168},\n", + " {'x': -122.316410608659, 'y': 37.873054983580076},\n", + " {'x': -122.31639683558704, 'y': 37.873039701078184},\n", + " {'x': -122.31635551637117, 'y': 37.873039701078184},\n", + " {'x': -122.31635551637117, 'y': 37.87398109727749},\n", + " {'x': -122.31703039689702, 'y': 37.87397804081582}\n", + " ]\n", + "}\n", + "\n", + "####### Bounding Box #######\n", + "coord_object = {\n", + " \"coordinates\": [\n", + " [\n", + " [\n", + " -122.31734455895823,\n", + " 37.873713376083884\n", + " ],\n", + " [\n", + " -122.31734455895823,\n", + " 37.87385944699745\n", + " ],\n", + " [\n", + " -122.31673038840458,\n", + " 37.87385944699745\n", + " ],\n", + " [\n", + " -122.31673038840458,\n", + " 37.873713376083884\n", + " ],\n", + " [\n", + " -122.31734455895823,\n", + " 37.873713376083884\n", + " ]\n", + " ]\n", + " ] \n", + " }\n", + "\n", + "\n", + "bbox_top_left = lb_types.Point(x=-122.31734455895823, y=37.873713376083884)\n", + "bbox_bottom_right = lb_types.Point(x=-122.31673038840458, y=37.87385944699745)\n", + "\n", + "bbox_annotation_ndjson = {\n", + " \"name\" : \"bbox_geo\",\n", + " \"bbox\" : {\n", + " 'top': coord_object[\"coordinates\"][0][1][1],\n", + " 'left': coord_object[\"coordinates\"][0][1][0],\n", + " 'height': coord_object[\"coordinates\"][0][3][1] - coord_object[\"coordinates\"][0][1][1], \n", + " 'width': coord_object[\"coordinates\"][0][3][0] - coord_object[\"coordinates\"][0][1][0]\n", + " }\n", + "}\n", + "\n", + "####### Classification - radio (single choice) #######\n", + "\n", + "radio_annotation_ndjson = {\n", + " \"name\": \"radio_question_geo\",\n", + " \"answer\": { \"name\": \"first_radio_answer\"}\n", + "}\n", + "\n", + "####### Classification - Checklist (multi-choice) #######\n", + "\n", + "coord_object_checklist = {\n", + " \"coordinates\": [\n", + " [\n", + " [\n", + " -122.31711256877092,\n", + " 37.87340218056304\n", + " ],\n", + " [\n", + " -122.31711256877092,\n", + " 37.87360752741479\n", + " ],\n", + " [\n", + " -122.31665529331502,\n", + " 37.87360752741479\n", + " ],\n", + " [\n", + " -122.31665529331502,\n", + " 37.87340218056304\n", + " ],\n", + " [\n", + " -122.31711256877092,\n", + " 37.87340218056304\n", + " ]\n", + " ]\n", + " ] \n", + "}\n", + "\n", + "bbox_with_checklist_subclass_annotation_ndjson = {\n", + " \"name\": \"bbox_checklist_geo\", \n", + " \"classifications\": [{\n", + " \"name\": \"checklist_class_name\",\n", + " \"answer\": [\n", + " { \"name\":\"first_checklist_answer\", \"confidence\": 0.5 }\n", + " ] \n", + " }],\n", + " \"bbox\": {\n", + " 'top': coord_object_checklist[\"coordinates\"][0][1][1],\n", + " 'left': coord_object_checklist[\"coordinates\"][0][1][0],\n", + " 'height': coord_object_checklist[\"coordinates\"][0][3][1] - coord_object_checklist[\"coordinates\"][0][1][1], \n", + " 'width': coord_object_checklist[\"coordinates\"][0][3][0] - coord_object_checklist[\"coordinates\"][0][1][0]\n", + " }\n", + "}\n", + "\n", + "####### Classification free form text with bbox #######\n", + "\n", + "coord_object_text ={\n", + " \"coordinates\": [\n", + " [\n", + " [\n", + " -122.31750814315438,\n", + " 37.87318201423049\n", + " ],\n", + " [\n", + " -122.31750814315438,\n", + " 37.87337992476082\n", + " ],\n", + " [\n", + " -122.31710049991725,\n", + " 37.87337992476082\n", + " ],\n", + " [\n", + " -122.31710049991725,\n", + " 37.87318201423049\n", + " ],\n", + " [\n", + " -122.31750814315438,\n", + " 37.87318201423049\n", + " ]\n", + " ]\n", + " ]\n", + "}\n", + "\n", + "bbox_with_free_text_subclass_annotation_ndjson = {\n", + " \"name\":\"bbox_text_geo\",\n", + " \"classifications\": [{\n", + " \"name\": \"free_text_geo\",\n", + " \"answer\": \"sample text\"\n", + " }],\n", + " \"bbox\": {\n", + " 'top': coord_object_text[\"coordinates\"][0][1][1],\n", + " 'left': coord_object_text[\"coordinates\"][0][1][0],\n", + " 'height': coord_object_text[\"coordinates\"][0][3][1] - coord_object_text[\"coordinates\"][0][1][1], \n", + " 'width': coord_object_text[\"coordinates\"][0][3][0] - coord_object_text[\"coordinates\"][0][1][0]\n", + " }\n", + "}\n", + "\n", + "####### Classification - Checklist (multi-choice) #######\n", + "\n", + "checklist_annotation_ndjson = {\n", + " 'name': 'checklist_question_geo',\n", + " 'answer': [\n", + " {'name': 'first_checklist_answer', \"confidence\": 0.5},\n", + " {'name': 'second_checklist_answer', \"confidence\": 0.5},\n", + " {'name': 'third_checklist_answer', \"confidence\": 0.5},\n", + " ]\n", + "}" + ], + "metadata": { + "id": "Xykw7ZACqlRe" + }, + "execution_count": 30, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "##### 7.4. Create the label object" + ], + "metadata": { + "id": "8QwmguFvPltl" + } + }, + { + "cell_type": "code", + "source": [ + "# Create a Label object by identifying the applicable data row in Labelbox and providing a list of annotations\n", + "ndjson_annotation = []\n", + "for annot in [\n", + " radio_annotation_ndjson,\n", + " checklist_annotation_ndjson,\n", + " bbox_with_free_text_subclass_annotation_ndjson, \n", + " bbox_with_checklist_subclass_annotation_ndjson,\n", + " bbox_annotation_ndjson,\n", + " point_annotation_ndjson,\n", + " polyline_annotation_ndjson, \n", + " polygon_annotation_ndjson,\n", + " polygon_annotation_two_ndjson\n", + "]:\n", + " annot.update({\n", + " 'uuid': str(uuid.uuid4()),\n", + " 'dataRow': {'id': data_row.uid},\n", + " })\n", + " ndjson_annotation.append(annot) " + ], + "metadata": { + "id": "9gD_alThQA3G" + }, + "execution_count": 31, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "##### 7.5. Upload annotations to the project using Label Import" + ], + "metadata": { + "id": "nGVNQlvPQ-kF" + } + }, + { + "cell_type": "code", + "source": [ + "upload_job_annotation = lb.LabelImport.create_from_objects(\n", + " client = client,\n", + " project_id = project.uid,\n", + " name=\"geospatial_annotations_import_\" + str(uuid.uuid4()),\n", + " labels=ndjson_annotation)\n", + "\n", + "upload_job_annotation.wait_until_done()\n", + "# Errors will appear for annotation uploads that failed.\n", + "print(\"Errors:\", upload_job_annotation.errors)\n" + ], + "metadata": { + "id": "HYh9AzrlRYX-", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "6e7dfa65-4e39-4bba-fbe9-762f4e138397" + }, + "execution_count": 32, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "WARNING:labelbox.schema.annotation_import:\n", + " Confidence scores are not supported in Label Import.\n", + " Corresponding confidence score values will be ignored.\n", + " \n" + ] + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Errors: []\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "##### 7.6. Send the annotations to the Model Run" + ], + "metadata": { + "id": "Y3rgM-5cRrxM" + } + }, + { + "cell_type": "code", + "source": [ + "# get the labels id from the project\n", + "label_ids = [x['ID'] for x in project.export_labels(download=True)]\n", + "model_run.upsert_labels(label_ids)" + ], + "metadata": { + "id": "i2BrS8CcSBzo", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "dcff45fd-7af5-4b24-87f9-5fe71ddc4cc7" + }, + "execution_count": 33, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "True" + ] + }, + "metadata": {}, + "execution_count": 33 + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "## Optional deletions for cleanup \n" + ], + "metadata": { + "id": "DMtOfWWDWFbJ" + } + }, + { + "cell_type": "code", + "source": [ + "#upload_job\n", + "# project.delete()\n", + "# dataset.delete()" + ], + "metadata": { + "id": "aAhkyvJlWK1p" + }, + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file From b82fd660810c4f65fedb52b99cdb625044ba5c59 Mon Sep 17 00:00:00 2001 From: lmoehlenbrock <120418910+lmoehlenbrock@users.noreply.github.com> Date: Thu, 2 Feb 2023 11:31:26 -0600 Subject: [PATCH 2/3] removed API Key --- examples/prediction_upload/geospatial_predictions.ipynb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/prediction_upload/geospatial_predictions.ipynb b/examples/prediction_upload/geospatial_predictions.ipynb index 1cf2017d2..1ce7ec26c 100644 --- a/examples/prediction_upload/geospatial_predictions.ipynb +++ b/examples/prediction_upload/geospatial_predictions.ipynb @@ -148,7 +148,7 @@ { "cell_type": "code", "source": [ - "API_KEY = \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJjbGJwZ3hmYWVod3c2MDc2dGVkbzVland4Iiwib3JnYW5pemF0aW9uSWQiOiJjbGJvNTl6YTUwbDR5MDd6cWMyaHAxdGFkIiwiYXBpS2V5SWQiOiJjbGJwaDB2cHo2bGFrMDd3dGh0ZnJhbXd3Iiwic2VjcmV0IjoiOGNiMzkwMDcxMDVmMjBhZjcyZDgzMDIzMjAyMWMyN2QiLCJpYXQiOjE2NzExMzIzMDAsImV4cCI6MjMwMjI4NDMwMH0.P6a_kLqFiciEvpvFk0biqBbbIQsDFF-uw7CYtles9hQ\"\n", + "API_KEY = None\n", "client = lb.Client(API_KEY)" ], "metadata": { @@ -1560,4 +1560,4 @@ "outputs": [] } ] -} \ No newline at end of file +} From de9a3b9aed91344fc7f58e01cc12dd6d36f250ca Mon Sep 17 00:00:00 2001 From: lmoehlenbrock <120418910+lmoehlenbrock@users.noreply.github.com> Date: Thu, 2 Feb 2023 14:01:11 -0600 Subject: [PATCH 3/3] Updated notebook per PR comments --- examples/prediction_upload/geospatial_predictions.ipynb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/examples/prediction_upload/geospatial_predictions.ipynb b/examples/prediction_upload/geospatial_predictions.ipynb index 1ce7ec26c..527f5fb29 100644 --- a/examples/prediction_upload/geospatial_predictions.ipynb +++ b/examples/prediction_upload/geospatial_predictions.ipynb @@ -120,7 +120,6 @@ "from PIL import Image\n", "import cv2\n", "import ndjson\n", - "import gdal\n", "\n", "import labelbox as lb\n", "import labelbox.data.annotation_types as lb_types\n", @@ -770,9 +769,6 @@ "source": [ " ## Lets create another polygon annotation with python annotation tools that draws the image using cv2 and PIL python libraries\n", "\n", - "from PIL import Image\n", - "import cv2\n", - "\n", "hsv = cv2.cvtColor(tiled_image_data.value, cv2.COLOR_RGB2HSV)\n", "mask = cv2.inRange(hsv, (10, 25, 25), (100, 150, 255))\n", "kernel = np.ones((15, 20), np.uint8)\n", @@ -796,7 +792,7 @@ "\n", "# Here is the NDJSON representation of the resulting polygon:\n", "polygon_prediction_two_ndjson = {\n", - " \"name\": \"polygon_geo\",\n", + " \"name\": \"polygon_geo_2\",\n", " \"confidence\": 0.5,\n", " \"polygon\": [\n", " {'x': -122.31703039689702, 'y': 37.87397804081582},\n",