1. 从一次标注返工说起COCO 子集筛选与 AI 辅助标注如果你正在做目标检测或实例分割大概率绕不开 COCO 数据集。它包含 33 万张图像、250 万个标注、80 个常见类别是计算机视觉里最常用的公开数据之一。但真正上手后你会发现全量数据动辄几十 GB训练时根本用不上全部类别。更现实的做法是用 Python 读取 COCO 标注按类别筛选出需要的子集再把这个子集交给 AI 辅助标注脚本做预标注或质量复核。我试过直接拿全量 instances_train2017.json 跑脚本光加载就吃掉好几 GB 内存筛选逻辑还没写完机器就开始交换分区了。后来改成先解析标注、按类别过滤、只导出需要的图像和标注整个流程轻量很多。这篇就聚焦这个场景用 pycocotools 读取 COCO 标注按类别筛选并导出子集同时把 TaoToken 作为统一 Key/API 通道接入 AI 辅助标注脚本让筛选、预标注、核对计数形成一条可复制的流水线。适合谁看已经装好 Python 环境、想快速上手 COCO 子集操作的同学手里有标注脚本、想统一模型调用入口的开发者以及需要把筛选导出和AI 预标注串起来的工程实践者。下面从环境准备开始一步步给出可复制的配置和代码。2. 前置准备pycocotools 安装与 TaoToken 统一 Key2.1 安装 COCO Python APICOCO 官方提供了 pycocotools安装很直接pip install pycocotools如果你用的是 Windows可能会遇到编译问题可以改用预编译版本pip install pycocotools-windows安装完成后验证一下能否正常导入from pycocotools.coco import COCO print(pycocotools ok)2.2 为什么用 TaoToken 做统一 KeyAI 辅助标注脚本通常要调用模型做预标注比如让视觉模型给出候选框或者让语言模型帮忙生成类别描述。如果每个脚本都单独配一套 Key管理起来很乱。TaoToken 提供统一 Key/API 通道把模型调用收敛到一个入口脚本里只维护一份配置即可。官网地址https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentAPI 地址https://taotoken.net/api你需要在控制台创建一个 API Key然后把它写进配置文件。控制台入口https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewriteAPI Keys 管理页https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite2.3 config.toml 骨架在项目根目录建一个 config.toml把数据路径和 TaoToken 配置放进去[data] root /data/coco ann_file /data/coco/annotations/instances_train2017.json image_dir /data/coco/train2017 output_dir /data/coco/subset_person_car [filter] categories [person, car, bicycle] min_bbox_area 1024 [taotoken] api_base https://taotoken.net/api api_key sk-你的Key model gpt-4o-mini timeout 60这里 categories 就是你要筛选的类别min_bbox_area 用来过滤太小的框避免噪声。TaoToken 部分统一管理模型调用后面 AI 辅助标注脚本直接读这段配置。3. 可复制配置读取 COCO 标注并按类别筛选导出3.1 加载标注并查看类别先写一个脚本读取标注文件确认类别名称和 ID 的映射关系import json from pycocotools.coco import COCO ann_file /data/coco/annotations/instances_train2017.json coco COCO(ann_file) cats coco.loadCats(coco.getCatIds()) for c in cats[:10]: print(c[id], c[name])COCO 的类别 ID 不是连续的比如 person 是 1bicycle 是 2car 是 3中间有些 ID 被跳过。所以筛选时要用类别名称反查 ID而不是硬编码。3.2 按类别筛选图像和标注核心逻辑是先拿到目标类别的 catIds再用 getImgIds 找出包含这些类别的图像最后用 getAnnIds 取出对应标注。import os import shutil from pycocotools.coco import COCO def filter_coco(ann_file, image_dir, output_dir, target_cats, min_area0): coco COCO(ann_file) cat_ids coco.getCatIds(catNmstarget_cats) img_ids coco.getImgIds(catIdscat_ids) os.makedirs(os.path.join(output_dir, images), exist_okTrue) new_ann {images: [], annotations: [], categories: []} ann_id 1 for img_id in img_ids: img_info coco.loadImgs(img_id)[0] ann_ids coco.getAnnIds(imgIdsimg_id, catIdscat_ids) anns coco.loadAnns(ann_ids) valid_anns [a for a in anns if a[area] min_area] if not valid_anns: continue src os.path.join(image_dir, img_info[file_name]) dst os.path.join(output_dir, images, img_info[file_name]) if os.path.exists(src): shutil.copy(src, dst) new_ann[images].append(img_info) for a in valid_anns: a dict(a) a[id] ann_id ann_id 1 new_ann[annotations].append(a) new_ann[categories] coco.loadCats(cat_ids) out_json os.path.join(output_dir, annotations.json) with open(out_json, w) as f: json.dump(new_ann, f) return new_ann if __name__ __main__: result filter_coco( ann_file/data/coco/annotations/instances_train2017.json, image_dir/data/coco/train2017, output_dir/data/coco/subset_person_car, target_cats[person, car, bicycle], min_area1024 ) print(images:, len(result[images])) print(annotations:, len(result[annotations]))这段代码做了三件事筛选类别、过滤小框、复制图像并生成新的标注 JSON。导出后的子集可以直接被 pycocotools 重新加载格式和原版一致。3.3 把 TaoToken 接入 AI 辅助标注脚本筛选出子集后下一步是让 AI 帮忙做预标注或复核。下面是一个调用示例用 TaoToken 的统一 API 通道请求模型对筛选结果做类别描述生成import toml import requests cfg toml.load(config.toml) tk cfg[taotoken] def ask_model(prompt): headers { Authorization: fBearer {tk[api_key]}, Content-Type: application/json } payload { model: tk[model], messages: [ {role: system, content: 你是标注助手输出简洁的类别说明。}, {role: user, content: prompt} ] } resp requests.post( f{tk[api_base]}/v1/chat/completions, headersheaders, jsonpayload, timeouttk[timeout] ) resp.raise_for_status() return resp.json()[choices][0][message][content] if __name__ __main__: print(ask_model(person、car、bicycle 三个类别在标注时各有什么易混淆点))这样你的标注脚本只需要读 config.toml就能统一走 TaoToken 通道不用在每个脚本里重复配置。4. 验证请求跑通筛选导出并核对类别计数4.1 重新加载导出结果导出完成后用 pycocotools 重新加载子集标注确认格式没问题from pycocotools.coco import COCO sub COCO(/data/coco/subset_person_car/annotations.json) print(images:, len(sub.imgs)) print(annotations:, len(sub.anns)) print(categories:, [c[name] for c in sub.loadCats(sub.getCatIds())])如果 categories 只包含 person、car、bicycle说明筛选生效。4.2 核对每个类别的标注计数这一步很关键避免筛选逻辑漏掉或多算from collections import Counter cat_counter Counter() for ann in sub.anns.values(): cat_counter[ann[category_id]] 1 id2name {c[id]: c[name] for c in sub.loadCats(sub.getCatIds())} for cid, cnt in cat_counter.items(): print(id2name[cid], cnt)对照原数据集里这三个类别的总数确认子集计数合理。如果某个类别计数为 0检查 target_cats 拼写和 min_area 阈值。4.3 验证 TaoToken 通道单独跑一次模型调用确认 Key 和 API 地址可用curl -X POST https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer sk-你的Key \ -H Content-Type: application/json \ -d {model:gpt-4o-mini,messages:[{role:user,content:ping}]}返回正常 JSON 就说明通道没问题。如果要在网页端直接验证模型可以用模型对话入口https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite5. 本篇常见错排查5.1 pycocotools 导入报错常见于 Windows 缺少 C 编译环境。解决办法是装 pycocotools-windows或者用 conda 安装conda install -c conda-forge pycocotools5.2 类别筛选后计数为 0先确认类别名称拼写COCO 里是 person 不是 Person。再检查 min_area 是否设得太大把有效框全过滤掉了。可以先把 min_area 设为 0 跑一遍看计数是否正常。5.3 图像复制路径不对COCO 的 file_name 是相对路径比如 000000000009.jpg。拼接时要用 image_dir file_name不要多加子目录。如果原图不在本地复制会静默跳过导致 images 列表和实际文件不一致。5.4 TaoToken 请求 401检查 config.toml 里的 api_key 是否带了多余空格以及 api_base 是否写成 https://taotoken.net/api。注意 API 地址不带 UTM 参数直接写基础路径即可。如果 Key 刚创建稍等几秒再试。5.5 导出 JSON 加载失败多半是 json.dump 时遇到了 numpy 类型。COCO 标注里的 area、bbox 可能是 numpy.float64需要转成 Python 原生类型import numpy as np def to_native(obj): if isinstance(obj, dict): return {k: to_native(v) for k, v in obj.items()} if isinstance(obj, list): return [to_native(v) for v in obj] if isinstance(obj, (np.integer,)): return int(obj) if isinstance(obj, (np.floating,)): return float(obj) return obj在 dump 之前套一层 to_native 即可。6. 把筛选导出和 AI 预标注串成流水线到这里你已经有了一个可复制的流程读 COCO 标注、按类别筛选、导出子集、核对计数再用 TaoToken 统一 Key 接入 AI 辅助标注脚本。实际项目里我会把 filter_coco 和 ask_model 封装成两个模块主流程读 config.toml先跑筛选再对每个子集图像请求预标注建议最后人工复核。如果你要长期跑编码类或 Agent 类任务可以考虑 Coding Plan把模型调用额度集中管理https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite接入文档在这里遇到参数问题可以对照查https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite一个实用技巧筛选时先把 target_cats 和 min_area 写进 config.toml不要硬编码在脚本里。这样换类别、调阈值都不用改代码直接改配置重跑。另外导出目录建议带上类别名和阈值比如 subset_person_car_a1024方便回溯是哪次筛选的结果。