_utils.py 1.1 KB

1234567891011121314151617181920212223242526272829303132
  1. import imgviz
  2. import numpy as np
  3. import skimage
  4. def _get_contour_length(contour):
  5. contour_start = contour
  6. contour_end = np.r_[contour[1:], contour[0:1]]
  7. return np.linalg.norm(contour_end - contour_start, axis=1).sum()
  8. def compute_polygon_from_mask(mask):
  9. contours = skimage.measure.find_contours(np.pad(mask, pad_width=1))
  10. contour = max(contours, key=_get_contour_length)
  11. POLYGON_APPROX_TOLERANCE = 0.004
  12. polygon = skimage.measure.approximate_polygon(
  13. coords=contour,
  14. tolerance=np.ptp(contour, axis=0).max() * POLYGON_APPROX_TOLERANCE,
  15. )
  16. polygon = np.clip(polygon, (0, 0), (mask.shape[0] - 1, mask.shape[1] - 1))
  17. polygon = polygon[:-1] # drop last point that is duplicate of first point
  18. if 0:
  19. import PIL.Image
  20. image_pil = PIL.Image.fromarray(imgviz.gray2rgb(imgviz.bool2ubyte(mask)))
  21. imgviz.draw.line_(image_pil, yx=polygon, fill=(0, 255, 0))
  22. for point in polygon:
  23. imgviz.draw.circle_(image_pil, center=point, diameter=10, fill=(0, 255, 0))
  24. imgviz.io.imsave("contour.jpg", np.asarray(image_pil))
  25. return polygon[:, ::-1] # yx -> xy