news 2026/4/18 9:47:19

coco128-seg分割yolo格式转coco2017.json格式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
coco128-seg分割yolo格式转coco2017.json格式

将coco128-seg分割数据集yolo格式转换为coco2017.json格式,方便运行cocoapi接口测试:

保存为一个json文件。

labels.txt 是有80个类别txt信息

注意coco128-seg 中有两张图片和Label错误要挑选出来:

000000000250.jpg

000000000508.jpg

000000000656.txt

000000000659.txt

#!/usr/bin/env python3 """ Convert YOLO format segmentation data to COCO JSON format. Reads images and labels from coco128-seg folder and converts them to a single JSON file. """ import json import os from pathlib import Path from PIL import Image import numpy as np def load_labels_txt(labels_file): """Load category names from labels.txt file.""" with open(labels_file, 'r') as f: categories = [line.strip() for line in f.readlines()] return categories def yolo_to_coco_polygon(yolo_coords, img_width, img_height): """ Convert YOLO normalized polygon coordinates to COCO absolute coordinates. YOLO format: normalized coordinates (0-1) as [x1, y1, x2, y2, ...] COCO format: absolute pixel coordinates as [[x1, y1, x2, y2, ...]] """ coords = np.array(yolo_coords, dtype=np.float32) # Reshape to (N, 2) where N is number of points coords = coords.reshape(-1, 2) # Convert normalized to absolute coords[:, 0] *= img_width coords[:, 1] *= img_height # Flatten back to [x1, y1, x2, y2, ...] polygon = coords.flatten().tolist() return [polygon] def calculate_bbox_from_polygon(polygon): """ Calculate bounding box from polygon coordinates. polygon: [x1, y1, x2, y2, ...] (flattened) Returns: [x, y, width, height] (COCO bbox format) """ coords = np.array(polygon).reshape(-1, 2) x_min = float(np.min(coords[:, 0])) y_min = float(np.min(coords[:, 1])) x_max = float(np.max(coords[:, 0])) y_max = float(np.max(coords[:, 1])) return [x_min, y_min, x_max - x_min, y_max - y_min] def calculate_area_from_polygon(polygon): """ Calculate area from polygon using shoelace formula. polygon: [x1, y1, x2, y2, ...] (flattened) """ coords = np.array(polygon).reshape(-1, 2) x = coords[:, 0] y = coords[:, 1] area = 0.5 * np.abs(np.dot(x, np.roll(y, 1)) - np.dot(y, np.roll(x, 1))) return float(area) def convert_yolo_to_coco(yolo_dir, labels_file, output_json): """ Convert YOLO format segmentation data to COCO JSON format. Args: yolo_dir: Path to coco128-seg directory labels_file: Path to labels.txt file output_json: Path to output JSON file """ # Load category names category_names = load_labels_txt(labels_file) # Create categories list for COCO format # COCO uses 1-based category IDs, YOLO uses 0-based categories = [] for idx, name in enumerate(category_names): category_id = idx + 1 # Convert to 1-based for COCO # Determine supercategory (simplified mapping) if idx == 0: supercategory = "person" elif 1 <= idx <= 8: supercategory = "vehicle" elif 9 <= idx <= 13: supercategory = "outdoor" elif 14 <= idx <= 24: supercategory = "animal" elif 25 <= idx <= 32: supercategory = "accessory" elif 33 <= idx <= 42: supercategory = "sports" elif 43 <= idx <= 50: supercategory = "kitchen" elif 51 <= idx <= 60: supercategory = "food" elif 61 <= idx <= 70: supercategory = "furniture" elif 71 <= idx <= 77: supercategory = "electronic" elif 78 <= idx <= 82: supercategory = "appliance" else: supercategory = "indoor" categories.append({ "id": category_id, "name": name, "supercategory": supercategory }) # Paths images_dir = Path(yolo_dir) / "images" / "train2017" labels_dir = Path(yolo_dir) / "labels" / "train2017" # Collect all image files image_files = sorted(images_dir.glob("*.jpg")) # Check for missing labels images_without_labels = [] labels_without_images = [] valid_pairs = [] for img_path in image_files: label_path = labels_dir / (img_path.stem + ".txt") if label_path.exists(): valid_pairs.append((img_path, label_path)) else: images_without_labels.append(img_path.name) # Check for labels without images label_files = sorted(labels_dir.glob("*.txt")) for label_path in label_files: img_path = images_dir / (label_path.stem + ".jpg") if not img_path.exists(): labels_without_images.append(label_path.name) print(f"统计信息:") print(f" 总图片数: {len(image_files)}") print(f" 总标签数: {len(label_files)}") print(f" 有效配对: {len(valid_pairs)}") if images_without_labels: print(f" 没有标签的图片 ({len(images_without_labels)} 张): {', '.join(images_without_labels)}") if labels_without_images: print(f" 没有图片的标签 ({len(labels_without_images)} 个): {', '.join(labels_without_images)}") print() # Initialize COCO data structure coco_data = { "info": { "description": "COCO 2017 Dataset (converted from YOLO)", "url": "", "version": "1.0", "year": 2017, "contributor": "", "date_created": "2017/09/01" }, "licenses": [], "images": [], "annotations": [], "categories": categories } # Counters image_id = 1 annotation_id = 1 # Process each valid image-label pair for img_path, label_path in valid_pairs: # Get image dimensions try: img = Image.open(img_path) width, height = img.size except Exception as e: print(f"Warning: Could not open image {img_path}: {e}") continue # Add image entry coco_data["images"].append({ "id": image_id, "file_name": img_path.name, "width": width, "height": height, "license": 0, "coco_url": "", "flickr_url": "", "date_captured": "" }) # Read and process labels (label_path is already verified to exist) with open(label_path, 'r') as f: lines = f.readlines() for line in lines: line = line.strip() if not line: continue parts = line.split() if len(parts) < 3: continue try: yolo_class_id = int(parts[0]) # Convert YOLO 0-based class_id to COCO 1-based category_id category_id = yolo_class_id + 1 # Remaining parts are normalized coordinates yolo_coords = [float(x) for x in parts[1:]] if len(yolo_coords) < 6: # Need at least 3 points (x, y pairs) continue # Convert YOLO polygon to COCO format segmentation = yolo_to_coco_polygon(yolo_coords, width, height) # Calculate bounding box bbox = calculate_bbox_from_polygon(segmentation[0]) # Calculate area area = calculate_area_from_polygon(segmentation[0]) # Add annotation coco_data["annotations"].append({ "id": annotation_id, "image_id": image_id, "category_id": category_id, "segmentation": segmentation, "area": area, "bbox": bbox, "iscrowd": 0 }) annotation_id += 1 except (ValueError, IndexError) as e: print(f"Warning: Error processing line in {label_path}: {line[:50]}... Error: {e}") continue image_id += 1 # Write output JSON with open(output_json, 'w') as f: json.dump(coco_data, f, indent=2) print(f"Conversion complete!") print(f"Total images: {len(coco_data['images'])}") print(f"Total annotations: {len(coco_data['annotations'])}") print(f"Total categories: {len(coco_data['categories'])}") print(f"Output saved to: {output_json}") if __name__ == "__main__": # Set paths yolo_dir = "coco128-seg" labels_file = "labels.txt" output_json = "coco128_seg.json" # Convert convert_yolo_to_coco(yolo_dir, labels_file, output_json)
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 3:43:16

