path: ./m2cai16-tool-locations train: images/train val: images/val nc: 16 names: ['grasper','scissors','hook','clipper','irrigator','specimen_bag','bipolar','hook_electrode','trocars','stapler','suction','clip_applier','vessel_sealer','ligasure','ultrasonic','other'] This guide gives you a production‑ready starting point for loading, visualizing, converting, and training on the dataset. Adjust class names and annotation JSON structure based on your exact dataset version.

import json import os from PIL import Image import torch from torch.utils.data import Dataset from torchvision.ops import box_convert class M2CAI16ToolLocations(Dataset): """Dataset for m2cai16-tool-locations bounding box annotations."""

# 16 tool classes (example; adjust to your annotation file) CLASSES = [ 'background', 'grasper', 'scissors', 'hook', 'clipper', 'irrigator', 'specimen_bag', 'bipolar', 'hook_electrode', 'trocars', 'stapler', 'suction', 'clip_applier', 'vessel_sealer', 'ligasure', 'ultrasonic', 'other' ]

def __init__(self, root_dir, transform=None): self.root_dir = root_dir self.transform = transform self.samples = [] # Collect all (frame_path, annotation_path) pairs ann_dir = os.path.join(root_dir, 'annotations') for ann_file in os.listdir(ann_dir): if not ann_file.endswith('.json'): continue ann_path = os.path.join(ann_dir, ann_file) video_id = ann_file.replace('.json', '') frame_dir = os.path.join(root_dir, 'frames', video_id) with open(ann_path, 'r') as f: annotations = json.load(f) for frame_name, boxes_info in annotations.items(): frame_path = os.path.join(frame_dir, frame_name) if os.path.exists(frame_path): self.samples.append((frame_path, boxes_info))

m2cai16-tool-locations/ annotations/ video01.json # or .xml / .txt video02.json frames/ video01/ frame_000001.jpg ... Here’s a robust parser using and torchvision :

def __len__(self): return len(self.samples)

def __getitem__(self, idx): img_path, ann = self.samples[idx] image = Image.open(img_path).convert('RGB') # Parse annotations: list of [x1, y1, x2, y2, class_id] boxes = [] labels = [] for obj in ann.get('objects', []): x1, y1, x2, y2 = obj['bbox'] # absolute pixel coords label = self.CLASSES.index(obj['class_name']) boxes.append([x1, y1, x2, y2]) labels.append(label) boxes = torch.as_tensor(boxes, dtype=torch.float32) labels = torch.as_tensor(labels, dtype=torch.int64) image_id = torch.tensor([idx]) area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0]) iscrowd = torch.zeros((len(boxes),), dtype=torch.int64) target = { 'boxes': boxes, 'labels': labels, 'image_id': image_id, 'area': area, 'iscrowd': iscrowd } if self.transform: image, target = self.transform(image, target) return image, target Use matplotlib and torchvision.utils.draw_bounding_boxes :