news 2026/2/7 6:14:09

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/2/5 10:07:32

GLM-4-9B-Chat-1M保姆级教程:模型权重校验+SHA256完整性验证

GLM-4-9B-Chat-1M保姆级教程&#xff1a;模型权重校验SHA256完整性验证 1. 为什么校验模型权重这件事不能跳过&#xff1f; 你花两小时下载完 GLM-4-9B-Chat-1M 的模型权重&#xff0c;解压、配置环境、启动 Streamlit&#xff0c;结果一问就崩&#xff0c;或者回答明显胡说八…

作者头像 李华
网站建设 2026/2/7 5:10:55

ClawdBot惊艳案例:手写笔记图片→PDF+多语种翻译一体化生成

ClawdBot惊艳案例&#xff1a;手写笔记图片→PDF多语种翻译一体化生成 你有没有过这样的经历&#xff1a;会议结束&#xff0c;满纸潦草笔记&#xff1b;课堂下课&#xff0c;拍了一堆模糊的手写板书&#xff1b;出差归来&#xff0c;零散的便签贴满笔记本——可这些内容&…

作者头像 李华
网站建设 2026/2/4 8:20:58

ccmusic-database算力优化部署:VGG19_BN+CQT模型TensorRT加速实践指南

ccmusic-database算力优化部署&#xff1a;VGG19_BNCQT模型TensorRT加速实践指南 1. 为什么需要对音乐流派分类模型做TensorRT加速 你有没有试过在本地跑一个466MB的VGG19_BN模型&#xff1f;打开网页界面&#xff0c;上传一首30秒的音频&#xff0c;等上5到8秒才看到结果——…

作者头像 李华
网站建设 2026/2/6 8:45:39

轻量型服务器和云服务器的区别

轻量型服务器与云服务器&#xff08;CVM&#xff09;的核心差异&#xff0c;本质是“简化易用”与“灵活专业”的定位区分&#xff0c;二者在适用场景、配置弹性、运维难度等维度差异显著&#xff0c;具体区别如下&#xff1a; 轻量型服务器主打“极简运维、开箱即用”&#…

作者头像 李华
网站建设 2026/2/6 7:42:51

GLM-4-9B-Chat-1M开发者案例:API集成实现智能搜索

GLM-4-9B-Chat-1M开发者案例&#xff1a;API集成实现智能搜索 1. 为什么你需要一个“能读完200万字”的搜索助手&#xff1f; 你有没有遇到过这样的场景&#xff1a; 法务同事发来一份87页的并购协议PDF&#xff0c;要求30分钟内找出所有违约责任条款&#xff1b;运营团队甩…

作者头像 李华