A音色+B情感?IndexTTS 2.0实现创意语音自由搭配

A音色B情感&#xff1f;IndexTTS 2.0实现创意语音自由搭配 你有没有试过——录了一段自己温柔说话的音频&#xff0c;却想让它突然“愤怒地质问”&#xff1b;或者手头只有同事一段冷静播报的录音&#xff0c;却需要给短视频配上活泼俏皮的旁白&#xff1f;过去&#xff0c;这…

作者头像 李华
网站建设 2026/4/17 19:21:15

STM32智能电表设计:电压电流功率因数实时监测与远程控制

1. 智能电表系统架构设计 做智能电表开发这些年&#xff0c;我发现系统架构设计直接影响最终测量精度和稳定性。一个典型的STM32智能电表系统包含三大核心模块&#xff1a;信号采集层、数据处理层和通信控制层。 信号采集层就像电表的"感官系统"&#xff0c;我用TV…

作者头像 李华
网站建设 2026/4/18 5:34:15

SGLang在智能客服中的应用,响应速度翻倍实测

SGLang在智能客服中的应用&#xff0c;响应速度翻倍实测 1. 为什么智能客服卡在“慢”字上&#xff1f; 你有没有遇到过这样的场景&#xff1a;用户刚问完“订单怎么还没发货”&#xff0c;客服系统却要等3秒才开始打字&#xff1b;高峰期50个用户同时提问&#xff0c;后端GP…

作者头像 李华
网站建设 2026/4/18 6:57:33

DDColor效果惊艳展示:百年黑白老照片重焕生机的真实着色案例集

DDColor效果惊艳展示&#xff1a;百年黑白老照片重焕生机的真实着色案例集 1. 这不是“调色”&#xff0c;是让历史重新呼吸 你有没有翻过家里的老相册&#xff1f;泛黄的纸页里&#xff0c;祖父穿着笔挺的中山装站在照相馆布景前&#xff0c;祖母挽着发髻&#xff0c;眼神安…

作者头像 李华
网站建设 2026/4/17 19:25:06

如何让大模型‘认主人’?Qwen2.5-7B身份注入教程

如何让大模型‘认主人’&#xff1f;Qwen2.5-7B身份注入教程 你有没有试过问一个大模型&#xff1a;“你是谁&#xff1f;” 它不假思索地回答&#xff1a;“我是阿里云研发的超大规模语言模型……” 那一刻&#xff0c;你突然意识到&#xff1a;它很聪明&#xff0c;但不认识…

作者头像 李华