Skip to content

Commit 9f160e8

Browse files
author
Matt Sokoloff
committed
minor notebook improvements
1 parent c6f7469 commit 9f160e8

File tree

1 file changed

+57
-18
lines changed

1 file changed

+57
-18
lines changed

examples/model_assisted_labeling/tiled_imagery_mal.ipynb

Lines changed: 57 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,9 @@
220220
"id": "portable-grenada",
221221
"metadata": {},
222222
"source": [
223-
"#### Grab featureSchemaIds"
223+
"* <b>Grab featureSchemaIds</b>\n",
224+
"* This enables us to assign model inferences to a specific class in labelbox\n",
225+
"* Checkout the ndjson section to see where this is used"
224226
]
225227
},
226228
{
@@ -239,7 +241,7 @@
239241
],
240242
"source": [
241243
"# When we created a project with the ontology defined above, all of the ids were assigned.\n",
242-
"# So lets reconstruct the ontology builder with all of the ids.\n",
244+
"# Let's reconstruct the ontology builder with all of the ids.\n",
243245
"ontology = ontology_builder.from_project(project)\n",
244246
"# We want all of the feature schemas to be easily accessible by name.\n",
245247
"schema_lookup = {tool.name: tool.feature_schema_id for tool in ontology.tools}\n",
@@ -252,18 +254,18 @@
252254
"metadata": {},
253255
"source": [
254256
"### Create import objects\n",
255-
"* We want to create a json payload that matches this: https://docs.labelbox.com/en/model-assisted-labeling/create-import-file#images-7961\n",
256-
"* Here we will run inferences on all of our data (only one image this time)\n",
257-
"* See other notebook on supported objects. Everything is the same except coords are in lat lng"
257+
"* We want to create a polygon json payload that matches the format documented here : https://docs.labelbox.com/data-model/en/index-en#polygon"
258258
]
259259
},
260260
{
261261
"cell_type": "code",
262-
"execution_count": 11,
262+
"execution_count": null,
263263
"id": "advisory-preserve",
264264
"metadata": {},
265265
"outputs": [],
266266
"source": [
267+
"# Create helper functions\n",
268+
"\n",
267269
"def tile_generator(bounds: GeoBoundary, zoom : int):\n",
268270
" # Returns all tiles that intersect with the provide bounds\n",
269271
" bds = box(bounds.top_right.lng, bounds.top_right.lat, bounds.bottom_left.lng, bounds.bottom_left.lat).bounds\n",
@@ -296,16 +298,7 @@
296298
" max_x -= tile_bounds[0]\n",
297299
" min_y -= tile_bounds[1]\n",
298300
" max_y -= tile_bounds[1]\n",
299-
" return [int(x) for x in [min_x, min_y, max_x, max_y]], intersection\n"
300-
]
301-
},
302-
{
303-
"cell_type": "code",
304-
"execution_count": 12,
305-
"id": "according-sixth",
306-
"metadata": {},
307-
"outputs": [],
308-
"source": [
301+
" return [int(x) for x in [min_x, min_y, max_x, max_y]], intersection\n",
309302
"\n",
310303
"def get_image(tile : Tile, url : str) -> np.ndarray:\n",
311304
" # Downloads a tile\n",
@@ -320,6 +313,16 @@
320313
"\n"
321314
]
322315
},
316+
{
317+
"cell_type": "markdown",
318+
"id": "informative-happiness",
319+
"metadata": {},
320+
"source": [
321+
"* <b>Visualize tile and labeling region</b>\n",
322+
"* The tile is one of the tiles that overlapped with the `GeoBoundary` that we provided\n",
323+
"* The red box, `GeoBoundary`, is the area where the labelers will label"
324+
]
325+
},
323326
{
324327
"cell_type": "code",
325328
"execution_count": 13,
@@ -372,6 +375,16 @@
372375
"Image.fromarray(crop)"
373376
]
374377
},
378+
{
379+
"cell_type": "markdown",
380+
"id": "distant-breast",
381+
"metadata": {},
382+
"source": [
383+
"* <b>Run Model</b>\n",
384+
"* This is where users can run model inferences.\n",
385+
"* For this example we are detecting water with some simple image processing"
386+
]
387+
},
375388
{
376389
"cell_type": "code",
377390
"execution_count": 15,
@@ -411,6 +424,14 @@
411424
"Image.fromarray(mask)"
412425
]
413426
},
427+
{
428+
"cell_type": "markdown",
429+
"id": "earned-correspondence",
430+
"metadata": {},
431+
"source": [
432+
"* <b>Convert Mask to WGS84 Polygons<b>"
433+
]
434+
},
414435
{
415436
"cell_type": "code",
416437
"execution_count": 17,
@@ -419,6 +440,7 @@
419440
"outputs": [],
420441
"source": [
421442
"def extract_polygons(mask: np.ndarray) -> Polygon:\n",
443+
" # Turns a segementation mask into shapely polygons\n",
422444
" contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)\n",
423445
" polygons = []\n",
424446
"\n",
@@ -431,7 +453,8 @@
431453
" polygons = [Polygon(poly) for poly in polygons]\n",
432454
" return [poly.simplify(3) for poly in polygons if poly.area > 50]\n",
433455
"\n",
434-
"def convert_to_epsg4326(poly : Polygon, intersection: Polygon) -> List[GeoPoint]:\n",
456+
"def convert_to_wgs84(poly : Polygon, intersection: Polygon) -> List[GeoPoint]:\n",
457+
" # Turns pixel polygons into wgs84 polygons\n",
435458
" result = []\n",
436459
" for coord in poly.__geo_interface__['coordinates'][0]:\n",
437460
" x = intersection.bounds[1] + coord[0]\n",
@@ -478,7 +501,7 @@
478501
"metadata": {},
479502
"outputs": [],
480503
"source": [
481-
"geo_polygons = [convert_to_epsg4326(poly, intersection) for poly in pixel_polygons]"
504+
"geo_polygons = [convert_to_wgs84(poly, intersection) for poly in pixel_polygons]"
482505
]
483506
},
484507
{
@@ -508,6 +531,14 @@
508531
"geo_polygons"
509532
]
510533
},
534+
{
535+
"cell_type": "markdown",
536+
"id": "industrial-tuner",
537+
"metadata": {},
538+
"source": [
539+
"* <b>Create NDJson From Geo Polygons</b>"
540+
]
541+
},
511542
{
512543
"cell_type": "code",
513544
"execution_count": 27,
@@ -532,6 +563,14 @@
532563
" })"
533564
]
534565
},
566+
{
567+
"cell_type": "markdown",
568+
"id": "former-skiing",
569+
"metadata": {},
570+
"source": [
571+
"* <b>Upload to Labelbox</b>"
572+
]
573+
},
535574
{
536575
"cell_type": "code",
537576
"execution_count": 28,

0 commit comments

Comments
 (0)