diff --git a/examples/prediction_upload/geospatial_predictions.ipynb b/examples/prediction_upload/geospatial_predictions.ipynb new file mode 100644 index 000000000..527f5fb29 --- /dev/null +++ b/examples/prediction_upload/geospatial_predictions.ipynb @@ -0,0 +1,1559 @@ +{ + "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", + "\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 = None\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", + "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_2\",\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": [] + } + ] +}