|
59 | 59 | "source": [
|
60 | 60 | "import labelbox as lb\n",
|
61 | 61 | "import labelbox.types as lb_types\n",
|
| 62 | + "from labelbox.schema.conflict_resolution_strategy import ConflictResolutionStrategy\n", |
62 | 63 | "import uuid"
|
63 | 64 | ],
|
64 | 65 | "cell_type": "code",
|
|
138 | 139 | {
|
139 | 140 | "metadata": {},
|
140 | 141 | "source": [
|
141 |
| - "### Add a data rows to a project \n" |
| 142 | + "### Add data rows to a project \n" |
142 | 143 | ],
|
143 | 144 | "cell_type": "markdown"
|
144 | 145 | },
|
|
226 | 227 | "\n",
|
227 | 228 | "In this section, we are creating an ontology to attach to a project and creating labels to import as ground truths. We need this setup to demonstrate other methods later in the demo. For more information, please reference our [Ontology](https://docs.labelbox.com/reference/ontology) and [Import Image Annotation](https://docs.labelbox.com/reference/import-image-annotations) development guides."
|
228 | 229 | ],
|
229 |
| - "cell_type": "raw" |
230 |
| - }, |
231 |
| - { |
232 |
| - "metadata": {}, |
233 |
| - "source": [], |
234 | 230 | "cell_type": "markdown"
|
235 | 231 | },
|
236 | 232 | {
|
237 | 233 | "metadata": {},
|
238 | 234 | "source": [
|
239 |
| - "Create your ontology" |
| 235 | + "#### Create your ontology" |
240 | 236 | ],
|
241 |
| - "cell_type": "raw" |
| 237 | + "cell_type": "markdown" |
242 | 238 | },
|
243 | 239 | {
|
244 | 240 | "metadata": {},
|
|
263 | 259 | {
|
264 | 260 | "metadata": {},
|
265 | 261 | "source": [
|
266 |
| - "Attach ontology to project" |
| 262 | + "#### Attach ontology to project" |
267 | 263 | ],
|
268 | 264 | "cell_type": "markdown"
|
269 | 265 | },
|
270 | 266 | {
|
271 | 267 | "metadata": {},
|
272 | 268 | "source": [
|
273 |
| - "\n", |
274 | 269 | "project.setup_editor(ontology)"
|
275 | 270 | ],
|
276 | 271 | "cell_type": "code",
|
|
280 | 275 | {
|
281 | 276 | "metadata": {},
|
282 | 277 | "source": [
|
283 |
| - "Create labels and upload them to project as ground truths" |
| 278 | + "### Create labels and upload them to project as ground truths" |
284 | 279 | ],
|
285 | 280 | "cell_type": "markdown"
|
286 | 281 | },
|
|
290 | 285 | "# Create labels\n",
|
291 | 286 | "labels = []\n",
|
292 | 287 | "for global_key in global_keys:\n",
|
293 |
| - " labels.append(lb_types.Label(data=lb_types.ImageData(global_key=global_key),\n", |
| 288 | + " labels.append(lb_types.Label(data={\"global_key\":global_key},\n", |
294 | 289 | " annotations=[\n",
|
295 | 290 | " # Create radio classification annotation for labels\n",
|
296 | 291 | " lb_types.ClassificationAnnotation(\n",
|
|
384 | 379 | "outputs": [],
|
385 | 380 | "execution_count": null
|
386 | 381 | },
|
| 382 | + { |
| 383 | + "metadata": {}, |
| 384 | + "source": [ |
| 385 | + "### Copy labels and data rows from one project to a different project\n", |
| 386 | + "In the below steps we will be copying data rows with their corresponding labels from one project to a different project with a similar ontology. First, we must set up a new project with a ontology that matches the tooling of our source project ontology." |
| 387 | + ], |
| 388 | + "cell_type": "markdown" |
| 389 | + }, |
| 390 | + { |
| 391 | + "metadata": {}, |
| 392 | + "source": [ |
| 393 | + "# Create an empty destination project\n", |
| 394 | + "destination_project = client.create_project(name=\"destination-test-project\",\n", |
| 395 | + " description=\"a description\",\n", |
| 396 | + " media_type=lb.MediaType.Image)\n", |
| 397 | + "\n", |
| 398 | + "# Create ontology and attach to destination project\n", |
| 399 | + "destination_ontology_builder = lb.OntologyBuilder(classifications=[ # List of Classification objects\n", |
| 400 | + " lb.Classification(class_type=lb.Classification.Type.RADIO,\n", |
| 401 | + " name=\"destination_radio_question\",\n", |
| 402 | + " options=[\n", |
| 403 | + " lb.Option(value=\"destination_first_radio_answer\"),\n", |
| 404 | + " lb.Option(value=\"destination_second_radio_answer\")\n", |
| 405 | + " ]),\n", |
| 406 | + "])\n", |
| 407 | + "\n", |
| 408 | + "destination_ontology = client.create_ontology(\"dest-test-ontology\",\n", |
| 409 | + " ontology_builder.asdict())\n", |
| 410 | + "\n", |
| 411 | + "destination_project.setup_editor(destination_ontology)" |
| 412 | + ], |
| 413 | + "cell_type": "code", |
| 414 | + "outputs": [], |
| 415 | + "execution_count": null |
| 416 | + }, |
| 417 | + { |
| 418 | + "metadata": {}, |
| 419 | + "source": [ |
| 420 | + "#### Copy data rows and labels\n", |
| 421 | + "To copy our data rows and labels to our project from a source project we will be using the `send_to_annotate_from_catalog` method with our Labelbox client.\n", |
| 422 | + "\n", |
| 423 | + "##### Parameters\n", |
| 424 | + "\n", |
| 425 | + "When you send data rows with labels to our destination project, you may choose to include or exclude certain parameters, at a minimum a `source_project_id` will need to be provided:\n", |
| 426 | + "\n", |
| 427 | + "* `source_project_id`\n", |
| 428 | + " - The id of the project were our data rows with labels will originate.\n", |
| 429 | + "* `annotation_ontology_mapping`\n", |
| 430 | + " - A dictionary containing the mapping of the source project's ontology feature schema ids to the destination project's ontology feature schema ids. If left empty only the data rows will be sent to our destination project with no labels.\n", |
| 431 | + "* `exclude_data_rows_in_project`\n", |
| 432 | + " - Excludes data rows that are already in the project. \n", |
| 433 | + "* `override_existing_annotations_rule` \n", |
| 434 | + " - The strategy defining how to handle conflicts in classifications between the data rows that already exist in the project and incoming labels from the source project. \n", |
| 435 | + " * Defaults to ConflictResolutionStrategy.KeepExisting\n", |
| 436 | + " * Options include:\n", |
| 437 | + " * ConflictResolutionStrategy.KeepExisting\n", |
| 438 | + " * ConflictResolutionStrategy.OverrideWithPredictions\n", |
| 439 | + " * ConflictResolutionStrategy.OverrideWithAnnotations\n", |
| 440 | + "* `param batch_priority`\n", |
| 441 | + " - The priority of the batch." |
| 442 | + ], |
| 443 | + "cell_type": "markdown" |
| 444 | + }, |
| 445 | + { |
| 446 | + "metadata": {}, |
| 447 | + "source": [ |
| 448 | + "# Get ontology dictionary to obtain featureSchemaIds\n", |
| 449 | + "source_ontology_normalized = ontology.normalized\n", |
| 450 | + "destination_ontology_normalized = destination_ontology.normalized\n", |
| 451 | + "\n", |
| 452 | + "ANNOTATION_ONTOLOGY_MAPPING = {\n", |
| 453 | + " source_ontology_normalized[\"classifications\"][0][\"featureSchemaId\"]:destination_ontology_normalized[\"classifications\"][0][\"featureSchemaId\"], # Classification featureSchemaID\n", |
| 454 | + " source_ontology_normalized[\"classifications\"][0][\"options\"][0][\"featureSchemaId\"]:destination_ontology_normalized[\"classifications\"][0][\"options\"][0][\"featureSchemaId\"], # Different Classification Answer featureSchemaIDs\n", |
| 455 | + " source_ontology_normalized[\"classifications\"][0][\"options\"][1][\"featureSchemaId\"]:destination_ontology_normalized[\"classifications\"][0][\"options\"][1][\"featureSchemaId\"]\n", |
| 456 | + "}" |
| 457 | + ], |
| 458 | + "cell_type": "code", |
| 459 | + "outputs": [], |
| 460 | + "execution_count": null |
| 461 | + }, |
| 462 | + { |
| 463 | + "metadata": {}, |
| 464 | + "source": [ |
| 465 | + "send_to_annotate_params = {\n", |
| 466 | + " \"source_project_id\": project.uid,\n", |
| 467 | + " \"annotations_ontology_mapping\": ANNOTATION_ONTOLOGY_MAPPING,\n", |
| 468 | + " \"exclude_data_rows_in_project\": False,\n", |
| 469 | + " \"override_existing_annotations_rule\": ConflictResolutionStrategy.OverrideWithPredictions,\n", |
| 470 | + " \"batch_priority\": 5,\n", |
| 471 | + "}\n", |
| 472 | + "\n", |
| 473 | + "# Get task id to workflow you want to send data rows. If sent to initial labeling queue, labels will be pre-labels. \n", |
| 474 | + "queue_id = [queue.uid for queue in destination_project.task_queues() if queue.queue_type == \"MANUAL_REVIEW_QUEUE\" ][0]\n", |
| 475 | + "\n", |
| 476 | + "task = client.send_to_annotate_from_catalog(\n", |
| 477 | + " destination_project_id=destination_project.uid,\n", |
| 478 | + " task_queue_id=queue_id, # ID of workflow task, set ID to None if you want to send data rows with labels to the Done queue.\n", |
| 479 | + " batch_name=\"Prediction Import Demo Batch\",\n", |
| 480 | + " data_rows=lb.GlobalKeys(\n", |
| 481 | + " global_keys # Provide a list of global keys from source project\n", |
| 482 | + " ),\n", |
| 483 | + " params=send_to_annotate_params\n", |
| 484 | + " )\n", |
| 485 | + "\n", |
| 486 | + "task.wait_till_done()\n", |
| 487 | + "\n", |
| 488 | + "print(f\"Errors: {task.errors}\")" |
| 489 | + ], |
| 490 | + "cell_type": "code", |
| 491 | + "outputs": [], |
| 492 | + "execution_count": null |
| 493 | + }, |
387 | 494 | {
|
388 | 495 | "metadata": {},
|
389 | 496 | "source": [
|
|
395 | 502 | "metadata": {},
|
396 | 503 | "source": [
|
397 | 504 | "# project.delete()\n",
|
| 505 | + "# destination_project.delete()\n", |
398 | 506 | "# dataset.delete()\n",
|
| 507 | + "# client.delete_unused_ontology(destination_ontology.uid)\n", |
399 | 508 | "# client.delete_unused_ontology(ontology.uid)"
|
400 | 509 | ],
|
401 | 510 | "cell_type": "code",
|
|
0 commit comments