Data Labeling for Computer Vision (Bounding Boxes, Masks, Polygons, Keypoints)

We design and deploy artificial intelligence systems: from prototype to production-ready solutions. Our team combines expertise in machine learning, data engineering and MLOps to make AI work not in the lab, but in real business.
Showing 1 of 1 servicesAll 1566 services
Data Labeling for Computer Vision (Bounding Boxes, Masks, Polygons, Keypoints)
Simple
ongoing support
FAQ
AI Development Areas
AI Solution Development Stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1212
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    852
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_logo-advance_0.png
    B2B Advance company logo design
    561
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    822

Разметка данных для Computer Vision

Качество разметки определяет потолок точности модели — никакая архитектура не исправит шумные аннотации. При этом разметка CV-данных — не просто «нарисовать рамки»: согласованность между аннотаторами, онтология классов, edge cases, форматы экспорта и QA-процесс занимают столько же времени, сколько сама разметка.

Инструменты и форматы

CVAT — основной инструмент для командной разметки. Self-hosted, поддерживает bbox, polygon, polyline, points, 3D. REST API позволяет автоматизировать создание задач и экспорт.

Label Studio — более гибкий, поддерживает мультимодальную разметку (изображения + текст + аудио), удобен для сложных задач с conditional логикой.

Roboflow — облачный вариант с версионированием датасетов и встроенной аугментацией. Удобен для быстрого старта, менее гибкий для сложных онтологий.

# Автоматизация создания задач в CVAT через API
from cvat_sdk import make_client, models

with make_client(host='http://cvat.company.local') as client:
    client.login(('annotator_api', 'secret'))

    # Создаём задачу с набором labels
    task_spec = models.TaskWriteRequest(
        name='defects_batch_042',
        labels=[
            models.PatchedLabelRequest(
                name='crack',
                color='#ff0000',
                attributes=[
                    models.AttributeRequest(
                        name='severity',
                        mutable=True,
                        input_type='select',
                        values=['minor', 'moderate', 'critical']
                    )
                ]
            ),
            models.PatchedLabelRequest(name='scratch', color='#ff8800'),
            models.PatchedLabelRequest(name='dent',    color='#ffff00'),
        ],
        segment_size=50   # по 50 кадров на сегмент
    )
    task = client.tasks.create(task_spec)

    # Загружаем изображения
    task.upload_files(image_paths)

Inter-annotator agreement и QA

Главная проблема командной разметки — разногласие аннотаторов. IoU 0.65 между двумя разметчиками на мелких объектах — не редкость. Это напрямую влияет на обучение: если два bbox одного объекта расходятся на 20%, модель получает противоречивый сигнал.

import numpy as np
from itertools import combinations

def calculate_iou(box1: list, box2: list) -> float:
    """IoU для двух bbox [x1, y1, x2, y2]"""
    inter_x1 = max(box1[0], box2[0])
    inter_y1 = max(box1[1], box2[1])
    inter_x2 = min(box1[2], box2[2])
    inter_y2 = min(box1[3], box2[3])

    if inter_x2 < inter_x1 or inter_y2 < inter_y1:
        return 0.0

    inter_area = (inter_x2 - inter_x1) * (inter_y2 - inter_y1)
    area1 = (box1[2]-box1[0]) * (box1[3]-box1[1])
    area2 = (box2[2]-box2[0]) * (box2[3]-box2[1])

    return inter_area / (area1 + area2 - inter_area)

def inter_annotator_iou(annotations_by_annotator: dict) -> dict:
    """
    Считаем попарное IoU между аннотаторами.
    Порог для приёмки: mean IoU > 0.80 на совпадающих объектах.
    """
    annotators = list(annotations_by_annotator.keys())
    results = {}

    for a1, a2 in combinations(annotators, 2):
        boxes1 = annotations_by_annotator[a1]
        boxes2 = annotations_by_annotator[a2]

        ious = []
        for b1 in boxes1:
            best_iou = max(
                (calculate_iou(b1, b2) for b2 in boxes2),
                default=0.0
            )
            if best_iou > 0.1:   # только совпадающие объекты
                ious.append(best_iou)

        results[f'{a1}_vs_{a2}'] = {
            'mean_iou': np.mean(ious) if ious else 0.0,
            'n_matched': len(ious)
        }

    return results

Auto-labeling для ускорения разметки

Предварительная авторазметка моделью + ручная корректура — стандарт для больших объёмов. Экономия времени 60–75% при правильном выборе модели.

from ultralytics import YOLO
import json

def auto_label_batch(
    image_paths: list[str],
    model_path: str = 'yolov8l-world.pt',  # или дообученная модель
    conf_threshold: float = 0.5,
    output_format: str = 'yolo'             # 'yolo' | 'coco' | 'cvat'
) -> dict:
    """
    Авторазметка пачки изображений.
    Высокий порог conf=0.5 — берём только уверенные предсказания,
    спорные помечаем для ручной проверки.
    """
    model = YOLO(model_path)
    results = {}

    for img_path in image_paths:
        preds = model.predict(
            img_path, conf=conf_threshold,
            verbose=False
        )[0]

        confident_boxes   = []
        needs_review_boxes = []

        for box in preds.boxes:
            conf = float(box.conf)
            entry = {
                'bbox': box.xyxy[0].tolist(),
                'class_id': int(box.cls),
                'confidence': conf
            }
            if conf > 0.7:
                confident_boxes.append(entry)
            else:
                needs_review_boxes.append(entry)  # отправляем на проверку

        results[img_path] = {
            'auto_labeled': confident_boxes,
            'needs_review': needs_review_boxes,
            'review_required': len(needs_review_boxes) > 0
        }

    return results

Форматы экспорта

Формат Применение Инструмент
YOLO TXT YOLOv5/v8/v11 обучение Ultralytics
COCO JSON Detectron2, MMDetection torchvision
Pascal VOC XML TensorFlow Object Detection API TF OD API
LabelMe JSON Сегментация, polygons LabelMe
CVAT XML Импорт/экспорт CVAT cvat-sdk

Сроки и объёмы

Тип разметки Скорость (человек/час) Стоимость относительно bbox
Bbox (bounding box) 200–400 объектов 1x
Polygon (instance segmentation) 40–80 объектов 4–6x
Semantic segmentation (по пикселям) 2–5 изображений 15–20x
Keypoints (pose) 50–100 персон 3x
Объём датасета Срок с QA
1000 изображений, bbox 1–2 недели
5000 изображений, bbox 3–4 недели
2000 изображений, polygon 3–5 недель