Skip to content
Back to skills

Coco Annotation Conversion

ASecurity

Convert per-instance RLE or polygon annotations to COCO JSON format for seamless use with Detectron2 and MMDetection

  • 61 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 12, 2026
datapythongoaws

Security analysis

A100/100

Scanned September 12, 2026

npx -y skills add wenmin-wu/ds-skills --skill coco-annotation-conversion --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Coco Annotation Conversion?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Coco Annotation Conversion
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/wenmin-wu-coco-annotation-conversion/badge)](https://www.skillsdirectory.com/skills/wenmin-wu-coco-annotation-conversion)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: cv-coco-annotation-conversion
description: Convert per-instance RLE or polygon annotations to COCO JSON format for seamless use with Detectron2 and MMDetection
---

# COCO Annotation Conversion

## Overview

Detectron2 and MMDetection expect COCO-format JSON annotations (`images`, `annotations`, `categories` arrays). Competition data often comes as CSV with RLE strings or per-image annotation lists. Converting to COCO JSON enables direct use of `register_coco_instances` and standard data loaders, avoiding custom dataset classes.

## Quick Start

```python
import json
import numpy as np
from pycocotools import mask as mask_util

def build_coco_json(df, image_dir, output_path):
    images, annotations = [], []
    ann_id = 1
    for img_id, (image_name, group) in enumerate(df.groupby('image_id')):
        h, w = group.iloc[0]['height'], group.iloc[0]['width']
        images.append({
            'id': img_id, 'file_name': f'{image_name}.png',
            'height': h, 'width': w
        })
        for _, row in group.iterrows():
            mask = rle_decode(row['annotation'], (h, w))
            rle = mask_util.encode(np.asfortranarray(mask))
            rle['counts'] = rle['counts'].decode('utf-8')
            bbox = mask_util.toBbox(rle).tolist()
            annotations.append({
                'id': ann_id, 'image_id': img_id,
                'category_id': row.get('class_id', 0),
                'segmentation': rle, 'bbox': bbox,
                'bbox_mode': 0, 'area': int(mask.sum()),
                'iscrowd': 0
            })
            ann_id += 1
    coco = {
        'images': images,
        'annotations': annotations,
        'categories': [{'id': 0, 'name': 'cell'}]
    }
    with open(output_path, 'w') as f:
        json.dump(coco, f)

# Register with Detectron2
from detectron2.data.datasets import register_coco_instances
register_coco_instances('train', {}, 'annotations_train.json', 'images/')
```

## Workflow

1. Group annotations by image ID
2. For each annotation: decode mask, re-encode as COCO RLE, compute bbox and area
3. Build the COCO JSON structure with `images`, `annotations`, `categories`
4. Save to disk and register with `register_coco_instances`

## Key Decisions

- **RLE counts as string**: COCO JSON requires `counts` as UTF-8 string, not bytes — decode after encoding
- **bbox_mode**: Detectron2 uses `BoxMode.XYXY_ABS` (mode 0) by default; COCO uses XYWH — check your framework
- **iscrowd**: set to 0 for instance segmentation; 1 for crowd regions to ignore
- **Train/val split**: generate separate JSON files per fold for cross-validation

## References

- [Positive score with Detectron 2/3 - Training](https://www.kaggle.com/code/slawekbiel/positive-score-with-detectron-2-3-training)
- [Sartorius: MMDetection [Train]](https://www.kaggle.com/code/awsaf49/sartorius-mmdetection-train)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…