@@ -318,9 +318,6 @@ def get_gson(
318
318
x-coordinate offset. (to set geojson to .mrxs wsi coordinates)
319
319
y_offset : int, default=0
320
320
y-coordinate offset. (to set geojson to .mrxs wsi coordinates)
321
- geo_format : str, default="qupath"
322
- The format for the geo object. "qupath" format allows the result file
323
- to be read with QuPath. "simple" format allows for geopandas etc.
324
321
325
322
Returns
326
323
-------
@@ -357,25 +354,38 @@ def get_gson(
357
354
inst_type_soft [key ] = float (inst_type_soft [key ])
358
355
359
356
# get the cell contour coordinates
360
- contours = cv2 .findContours (inst , cv2 .RETR_LIST , cv2 .CHAIN_APPROX_SIMPLE )
357
+ contours = cv2 .findContours (inst , cv2 .RETR_TREE , cv2 .CHAIN_APPROX_SIMPLE )
361
358
contours = contours [0 ] if len (contours ) == 2 else contours [1 ]
362
359
360
+ shell = contours [0 ] # exterior
361
+ holes = [cont for cont in contours [1 :]]
362
+
363
363
# got a line instead of a polygon
364
- if contours [ 0 ] .shape [0 ] < 3 :
364
+ if shell .shape [0 ] < 3 :
365
365
continue
366
366
367
367
# shift coordinates based on the offsets
368
368
if x_offset :
369
- contours [0 ][..., 0 ] += x_offset
369
+ shell [..., 0 ] += x_offset
370
+ if holes :
371
+ for cont in holes :
372
+ cont [..., 0 ] += x_offset
373
+
370
374
if y_offset :
371
- contours [0 ][..., 1 ] += y_offset
375
+ shell [..., 1 ] += y_offset
376
+ if holes :
377
+ for cont in holes :
378
+ cont [..., 1 ] += y_offset
372
379
373
- poly = contours [0 ].squeeze ().tolist ()
374
- poly .append (poly [0 ]) # close the polygon
380
+ # convert to list for shapely Polygon
381
+ shell = shell .squeeze ().tolist ()
382
+ if holes :
383
+ holes = [cont .squeeze ().tolist () for cont in holes ]
384
+ # shell.append(shell[0]) # close the polygon
375
385
376
386
features .append (
377
387
FileHandler .geo_obj (
378
- poly = Polygon (poly ),
388
+ poly = Polygon (shell = shell , holes = holes ),
379
389
uid = inst_id ,
380
390
class_name = inst_type ,
381
391
class_probs = inst_type_soft ,
@@ -390,6 +400,7 @@ def to_gson(
390
400
features : List [Dict [str , Any ]],
391
401
format : str = ".feather" ,
392
402
show_bbox : bool = True ,
403
+ silence_warnings : bool = True ,
393
404
) -> None :
394
405
"""Write a geojson/feather/parquet file from a list of geojson features.
395
406
@@ -403,6 +414,8 @@ def to_gson(
403
414
The output format. One of ".feather", ".parquet", ".geojson".
404
415
show_bbox : bool, default=True
405
416
If True, the bbox is added to the geojson object.
417
+ silence_warnings : bool, default=True
418
+ If True, warnings are silenced.
406
419
"""
407
420
out_fn = Path (out_fn )
408
421
if format not in (".feather" , ".parquet" , ".geojson" ):
@@ -442,7 +455,8 @@ def to_gson(
442
455
if show_bbox :
443
456
geo ["bbox" ] = tuple (gdf .total_bounds )
444
457
else :
445
- warnings .warn (f"The { out_fn .name } file is empty." )
458
+ if not silence_warnings :
459
+ warnings .warn (f"The { out_fn .name } file is empty." )
446
460
447
461
if format == ".feather" :
448
462
gdf .to_feather (out_fn .with_suffix (".feather" ))
0 commit comments