@@ -318,9 +318,6 @@ def get_gson(
318318 x-coordinate offset. (to set geojson to .mrxs wsi coordinates)
319319 y_offset : int, default=0
320320 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.
324321
325322 Returns
326323 -------
@@ -357,25 +354,38 @@ def get_gson(
357354 inst_type_soft [key ] = float (inst_type_soft [key ])
358355
359356 # 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 )
361358 contours = contours [0 ] if len (contours ) == 2 else contours [1 ]
362359
360+ shell = contours [0 ] # exterior
361+ holes = [cont for cont in contours [1 :]]
362+
363363 # got a line instead of a polygon
364- if contours [ 0 ] .shape [0 ] < 3 :
364+ if shell .shape [0 ] < 3 :
365365 continue
366366
367367 # shift coordinates based on the offsets
368368 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+
370374 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
372379
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
375385
376386 features .append (
377387 FileHandler .geo_obj (
378- poly = Polygon (poly ),
388+ poly = Polygon (shell = shell , holes = holes ),
379389 uid = inst_id ,
380390 class_name = inst_type ,
381391 class_probs = inst_type_soft ,
@@ -390,6 +400,7 @@ def to_gson(
390400 features : List [Dict [str , Any ]],
391401 format : str = ".feather" ,
392402 show_bbox : bool = True ,
403+ silence_warnings : bool = True ,
393404 ) -> None :
394405 """Write a geojson/feather/parquet file from a list of geojson features.
395406
@@ -403,6 +414,8 @@ def to_gson(
403414 The output format. One of ".feather", ".parquet", ".geojson".
404415 show_bbox : bool, default=True
405416 If True, the bbox is added to the geojson object.
417+ silence_warnings : bool, default=True
418+ If True, warnings are silenced.
406419 """
407420 out_fn = Path (out_fn )
408421 if format not in (".feather" , ".parquet" , ".geojson" ):
@@ -442,7 +455,8 @@ def to_gson(
442455 if show_bbox :
443456 geo ["bbox" ] = tuple (gdf .total_bounds )
444457 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." )
446460
447461 if format == ".feather" :
448462 gdf .to_feather (out_fn .with_suffix (".feather" ))
0 commit comments