Search code examples
pythonopencvcomputer-visionimage-segmentationyolov8

How to convert a binary mask (segmentation) to YOLO Segmentation text file?


I have found a solution but the problem is I have way too many points and I want to reduce them. Which is not a major issue, but still I would like to have fewer points.

I have searched for other answers here but I have found nothing pertaining to my issue. I have attached a sample mask for reference.

The sample binarised mask

Just to be clear, I have written a script in Python that does just that. The steps I had taken were:

  1. Convert the colorised mask to a binarized one (since I have only one class).
  2. Apply contours on the image and find the edge points of the mask.
  3. Ravel the detected contour points.
  4. Based on major shifts in angles, noted down only those points.
  5. Save all the points in YOLO segmentation text format (cls_name x1 y1 x2 y2 .... xn yn)

EDIT: I did manage to do all these. But in the end I came to a horrible realization that, because it considers the outside borders, and if the labels are all overlapped, it becomes one big blob that contains unwanted region too. So I had to drop this and use those masks in UNET where I am getting the outputs I desire.


Solution

  • If you want to reduce the number of points, you can use cv.approxPolyDP().

    It's not a very smart algorithm but it will do. It will either maintain or remove certain points, depending on how similar the contour would be if each point were removed. It will not insert or move any points.

    epsilon = 0.1 * cv.arcLength(cnt, True)
    approx = cv.approxPolyDP(cnt, epsilon, True)
    

    Choose a smaller epsilon (reduce the factor) to get a more accurate result, i.e. with not as many points removed.

    Here's the official tutorial:

    https://docs.opencv.org/4.x/dd/d49/tutorial_py_contour_features.html