Mask2Label · instance masks to single-row polygon labels
One polygon row per instance. Holes and detached parts intact.
Mask2Label converts the masks your annotators, SAM or your renderer already produce into label rows in the YOLO segmentation format, without dropping fragments or splitting one object into several. In every example on this page, every hole is still open after rasterizing. There is no limit on the number of holes or separate parts in an instance.
A Python + Cython converter with tests and documentation. It reads colour-encoded instance PNGs today; adapters for other encodings are part of integration. Offered as a commercial licence, an exclusive licence or an outright IP purchase, with fixed-fee integration into your export pipeline. Output checked against the Ultralytics 8.4.12 dataset loader.
Where mask-to-polygon conversion goes wrong
The YOLO segmentation format stores one flat list of points per object. It has no syntax for a hole or for an object in several pieces, so every converter has to make a choice, and the usual choices change your labels without telling you.
Holes get filled
Tracing only the outer boundary turns a ring into a disc. The model is then trained to predict pixels your annotator deliberately left out.
Parts get dropped or split
An occluded or fragmented object becomes “largest piece only”, or several separate objects. Instance counts no longer match the source.
Raster masks have no route at all
Brush tools, SAM output, medical masks and rendered segmentation images are rasters. Many exporters write YOLO-format labels only from hand-drawn polygons.
Real examples
These are real source images with the converter’s real output drawn on them. Where available, switch between the archive render, a contour-only view and a filled view; the contour and filled views show boxes and class labels. Click any image to open it at full size.
How to read the overlays: the straight lines that cross gaps are zero-width seams. They are how a single YOLO row can carry many parts and holes; a seam is traced out and back, so it encloses no area. Label files are not published here; they are delivered with an evaluation build or a licence.
Measured against the free alternatives
The fair test of any exporter is what the Ultralytics loader gets back from its labels. Every label below was rasterized with Ultralytics’ own polygon2mask and compared with the source mask, pixel for pixel.
| Test mask | Mask2Label | supervision 0.31.7 | Ultralytics convert_coco* |
|---|---|---|---|
| Dense glyphs: 1 instance, 91 parts, 81 holes (1500 × 1500) | 99.70% | 93.80% | 73.87% |
| Four closely packed characters: 4 instances, 23 holes | 99.89% | 93.29% | 91.69% |
| Handwritten β: 1 instance, 2 holes (128 × 128) | 100.00% | 95.50% | 81.19% |
| Multipart test shape: 19 parts, 7 holes (89 × 83) | 98.78% | 67.70% | 68.20% |
| 200 holes of 1–3 pixels in one blob (synthetic) | 100.00% 200 of 200 open | 99.51% 103 of 200 open | 99.60% 0 of 200 open |
| Foreground pixels lost per mask, eleven masks† | 0 | 0 to 14,241 | 0 to 10,829 |
| Seconds for the dense-glyph mask‡ | 4.3 | 0.1 | 0.1 |
How this was measured. Versions: Ultralytics 8.4.12, supervision 0.31.7 (DetectionDataset.as_yolo, default arguments), OpenCV 4.12, Python 3.13; twelve masks, six real and six synthetic. *convert_coco was given each instance’s outer contours, which is what its own mask path keeps. †One of the twelve masks is not shown on this page and is left out of that row; Mask2Label loses no pixel on it either. ‡Mask2Label: the whole run, including reading the PNG and writing the label and inspection files (conversion alone: 1.5 s); the other two: the conversion call on masks already in memory. Every figure is for labels read the way Ultralytics reads them, at native resolution; a tool that rasterizes labels differently will give different figures, and the integration’s acceptance tests are run against the loader you target. On a training-like grid (640 pixels on the long side, default mask ratio), Mask2Label scores above supervision on eleven of the twelve masks; read through the Ultralytics training loader itself, the dense-glyph label scores 89.2% against 84.8%. Mask2Label is the slowest of the three on eleven of the twelve masks; a faster seam search is part of the integration work. Twelve masks are not a study, and they say nothing yet about trained-model accuracy. Run it on yours.
Try it on your own masks, free
You should not have to take a stranger’s screenshots on trust. Send a handful of masks that give your current export trouble and compare the result with what you ship today.
- Send 5–10 masksAny raster form: PNG instance or class maps, brush or RLE exports, SAM output, rendered segmentation with an ID map. Public or synthetic samples are fine.
- 48-hour turnaroundI run the converter and measure the result the way the Ultralytics training loader rasterizes it.
- You get the evidenceOverlays for every mask, a per-instance report (rows, holes, parts, pixel differences) and a pixel-level diff against the export you use today. The label files themselves follow with an evaluation build or a licence.
- Then decideIf it solves a problem you have, pick a commercial structure below, or propose your own. If not, nothing is owed and your files are deleted.
Three ways to buy it
Every team is offered the same three structures. Integration into your export or import path is quoted separately as a fixed fee, so you know the total before you commit.
What is delivered
The same converter under any of the three structures: a licence delivers it as a compiled package, a purchase delivers the full source.
- ConverterPython with a Cython core, delivered compiled under a licence and as full source with a purchase; command line and batch folder mode.
- Input handlingColour-encoded instance PNGs (class and instance IDs in the pixel values), with adapters scoped to your own encoding.
- OutputsLabel rows in the YOLO segmentation format, in the dataset layout the Ultralytics documentation describes, plus SVG and JSON for inspection.
- Stress corpus and testsThe hard cases shown on this page and a synthetic torture set, with expected results.
- Fidelity reportPer-instance rows, holes, parts and pixel differences, measured the way your training loader rasterizes labels.
- Hand-overDocumentation, a walkthrough call for your engineers, and a bug-fix window.
Questions engineers ask first
Can a YOLO-format label really hold a hole?
Not natively. The format is one flat polygon per row. A hole is carried by a zero-width seam: the outline runs in to the hole, around it, and back out along the same path. Where a seam crosses background, the Ultralytics loader draws it as a one-pixel line. The per-instance report that comes with a free sample states, for every instance, exactly how many pixels that adds.
Which inputs does it take?
Today: PNG instance masks with class and instance IDs encoded in the pixel values. Brush or RLE exports, 16-bit instance-ID bitmaps, SAM masks and renderer output with an ID map are adapter work, scoped and priced per buyer.
Our SDK is open source. Can the code live there?
The adapter can: it is written for your repository and delivered under your licence, while the converter itself stays a closed package. To publish the converter as well, buy it outright and release it however you wish.
Can we evaluate it before buying?
Yes, in stages. First the sample results on your own masks. Then, under a short evaluation agreement, an optional 30-day build your engineers can run themselves ($4,500, credited in full against any licence or purchase). A licence delivers the compiled package. The full source comes with an outright purchase, and your engineers can review it under a confidentiality agreement before that purchase closes.
Who owns it, and what comes with the paperwork?
I wrote it and I own it. A licence or assignment comes with a written warranty of authorship, the list of third-party dependencies and their licences, and whatever else your counsel needs to be comfortable.
How long does integration take?
Typically one to two weeks for one input format and one target layout, against acceptance tests agreed before work starts.
Who is behind this
I’m Athanasios Delis, a computer-vision researcher and engineer. I wrote Mask2Label and I am its sole developer and owner.
The converter came out of research on instance segmentation of handwritten characters, where almost every glyph has holes or detached strokes and the standard converters quietly damaged the labels.
Based in Athens, Greece (UTC+2), at D3 Innovation Engineering. Replies within one working day.
Request a free sample
Email five to ten masks (attached, or as a download link), or tell me which export gives you trouble. You can also send an offer or a counter-proposal directly.
athanasiosdelis@d3inneng.com



