信息速览
INFOBOX
| 数据集名称 | Cholec80 |
| 英文全称 | Cholec80: A Surgical Workflow Dataset for Laparoscopic Cholecystectomy |
| 别名 / 简称 | Cholec80、Surgical Workflow Dataset、EndoNet Dataset |
| 疾病分类 | DC10 胆囊炎 / DC11 胆石症 / DC12 胆道运动障碍(ICD-11 胆囊与胆管疾病) |
| SNOMED CT | 89734007 Laparoscopic cholecystectomy / 235934003 Cholecystitis / 787844009 Cholelithiasis / 39816001 Surgical procedure margin (phase transition) |
| 数据模态 | 影像(腹腔镜内窥镜视频,RGB) |
| AI 任务类型 | 时序动作分割(手术阶段识别)、多标签分类(器械存在检测)、多任务学习、剩余手术时长预测 |
| 样本总数 | 80 例腹腔镜胆囊切除术视频(约 184,500 帧 @ 1 fps) |
| 数据大小 | ~50 GB(估计,1 fps 下采样 PNG 帧) |
| 数据格式 | PNG(帧,854×480)/ TXT(阶段与器械标注)/ MP4(原始视频) |
| 许可证 | CC-BY-NC-SA 4.0(非商业、相同方式共享) |
| 访问级别 | 注册后开放(需在线填写申请表) |
| DUO 标签 | HMB, NPUNCU |
| 语言 | 不适用(视频与数值标注,无文本) |
| 首发日期 | 2016-02-09(arXiv 预印本)/ 2017-01(IEEE TMI 正式发表) |
| 最后更新 | 2017-01(IEEE TMI 正式版,无后续版本更新) |
| 发布机构 | CAMMA Research Group, University of Strasbourg(法国斯特拉斯堡大学,ICube 实验室 / IHU Strasbourg / IRCAD) |
| 官方主页 | https://camma.unistra.fr/datasets/ |
| 下载地址 | https://camma.unistra.fr/datasets/(需填写申请表) |
| DOI | 10.1109/TMI.2016.2593957 |
| 引用次数 | 1,000+(Google Scholar,截至 2026-08) |
| AI 就绪度评分 | ⭐⭐⭐⭐(4/5)— 标准 40:40 划分 + 7 阶段逐帧标注 + 7 器械二值标注 + 官方 GitHub 代码;扣分项:非商业许可、单一标注者无 IAA、无患者人口统计数据 |
| 页面状态 | published |
§0 E-E-A-T 信任声明与免责声明
医学审核者:[千方病案医学编辑部]交叉审核:§2 医学背景(ICD-11 映射、胆囊切除术临床流程、7 阶段定义、Calot 三角解剖)、§7 偏倚分析。
数据工程审核者:[千方病案医学编辑部交叉审核] 医疗 AI 数据工程师,审核范围:§4 DAIMS 数据字典、§5 数据划分策略、§6 预处理 Pipeline 和坑点。
审核日期:2026-08-07
医疗免责声明:本页面提供的医学信息仅供研究和教育目的,不构成医疗建议、诊断或治疗方案。数据集的医学描述基于公开发表的文献,未经逐一临床验证。任何基于该数据集训练的 AI 模型在应用于临床决策前,必须经过独立的临床验证和监管审批。
技术免责声明:本页面的代码示例、预处理建议和基准性能数据基于公开资料整理,不保证在特定环境下的准确性和适用性。使用者应自行验证代码安全性和数据预处理流程的正确性。千方病案医数集不对因使用本页面信息而导致的任何直接或间接损失承担责任。
数据使用合规:使用本页面描述的数据集前,请务必阅读并遵守数据集原始许可协议。Cholec80 采用 CC-BY-NC-SA 4.0 许可证,禁止商业用途。DUO 标签仅供参考,具体使用限制以数据集官方协议为准。
§1 数据集概览(Overview)
§1.0 📌 30 秒速览(Executive Summary)
Cholec80 是法国斯特拉斯堡大学 CAMMA 研究组于 2016 年发布的腹腔镜胆囊切除术视频数据集,包含 80 例由 13 位外科医生执行的手术视频,每帧标注了 7 个手术阶段和 7 种手术器械的存在性,是计算手术学领域的奠基性数据集。
它的独特价值在于首次以 CNN 多任务学习范式定义了"手术阶段识别 + 器械存在检测"双任务基准——EndoNet 架构同时学习视觉特征和工具-阶段关联,开创了深度学习在腹腔镜视频分析中的应用先河。原始论文已被引用 1,000 余次,衍生出 CholecSeg8K、CholecT50、CholecInstanceSeg 等扩展数据集,形成完整的"Cholec 生态"。
你可以用它来:训练一个手术阶段自动识别模型实现术中实时辅助、研究时序模型(TCN/LSTM/Transformer)在长视频中的建模能力、或者基于器械-阶段关联开展多任务学习研究。
§1.1 摘要
Cholec80 由斯特拉斯堡大学 ICube 实验室的 CAMMA 研究组构建,与斯特拉斯堡大学医院(University Hospital of Strasbourg)、IHU Strasbourg 和 IRCAD 合作采集。数据集包含 80 例腹腔镜胆囊切除术(Laparoscopic Cholecystectomy, LC)视频,由 13 位外科医生主刀完成。视频以 25 fps 采集,下采样至 1 fps 进行处理,平均时长约 38.4 分钟(2,306 秒)。
核心创新在于:(1) 多任务标注体系——阶段标注以 25 fps 逐帧进行(7 个手术阶段),器械标注以 1 fps 进行(7 种器械的二值存在性),由一位资深外科医生定义和标注;(2) EndoNet 架构——基于 AlexNet 的多任务 CNN,同时预测阶段和器械存在,第一阶段输出通过 HMM 时序平滑后获得最终阶段预测;(3) 工具-阶段语义关联——7 种器械与 7 个阶段存在强关联(如 P3 Clipping and Cut 阶段必然出现 Clipper),为多任务学习提供天然监督信号。
数据集以 CC-BY-NC-SA 4.0 许可证发布,需在线填写申请表获取。标准划分为 40 训练 / 40 测试(video01-40 / video41-80),该划分已成为领域事实标准。
§1.2 战略价值分析
计算手术学范式定义维度:Cholec80 不仅是第一个大规模公开的腹腔镜手术视频数据集,更重要的是它定义了计算手术学的核心问题框架——"手术阶段识别"和"器械存在检测"成为后续 10 年该领域最活跃的两个研究方向。EndoNet 论文提出的"CNN 特征提取 + 时序模型 + 多任务学习"三段式范式,被 TMRNet、Trans-SVNet、LoViT、Surgformer 等几乎所有后续 SOTA 方法继承。
Cholec 生态系统维度:Cholec80 作为"母数据集"催生了一系列衍生数据集,形成完整的手术 AI 研究生态。CholecSeg8K(8,080 帧语义分割)扩展了空间理解维度,CholecT50/CholecT45(手术动作三元组标注)扩展了动作理解粒度,Cholec80-Boxes(边界框标注)补充了器械定位能力,CholecInstanceSeg(实例分割)提供了最精细的器械分割标注。这些数据集共享 Cholec80 的视频源,但标注粒度和任务类型互补,使研究者可以在同一视频素材上开展从粗粒度(阶段)到细粒度(动作三元组、实例分割)的多层次研究。
§1.3 同类数据集横向对比
| 数据集 | 样本量 | 模态 | 标注方式 | 核心差异化 |
|---|---|---|---|---|
| Cholec80 | 80 视频(~184,500 帧) | 腹腔镜视频 | 7 阶段 + 7 器械(二值) | 计算手术学奠基,多任务基准 |
| M2CAI16-workflow | 41 视频(15 train + 26 test) | 腹腔镜视频 | 8 阶段 | MICCAI 2016 挑战赛子集 |
| AutoLaparo | 21 视频(10 train + 5 val + 6 test) | 腹腔镜视频 | 10 阶段 | 更长手术视频,更细粒度阶段 |
| CATARACTS | 50 视频 | 白内障手术视频 | 21 器械 + 12 阶段 | 不同术种(眼科) |
| GraSP | 17 视频 | 腹腔镜视频 | 器械分割 | 空间分割标注 |
§1.4 版本演进时间轴
| 时间 | 事件 |
|---|---|
| 2016-02 | arXiv 预印本发布(arXiv:1602.03012),EndoNet 架构与 Cholec80 数据集首次公开 |
| 2016-10 | M2CAI 2016 挑战赛(MICCAI 卫星活动),使用 Cholec80 子集作为 workflow 和 tool 检测挑战赛数据 |
| 2017-01 | IEEE Transactions on Medical Imaging (TMI) 正式发表,DOI: 10.1109/TMI.2016.2593957 |
| 2019 | RSDNet(Twinanda et al., IEEE TMI)基于 Cholec80 预测剩余手术时长 |
| 2020 | CholecSeg8K 发布(Hong et al., arXiv:2012.12453),8,080 帧语义分割标注 |
| 2021 | CholecTriplet2021 挑战赛,基于 Cholec80 的动作三元组标注 |
| 2022 | CholecT45 公开发布(Nwoye et al., Medical Image Analysis),手术动作三元组数据集 |
| 2023 | CholecT50 公开发布,扩展至 50 个视频序列 |
| 2024 | CholecInstanceSeg 发布(arXiv:2406.16039),41.9k 帧器械实例分割标注 |
§1.5 典型 AI 应用场景
- 术中手术阶段实时识别:基于内窥镜视频流自动判断当前手术阶段,为手术室调度系统和术中辅助决策提供上下文信息
- 器械存在检测:自动检测当前帧中出现的手术器械,辅助器械清点、手术安全核查和自动化流程监控
- 剩余手术时长预测:基于已完成的手术阶段序列,预测手术剩余时间,优化手术室排班和资源调度
- 多任务学习研究:利用阶段-器械天然关联,研究多任务共享表示学习的最佳架构设计
- 时序建模基准:作为长视频时序建模的标准测试床,评估 TCN、LSTM、Transformer 等时序架构在手术场景中的表现
§2 医学背景(Medical Context)
§2.1 ICD-11 疾病编码
| 数据集关联疾病 | ICD-11 编码 | 中文名称 |
|---|---|---|
| 胆囊炎 | DC10 | 胆囊炎 |
| 胆石症 | DC11 | 胆石症 |
| 胆囊息肉/肿瘤 | DB22.0 | 胆囊良性肿瘤 |
§2.1b SNOMED CT 映射
| 数据集标签 | ICD-11 | SNOMED CT | SNOMED CT 术语 |
|---|---|---|---|
| Laparoscopic Cholecystectomy | — | 89734007 | Laparoscopic cholecystectomy (procedure) |
| Cholecystitis | DC10 | 235934003 | Cholecystitis (disorder) |
| Cholelithiasis | DC11 | 787844009 | Cholelithiasis (disorder) |
| Calot Triangle | — | 3573002 | Calot’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’'s triangle (body structure) |
| Cystic Duct | — | 53514002 | Cystic duct (body structure) |
| Gallbladder | — | 28231008 | Gallbladder (body structure) |
§2.2 疾病简介与流行病学
胆囊切除术是治疗胆囊结石(胆石症)和胆囊炎的标准外科手术。胆石症在全球成人中的患病率约为 10-15%,女性发病率高于男性。腹腔镜胆囊切除术(Laparoscopic Cholecystectomy, LC)自 1987 年首次实施以来,已成为胆囊切除的金标准术式,占全部胆囊切除术的 90% 以上。LC 具有创伤小、恢复快、住院时间短等优势,但存在胆管损伤(Bile Duct Injury, BDI)等严重并发症风险(发生率 0.2-0.7%),因此术中实时阶段识别和辅助预警系统具有重要的临床价值。
§2.3 临床任务定义
| 任务类型 | 临床意义 | AI 任务边界 |
|---|---|---|
| 手术阶段识别 | 术中上下文感知、手术室调度优化、自动化手术报告 | 7 类时序分割,逐帧分类 |
| 器械存在检测 | 器械清点核查、手术安全监控、自动化流程记录 | 7 类多标签二值分类 |
| 剩余手术时长预测 | 手术室排班优化、资源调度 | 回归预测 |
§2.4 患者人群特征
| 维度 | 特征 |
|---|---|
| 数据来源 | 斯特拉斯堡大学医院(University Hospital of Strasbourg),法国 |
| 采集时间 | 2014-2016(估计,基于发布时间推断) |
| 年龄分布 | 未公开(数据集未包含患者人口统计信息) |
| 性别比例 | 未公开 |
| 种族分布 | 未公开 |
| 就医类型 | 住院手术( elective laparoscopic cholecystectomy) |
| 术者数量 | 13 位外科医生 |
§2.5 临床意义
腹腔镜胆囊切除术虽然是标准化程度较高的手术,但手术流程仍存在显著的术者间变异性和阶段持续时间差异(如 P2 Calot Triangle Dissection 阶段标准差达 663 秒,约为均值的 71%)。自动手术阶段识别可以:(1) 为手术室管理系统提供实时手术进度信息,优化接台安排;(2) 为初级外科医生提供术中导航和阶段切换提示;(3) 自动生成手术报告的时间轴标注;(4) 在教学场景中辅助手术录像的索引和检索。
§2.6 金标准
| 数据划分 | 标注方式 | 标注者 | 金标准性质 |
|---|---|---|---|
| Train(video01-40) | 阶段逐帧标注(25 fps)+ 器械存在标注(1 fps) | 一位资深外科医生(斯特拉斯堡大学医院) | 参考标准(单一标注者) |
| Test(video41-80) | 同上 | 同上 | 参考标准(单一标注者) |
注意:Cholec80 仅有一位标注者,无标注者间一致性(Inter-Annotator Agreement, IAA)数据。阶段标注以 25 fps 进行(即原始视频每一帧),器械标注以 1 fps 进行(每秒一帧)。器械存在判定标准:器械尖端至少一半可见于画面中。
§3 数据集规格(Specifications)
§3.0 版本抉择矩阵
| 你的需求 | 推荐版本/数据集 | 大小 | 理由 |
|---|---|---|---|
| 手术阶段识别/器械检测(标准基准) | Cholec80 | ~50 GB | 80 视频,7 阶段 + 7 器械标注,领域标准 |
| 器械空间定位/检测 | Cholec80-Boxes | 较小 | 测试集前 5 个视频的边界框标注 |
| 语义分割(组织/器官/器械) | CholecSeg8K | ~3.1 GB | 8,080 帧像素级分割,13 类语义标注 |
| 器械实例分割 | CholecInstanceSeg | ~15 GB | 41.9k 帧,实例 ID + 分割掩码 |
| 手术动作三元组识别 | CholecT50/CholecT45 | ~100 GB | 50 视频,工具-组织-动作三元组标注 |
| MICCAI 2016 挑战赛复现 | M2CAI16 | ~15 GB | 41 视频,Cholec80 子集 |
§3.1 模态详细说明
Cholec80 为纯视觉模态数据集——腹腔镜内窥镜 RGB 视频。视频通过标准腹腔镜摄像系统采集(具体设备型号未公开),视野为腹腔内手术区域。视频不包含音频、患者生命体征、手术机器人运动学数据等多模态信息。部分视频分辨率为 854×480,少数视频为 1920×1080。所有视频以 25 fps 采集,处理时下采样至 1 fps(每 25 帧取 1 帧)。
§3.2 样本数统计
| 数据划分 | 视频数 | 帧数(@ 1 fps) | 平均时长 | 备注 |
|---|---|---|---|---|
| Train | 40 | ~92,250 | ~38.4 min | video01-video40 |
| Test | 40 | ~92,250 | ~38.4 min | video41-video80 |
| 总计 | 80 | ~184,500 | ~38.4 min | 13 位外科医生主刀 |
注:平均时长 2,306.27 秒(约 38.4 分钟),基于 SASVi 论文(Springer, 2025)报告的数据。帧数为估计值(80 × 2,306 ≈ 184,480)。
§3.3 数据格式
| 文件类型 | 格式 | 尺寸 | 说明 |
|---|---|---|---|
| 视频帧 | PNG | 854×480(主要)/ 1920×1080(少数) | 1 fps 下采样后的逐帧 PNG |
| 阶段标注 | TXT | 每行:帧号 阶段编号(1-7) | 25 fps 粒度(原始帧率) |
| 器械标注 | TXT | 每行:帧号 7 个二值(Grasper Bipolar Hook Scissors Clipper Irrigator SpecimenBag) | 1 fps 粒度 |
| 原始视频 | MP4 | 25 fps | 部分申请者可获取原始视频 |
§3.4 存储大小
| 组件 | 大小(估计) | 说明 |
|---|---|---|
| 1 fps PNG 帧 | ~50 GB | ~184,500 帧 × ~270 KB/帧(854×480 PNG) |
| 标注文件 | < 10 MB | 80 个 TXT 文件 |
| 原始视频(25 fps) | ~200 GB | 80 × ~2.5 GB/视频(估计) |
§3.5 标注方式
Cholec80 的标注由斯特拉斯堡大学医院的一位资深外科医生完成,包含两个标注任务:
手术阶段标注(25 fps):将每例胆囊切除术划分为 7 个标准化阶段,按时间顺序为:
| 阶段 ID | 名称 | 平均时长 ± 标准差(秒) | 涉及器械 |
|---|---|---|---|
| P1 | Preparation(准备) | 107 ± 103 | Grasper |
| P2 | Calot Triangle Dissection(Calot 三角解剖) | 935 ± 663 | Grasper, Bipolar, Hook |
| P3 | Clipping and Cutting(夹闭与切断) | 176 ± 128 | Grasper, Clipper, Irrigator |
| P4 | Gallbladder Dissection(胆囊剥离) | 730 ± 533 | Grasper, Bipolar, Hook, Irrigator |
| P5 | Gallbladder Packaging(胆囊装袋) | 95 ± 48 | Grasper, Specimen Bag |
| P6 | Cleaning and Coagulation(清理与凝血) | 179 ± 156 | Grasper, Bipolar, Irrigator, Specimen Bag |
| P7 | Gallbladder Retraction(胆囊回收) | 83 ± 75 | Grasper, Specimen Bag |
器械存在标注(1 fps):7 种手术器械的二值存在性标注,判定标准为器械尖端至少一半可见于画面中。
| 器械 ID | 名称 | 中文 | 典型出现阶段 |
|---|---|---|---|
| T1 | Grasper | 抓钳 | P1-P7(几乎全程) |
| T2 | Bipolar | 双极电凝钳 | P2, P4, P6 |
| T3 | Hook | 钩形电凝钩 | P2, P4 |
| T4 | Scissors | 剪刀 | P3(极短,数据量最少) |
| T5 | Clipper | 施夹器 | P3 |
| T6 | Irrigator | 冲洗吸引器 | P3, P4, P6 |
| T7 | Specimen Bag | 标本袋 | P5, P6, P7 |
§3.6 标注者信息
| 维度 | 信息 |
|---|---|
| 标注者人数 | 1 人 |
| 标注者资质 | 资深外科医生(Senior Surgeon),斯特拉斯堡大学医院 |
| 标注工具 | 未公开 |
| IAA(标注者间一致性) | 无——仅一位标注者,无 IAA 数据 |
| 标注质量控制 | 未公开 |
§3.7 采集时间范围
数据采集时间估计为 2014-2016 年(基于 2016 年 arXiv 预印本发布时间推断),具体起止时间未公开。
§3.8 地理覆盖
单一机构:法国斯特拉斯堡大学医院(University Hospital of Strasbourg)/ IHU Strasbourg / IRCAD。无多中心数据。
§3.9 采集设备规格
腹腔镜摄像系统(具体品牌和型号未公开)。视频分辨率为 854×480(主要)或 1920×1080(少数)。帧率 25 fps。无 RGB-D、立体视觉或其他传感器数据。
§3.10 深度溯源链
斯特拉斯堡大学医院手术室
│
├── 腹腔镜摄像系统(品牌未公开)
│ └── 25 fps RGB 视频,854×480 / 1920×1080
│
├── 13 位外科医生主刀
│ └── 80 例腹腔镜胆囊切除术
│
├── 1 位资深外科医生标注
│ ├── 阶段标注(25 fps,7 阶段)
│ └── 器械存在标注(1 fps,7 器械二值)
│
├── CAMMA 研究组(University of Strasbourg, ICube / CNRS)
│ └── 数据处理、下采样、格式标准化
│
└── 公开发布
├── 2016-02: arXiv 预印本(arXiv:1602.03012)
├── 2017-01: IEEE TMI 正式发表
└── CC-BY-NC-SA 4.0 许可证,申请表获取
§4 数据结构详解(Data Schema)
§4.0 目录结构预览
cholec80/
├── frames/
│ ├── video01/
│ │ ├── video01_000001.png # 第 1 帧(854×480 RGB)
│ │ ├── video01_000002.png # 第 2 帧
│ │ └── ... # 1 fps,每视频约 2,300 帧
│ ├── video02/
│ │ └── ...
│ └── ...video80/
├── phase_annotations/
│ ├── video01-phase.txt # 格式:帧号 阶段编号
│ ├── video02-phase.txt
│ └── ...video80-phase.txt
├── tool_annotations/
│ ├── video01-tool.txt # 格式:帧号 Grasper Bipolar Hook Scissors Clipper Irrigator SpecimenBag
│ ├── video02-tool.txt
│ └── ...video80-tool.txt
└── LICENSE.txt # CC-BY-NC-SA 4.0
§4.1 DAIMS 标准化字段描述表
阶段标注文件(videoXX-phase.txt)
| 字段名 | 数据类型 | 说明 | 示例值 | AI 用途 | 观测误差 | 信息性缺失编码 | 取值范围 |
|---|---|---|---|---|---|---|---|
| frame | Integer | 帧序号(从 1 开始) | 1 | 时序定位 | 无 | N/A | 1 ~ ~138,000(25 fps) |
| phase | Integer (Label) | 手术阶段编号 | 2 | 时序分割标签 | 边界模糊(±10s) | 无 | 1-7 |
器械标注文件(videoXX-tool.txt)
| 字段名 | 数据类型 | 说明 | 示例值 | AI 用途 | 观测误差 | 信息性缺失编码 | 取值范围 |
|---|---|---|---|---|---|---|---|
| frame | Integer | 帧序号(从 1 开始,1 fps) | 1 | 时序定位 | 无 | N/A | 1 ~ ~2,300 |
| Grasper | Integer (Label) | 抓钳存在性 | 1 | 多标签分类 | 可见性判定主观 | 无 | 0/1 |
| Bipolar | Integer (Label) | 双极电凝钳存在性 | 0 | 多标签分类 | 同上 | 无 | 0/1 |
| Hook | Integer (Label) | 钩形电凝钩存在性 | 1 | 多标签分类 | 同上 | 无 | 0/1 |
| Scissors | Integer (Label) | 剪刀存在性 | 0 | 多标签分类 | 同上 | 无 | 0/1 |
| Clipper | Integer (Label) | 施夹器存在性 | 0 | 多标签分类 | 同上 | 无 | 0/1 |
| Irrigator | Integer (Label) | 冲洗吸引器存在性 | 0 | 多标签分类 | 同上 | 无 | 0/1 |
| SpecimenBag | Integer (Label) | 标本袋存在性 | 0 | 多标签分类 | 同上 | 无 | 0/1 |
§4.2 标签分布统计
阶段分布(按帧占比,基于测试集)
| 阶段 | 名称 | 帧占比(约) | 平均持续时长(秒) |
|---|---|---|---|
| P1 | Preparation | ~5% | 107 ± 103 |
| P2 | Calot Triangle Dissection | ~41% | 935 ± 663 |
| P3 | Clipping and Cutting | ~8% | 176 ± 128 |
| P4 | Gallbladder Dissection | ~32% | 730 ± 533 |
| P5 | Gallbladder Packaging | ~4% | 95 ± 48 |
| P6 | Cleaning and Coagulation | ~8% | 179 ± 156 |
| P7 | Gallbladder Retraction | ~4% | 83 ± 75 |
关键观察:P2(Calot 三角解剖)和 P4(胆囊剥离)合计占约 73% 的帧数,而 P5、P7 各仅占约 4%,存在显著的阶段类别不平衡。
器械出现频率(测试集 AP 值,EndoNet 原始结果)
| 器械 | 出现频率 | EndoNet AP | DPM AP(基线) |
|---|---|---|---|
| Grasper | 极高(几乎全程) | 84.8% | 82.3% |
| Hook | 高(P2, P4) | 95.6% | 93.4% |
| Bipolar | 中(P2, P4, P6) | 86.9% | 60.6% |
| Clipper | 低(P3) | 80.1% | 68.4% |
| Specimen Bag | 低(P5-P7) | 86.8% | 40.0% |
| Irrigator | 中低(P3, P4, P6) | 74.4% | 40.5% |
| Scissors | 极低(P3 短暂出现) | 58.6% | 23.4% |
| 平均 | — | 81.0% | 58.4% |
关键观察:Scissors(剪刀)的 AP 最低(58.6%),因其仅在 P3 阶段短暂出现,训练数据极少,且与 Grasper 视觉相似度高。
§4.3 关键字段描述性统计
- 阶段持续时间标准差/均值比(变异系数 CV):P2 = 0.71,P7 = 0.90,P1 = 0.96——短阶段变异系数更高,时序建模难度更大
- 每视频中器械种类数:平均 6.3/7(Scissors 出现频率最低)
- 器械共现对:Grasper-Hook(P2, P4)、Grasper-Bipolar(P2, P4, P6)、Grasper-Clipper(P3)
§4.4 数据层级关系
患者(1 人)→ 手术视频(1 个)→ 帧(~2,300 帧 @ 1 fps)
├── 阶段标签(1 个,1-7)
└── 器械标签(7 个二值向量)
§4.5 缺失值情况
| 字段 | 缺失情况 | 说明 |
|---|---|---|
| 阶段标注 | 无缺失 | 每帧均有阶段标注(25 fps 粒度) |
| 器械标注 | 无缺失 | 每帧(1 fps 粒度)均有 7 个二值标注 |
| 患者人口统计 | 全部缺失 | 年龄、性别、种族等均未收集 |
| 手术设备信息 | 全部缺失 | 腹腔镜系统品牌/型号未公开 |
| 术者信息 | 仅术者数量(13 人) | 术者经验年限、专长等未公开 |
§5 数据划分与使用建议(Splits & Usage)
§5.1 官方数据划分
| 划分 | 视频数 | 视频 ID | 帧数(@ 1 fps) |
|---|---|---|---|
| Train | 40 | video01-video40 | ~92,250 |
| Test | 40 | video41-video80 | ~92,250 |
标准划分:EndoNet 论文采用 40:40 划分(前 40 训练,后 40 测试),无独立验证集。该划分已成为 Cholec80 的事实标准,几乎所有后续论文均遵循此划分。
§5.2 常见非标准划分
| 划分方案 | Train/Val/Test | 来源 | 说明 |
|---|---|---|---|
| 标准 40:40 | 40/0/40 | EndoNet (Twinanda et al., 2017) | 事实标准 |
| 32:8:40 | 32/8/40 | Trans-SVNet (Jin et al., 2021) | 从训练集分出 8 个验证集 |
| 40:8:32 | 40/8/32 | 部分论文 | 从测试集分出 8 个验证集 |
| 48:12:20 | 48/12/20 | 少数论文 | 非标准 |
| 60:20 | 60/20 | 少数论文 | 非标准 |
| 4 折交叉验证 | — | Demir et al. (2022) | 在测试集上 4 折 CV |
⚠️ 警告:不同论文使用的划分方案不同,导致报告的性能指标不可直接比较。详见 §6.5 坑点 1。
§5.3 数据泄漏风险评估
| 风险点 | 评估 | 说明 |
|---|---|---|
| 同一术者跨划分 | 低 | 13 位术者的视频在训练/测试集中混合分布 |
| 同一患者跨划分 | 极低 | 每例手术为不同患者 |
| 时间泄漏 | 未知 | 采集时间未公开,无法评估时序泄漏 |
§5.4 交叉验证建议
由于 Cholec80 的标准划分为 40:40(无验证集),建议:
- 快速实验:直接使用标准 40:40 划分,无需验证集
- 需要超参调优:从训练集 40 个视频中分出 8 个作为验证集(32:8:40 划分)
- 严谨评估:在训练集上做 5 折交叉验证选择超参,在测试集上报告最终性能
§5.5 外部验证建议
Cholec80 为单一中心数据集,强烈建议在外部数据集上验证模型泛化性。可用外部数据集:
- M2CAI16-workflow(MICCAI 2016 挑战赛,41 视频)
- AutoLaparo(21 视频,不同手术流程定义)
- CATARACTS(50 视频,不同术种——白内障手术)
§5.6 使用建议
- 阶段识别任务:使用标准 40:40 划分,在测试集上报告 Accuracy、Precision、Recall、Jaccard
- 器械检测任务:使用标准 40:40 划分,在测试集上报告 mAP(mean Average Precision)
- 时序模型训练:使用整个视频序列(而非随机采帧),避免丢失时序信息
- 多任务学习:同时训练阶段识别和器械检测,利用器械-阶段关联增强表示学习
§6 AI 就绪指南(AI-Ready Guide)⭐ 核心差异化模块
§6.1 快速上手
<details>
<summary>📋 PyTorch DataLoader(Cholec80 阶段识别 + 器械检测)</summary>
# ========================================
# Cholec80 快速上手 — PyTorch 版
# 环境要求: torch>=2.0, torchvision, pandas, pillow
#
# ⚠️ 目录结构预期:
# 请将下载的数据解压至 ./data/cholec80/ 目录,确保以下结构:
# ./data/cholec80/
# ├── frames/
# │ ├── video01/
# │ │ ├── video01_000001.png
# │ │ └── ...
# │ └── ...video80/
# ├── phase_annotations/
# │ ├── video01-phase.txt
# │ └── ...
# └── tool_annotations/
# ├── video01-tool.txt
# └── ...
#
# 标注文件格式:
# - phase: 每行 "帧号 阶段编号(1-7)"
# - tool: 每行 "帧号 Grasper Bipolar Hook Scissors Clipper Irrigator SpecimenBag"
# ========================================
import os
import numpy as np
import torch
from torch.utils.data import Dataset, DataLoader
from PIL import Image
import torchvision.transforms as transforms
class Cholec80Dataset(Dataset):
"""Cholec80 数据集加载器,支持阶段识别和器械检测双任务"""
PHASE_NAMES = [
''''''''''''''''''''''''''''''''Preparation'''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''Calot Triangle Dissection'''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''Clipping and Cutting'''''''''''''''''''''''''''''''',
''''''''''''''''''''''''''''''''Gallbladder Dissection'''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''Gallbladder Packaging'''''''''''''''''''''''''''''''',
''''''''''''''''''''''''''''''''Cleaning and Coagulation'''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''Gallbladder Retraction''''''''''''''''''''''''''''''''
]
TOOL_NAMES = [
''''''''''''''''''''''''''''''''Grasper'''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''Bipolar'''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''Hook'''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''Scissors'''''''''''''''''''''''''''''''',
''''''''''''''''''''''''''''''''Clipper'''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''Irrigator'''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''Specimen Bag''''''''''''''''''''''''''''''''
]
def __init__(self, data_root, video_ids, phase=True, tool=True,
transform=None, frame_skip=25):
"""
Args:
data_root: 数据集根目录
video_ids: 视频ID列表,如 list(range(1, 41)) 表示训练集
phase: 是否加载阶段标注
tool: 是否加载器械标注
transform: 图像变换
frame_skip: 帧采样间隔(25 = 1 fps from 25 fps)
"""
self.data_root = data_root
self.transform = transform or transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])
])
self.samples = []
for vid in video_ids:
video_dir = os.path.join(data_root, ''''''''''''''''''''''''''''''''frames'''''''''''''''''''''''''''''''', f''''''''''''''''''''''''''''''''video{vid:02d}'''''''''''''''''''''''''''''''')
if not os.path.exists(video_dir):
continue
# 加载阶段标注
phase_labels = {}
if phase:
phase_file = os.path.join(data_root, ''''''''''''''''''''''''''''''''phase_annotations'''''''''''''''''''''''''''''''',
f''''''''''''''''''''''''''''''''video{vid:02d}-phase.txt'''''''''''''''''''''''''''''''')
if os.path.exists(phase_file):
with open(phase_file) as f:
for line in f:
parts = line.strip().split()
frame_idx = int(parts[0])
phase_label = int(parts[1]) - 1 # 0-indexed
phase_labels[frame_idx] = phase_label
# 加载器械标注
tool_labels = {}
if tool:
tool_file = os.path.join(data_root, ''''''''''''''''''''''''''''''''tool_annotations'''''''''''''''''''''''''''''''',
f''''''''''''''''''''''''''''''''video{vid:02d}-tool.txt'''''''''''''''''''''''''''''''')
if os.path.exists(tool_file):
with open(tool_file) as f:
for line in f:
parts = line.strip().split()
frame_idx = int(parts[0])
tools = [int(x) for x in parts[1:8]]
tool_labels[frame_idx] = tools
# 收集帧(按 frame_skip 采样,实现 1 fps)
frames = sorted(os.listdir(video_dir))
for fname in frames:
if not fname.endswith(''''''''''''''''''''''''''''''''.png''''''''''''''''''''''''''''''''):
continue
frame_idx = int(fname.split(''''''''''''''''''''''''''''''''_'''''''''''''''''''''''''''''''')[1].split(''''''''''''''''''''''''''''''''.'''''''''''''''''''''''''''''''')[0])
if frame_idx % frame_skip != 0:
continue
img_path = os.path.join(video_dir, fname)
p_label = phase_labels.get(frame_idx, -1)
t_label = tool_labels.get(frame_idx, [0] * 7)
if (phase and p_label == -1) or (tool and frame_idx not in tool_labels):
continue
self.samples.append({
''''''''''''''''''''''''''''''''image_path'''''''''''''''''''''''''''''''': img_path,
''''''''''''''''''''''''''''''''video_id'''''''''''''''''''''''''''''''': vid,
''''''''''''''''''''''''''''''''frame_idx'''''''''''''''''''''''''''''''': frame_idx,
''''''''''''''''''''''''''''''''phase'''''''''''''''''''''''''''''''': p_label,
''''''''''''''''''''''''''''''''tool'''''''''''''''''''''''''''''''': t_label
})
def __len__(self):
return len(self.samples)
def __getitem__(self, idx):
sample = self.samples[idx]
image = Image.open(sample[''''''''''''''''''''''''''''''''image_path'''''''''''''''''''''''''''''''']).convert(''''''''''''''''''''''''''''''''RGB'''''''''''''''''''''''''''''''')
if self.transform:
image = self.transform(image)
result = {''''''''''''''''''''''''''''''''image'''''''''''''''''''''''''''''''': image, ''''''''''''''''''''''''''''''''video_id'''''''''''''''''''''''''''''''': sample[''''''''''''''''''''''''''''''''video_id''''''''''''''''''''''''''''''''],
''''''''''''''''''''''''''''''''frame_idx'''''''''''''''''''''''''''''''': sample[''''''''''''''''''''''''''''''''frame_idx'''''''''''''''''''''''''''''''']}
if sample[''''''''''''''''''''''''''''''''phase''''''''''''''''''''''''''''''''] >= 0:
result[''''''''''''''''''''''''''''''''phase''''''''''''''''''''''''''''''''] = torch.tensor(sample[''''''''''''''''''''''''''''''''phase''''''''''''''''''''''''''''''''], dtype=torch.long)
result[''''''''''''''''''''''''''''''''tool''''''''''''''''''''''''''''''''] = torch.tensor(sample[''''''''''''''''''''''''''''''''tool''''''''''''''''''''''''''''''''], dtype=torch.float32)
return result
# 使用示例
data_root = ''''''''''''''''''''''''''''''''./data/cholec80''''''''''''''''''''''''''''''''
train_dataset = Cholec80Dataset(data_root, video_ids=list(range(1, 41)))
test_dataset = Cholec80Dataset(data_root, video_ids=list(range(41, 81)))
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True,
num_workers=4, pin_memory=True)
test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False,
num_workers=4, pin_memory=True)
print(f"训练集: {len(train_dataset)} 帧")
print(f"测试集: {len(test_dataset)} 帧")
print(f"阶段类别: {Cholec80Dataset.PHASE_NAMES}")
print(f"器械类别: {Cholec80Dataset.TOOL_NAMES}")
</details>
§6.2 数据获取方式
| 步骤 | 说明 |
|---|---|
| 1. 访问 CAMMA 数据集页面 | https://camma.unistra.fr/datasets/ |
| 2. 找到 Cholec80 Dataset | 点击进入数据集详情 |
| 3. 填写申请表 | 在线填写研究用途说明,需提供机构信息和研究计划 |
| 4. 获取下载链接 | 审核通过后收到下载链接(时间不定) |
| 5. 下载并解压 | ~50 GB(1 fps PNG 帧),需稳定网络环境 |
| 6. 克隆官方代码 | https://github.com/CAMMA-public/TF-Cholec80 |
§6.3 预处理 Pipeline
<details>
<summary>📋 预处理 Pipeline(帧加载 + 时序特征提取)</summary>
import os
import numpy as np
import torch
from PIL import Image
import torchvision.transforms as transforms
class Cholec80Preprocessor:
"""Cholec80 预处理器:帧加载、归一化、时序窗口构建"""
# ImageNet 统计量(用于预训练 backbone)
IMAGENET_MEAN = [0.485, 0.456, 0.406]
IMAGENET_STD = [0.229, 0.224, 0.225]
def __init__(self, image_size=224, sequence_length=16):
self.image_size = image_size
self.sequence_length = sequence_length
self.train_transform = transforms.Compose([
transforms.Resize((image_size, image_size)),
transforms.RandomHorizontalFlip(p=0.5),
transforms.ColorJitter(brightness=0.2, conevent-blocked=0.2,
saturation=0.2, hue=0.1),
transforms.ToTensor(),
transforms.Normalize(self.IMAGENET_MEAN, self.IMAGENET_STD)
])
self.eval_transform = transforms.Compose([
transforms.Resize((image_size, image_size)),
transforms.ToTensor(),
transforms.Normalize(self.IMAGENET_MEAN, self.IMAGENET_STD)
])
def build_video_sequence(self, frames_dir, annotations_dir, video_id,
max_frames=None):
"""构建完整视频的时序序列
Returns:
frames: list of PIL Images (1 fps)
phases: list of int (phase labels per frame)
tools: list of list (tool labels per frame)
"""
video_dir = os.path.join(frames_dir, f''''''''''''''''''''''''''''''''video{video_id:02d}'''''''''''''''''''''''''''''''')
# 加载标注
phases = self._load_phase_annotations(annotations_dir, video_id)
tools = self._load_tool_annotations(annotations_dir, video_id)
# 按帧号排序加载帧(1 fps 采样)
frame_files = sorted([f for f in os.listdir(video_dir)
if f.endswith(''''''''''''''''''''''''''''''''.png'''''''''''''''''''''''''''''''')])
frames = []
phase_seq = []
tool_seq = []
for fname in frame_files:
frame_idx = int(fname.split(''''''''''''''''''''''''''''''''_'''''''''''''''''''''''''''''''')[1].split(''''''''''''''''''''''''''''''''.'''''''''''''''''''''''''''''''')[0])
if frame_idx % 25 != 0: # 1 fps 采样
continue
if max_frames and len(frames) >= max_frames:
break
img = Image.open(os.path.join(video_dir, fname)).convert(''''''''''''''''''''''''''''''''RGB'''''''''''''''''''''''''''''''')
frames.append(img)
phase_seq.append(phases.get(frame_idx, 0))
tool_seq.append(tools.get(frame_idx, [0] * 7))
return frames, phase_seq, tool_seq
def create_temporal_windows(self, frames, labels, window_size=16,
stride=1):
"""将视频切分为时序窗口
用于 TCN/LSTM/Transformer 等时序模型训练
"""
windows = []
window_labels = []
for i in range(0, len(frames) - window_size + 1, stride):
window = frames[i:i + window_size]
window_label = labels[i + window_size - 1] # 取窗口最后一帧的标签
windows.append(window)
window_labels.append(window_label)
return windows, window_labels
def _load_phase_annotations(self, annotations_dir, video_id):
"""加载阶段标注"""
phase_file = os.path.join(annotations_dir,
f''''''''''''''''''''''''''''''''video{video_id:02d}-phase.txt'''''''''''''''''''''''''''''''')
phases = {}
if os.path.exists(phase_file):
with open(phase_file) as f:
for line in f:
parts = line.strip().split()
phases[int(parts[0])] = int(parts[1]) - 1 # 0-indexed
return phases
def _load_tool_annotations(self, annotations_dir, video_id):
"""加载器械标注"""
tool_file = os.path.join(annotations_dir,
f''''''''''''''''''''''''''''''''video{video_id:02d}-tool.txt'''''''''''''''''''''''''''''''')
tools = {}
if os.path.exists(tool_file):
with open(tool_file) as f:
for line in f:
parts = line.strip().split()
tools[int(parts[0])] = [int(x) for x in parts[1:8]]
return tools
# 使用示例
preprocessor = Cholec80Preprocessor(image_size=224, sequence_length=16)
# 构建视频序列
frames, phases, tools = preprocessor.build_video_sequence(
''''''''''''''''''''''''''''''''./data/cholec80/frames'''''''''''''''''''''''''''''''',
''''''''''''''''''''''''''''''''./data/cholec80/phase_annotations'''''''''''''''''''''''''''''''',
video_id=1
)
# 切分时序窗口
windows, window_labels = preprocessor.create_temporal_windows(
frames, phases, window_size=16, stride=1
)
print(f"视频 1: {len(frames)} 帧, {len(windows)} 个时序窗口")
</details>
§6.4 框架加载器
<details>
<summary>📋 TensorFlow / Keras DataLoader</summary>
import tensorflow as tf
import os
import numpy as np
def create_cholec80_tf_dataset(data_root, video_ids, batch_size=32,
image_size=224, shuffle=True):
"""Cholec80 TensorFlow 数据集"""
def load_sample(video_id, frame_idx):
video_dir = os.path.join(data_root, ''''''''''''''''''''''''''''''''frames'''''''''''''''''''''''''''''''', f''''''''''''''''''''''''''''''''video{video_id:02d}'''''''''''''''''''''''''''''''')
img_path = os.path.join(video_dir,
f''''''''''''''''''''''''''''''''video{video_id:02d}_{frame_idx:06d}.png'''''''''''''''''''''''''''''''')
img = tf.io.read_file(img_path)
img = tf.image.decode_png(img, channels=3)
img = tf.image.resize(img, [image_size, image_size])
img = tf.keras.applications.resnet50.preprocess_input(img)
return img
def load_annotations(data_root, video_id):
"""加载阶段和器械标注"""
phase_file = os.path.join(data_root, ''''''''''''''''''''''''''''''''phase_annotations'''''''''''''''''''''''''''''''',
f''''''''''''''''''''''''''''''''video{video_id:02d}-phase.txt'''''''''''''''''''''''''''''''')
tool_file = os.path.join(data_root, ''''''''''''''''''''''''''''''''tool_annotations'''''''''''''''''''''''''''''''',
f''''''''''''''''''''''''''''''''video{video_id:02d}-tool.txt'''''''''''''''''''''''''''''''')
phases = {}
with open(phase_file) as f:
for line in f:
parts = line.strip().split()
phases[int(parts[0])] = int(parts[1]) - 1
tools = {}
with open(tool_file) as f:
for line in f:
parts = line.strip().split()
tools[int(parts[0])] = [int(x) for x in parts[1:8]]
return phases, tools
samples = []
for vid in video_ids:
phases, tools = load_annotations(data_root, vid)
video_dir = os.path.join(data_root, ''''''''''''''''''''''''''''''''frames'''''''''''''''''''''''''''''''', f''''''''''''''''''''''''''''''''video{vid:02d}'''''''''''''''''''''''''''''''')
for fname in sorted(os.listdir(video_dir)):
if not fname.endswith(''''''''''''''''''''''''''''''''.png''''''''''''''''''''''''''''''''):
continue
frame_idx = int(fname.split(''''''''''''''''''''''''''''''''_'''''''''''''''''''''''''''''''')[1].split(''''''''''''''''''''''''''''''''.'''''''''''''''''''''''''''''''')[0])
if frame_idx % 25 != 0:
continue
if frame_idx in phases and frame_idx in tools:
samples.append((vid, frame_idx, phases[frame_idx],
tools[frame_idx]))
def gen():
for vid, fidx, phase, tool in samples:
img = load_sample(vid, fidx)
yield img, {''''''''''''''''''''''''''''''''phase'''''''''''''''''''''''''''''''': phase, ''''''''''''''''''''''''''''''''tool'''''''''''''''''''''''''''''''': tool}
output_signature = (
tf.TensorSpec(shape=(image_size, image_size, 3), dtype=tf.float32),
{
''''''''''''''''''''''''''''''''phase'''''''''''''''''''''''''''''''': tf.TensorSpec(shape=(), dtype=tf.int32),
''''''''''''''''''''''''''''''''tool'''''''''''''''''''''''''''''''': tf.TensorSpec(shape=(7,), dtype=tf.int32)
}
)
dataset = tf.data.Dataset.from_generator(gen, output_signature)
if shuffle:
dataset = dataset.shuffle(buffer_size=1000)
dataset = dataset.batch(batch_size).prefetch(tf.data.AUTOTUNE)
return dataset
# 使用示例
train_ds = create_cholec80_tf_dataset(''''''''''''''''''''''''''''''''./data/cholec80'''''''''''''''''''''''''''''''', list(range(1, 41)))
test_ds = create_cholec80_tf_dataset(''''''''''''''''''''''''''''''''./data/cholec80'''''''''''''''''''''''''''''''', list(range(41, 81)),
shuffle=False)
</details>
§6.5 常见坑点
⚠️ 坑点 1:评估协议不一致导致结果不可比较(分类:评估误用)
问题:Cholec80 上不同论文使用的评估协议差异极大——(a) 数据划分不同(40:40 vs 32:8:40 vs 48:12:20 vs 4 折 CV);(b) 边界处理不同(relaxed boundaries 在阶段转换 ±10 秒窗口内视为正确 vs unrelaxed 严格逐帧评估);© 标准差计算方式不同(跨实验重复 vs 跨视频)。
症状:同一方法在不同论文中报告的准确率差异可达 3-5 个百分点;看似"新 SOTA"可能仅因使用了更宽松的评估协议。
解决:
- 始终报告两种评估:同时报告 relaxed 和 unrelaxed 结果
- 明确数据划分:使用标准 40:40 划分,如需验证集则从训练集分出(32:8:40)
- 引用 Metrics Matter 论文:Funke et al. (2023) 系统总结了 Cholec80 上的评估不一致问题
- 使用公开评估代码:https://gitlab.com/nct_tso_public/phasemetrics
参考:Funke et al. (2023), “Metrics Matter in Surgical Phase Recognition”, arXiv:2305.13961
⚠️ 坑点 2:Scissors 器械类别严重不平衡(分类:标签理解)
问题:Scissors(剪刀)仅在 P3 Clipping and Cutting 阶段短暂出现,训练数据极少,且与 Grasper 视觉相似度高。EndoNet 原始 AP 仅 58.6%,是所有器械中最低的。
症状:模型对 Scissors 的检测准确率远低于其他器械(差距 >20 个百分点),直接取 7 类 mAP 时被 Scissors 拖低。
解决:
- 加权损失:使用中位数频率平衡(Median Frequency Balancing)或逆频率加权
- 过采样:对包含 Scissors 的帧进行过采样
- Focal Loss:使用 Focal Loss 替代 BCE,降低易分类样本权重
- 分离评估:报告逐器械 AP 和 mAP,不要只看 mAP
参考:Eigen & Fergus (2015), “Predicting Depth, Surface Normals and Semantic Labels with a Common Multi-Scale Convolutional Architecture”
⚠️ 坑点 3:阶段转换边界模糊(分类:标签理解)
问题:手术阶段之间的转换并非瞬间完成,存在过渡区间(如 P2→P3 之间可能存在同时包含两个阶段特征的帧)。单一标注者的主观判断导致边界标签存在噪声。
症状:模型在阶段转换前后 5-10 秒内的预测不稳定,频繁跳变;训练 loss 在这些帧上持续较高。
解决:
- Relaxed boundaries 评估:在阶段转换 ±10 秒窗口内不计算错误(与多数论文一致)
- 时序平滑:使用 HMM、TCN 或 LSTM 对帧级预测进行时序平滑
- 边界感知训练:在转换边界附近降低 loss 权重
参考:Twinanda et al. (2017), IEEE TMI, §IV-C HHMM 时序平滑
⚠️ 坑点 4:非商业许可证限制(分类:工程陷阱)
问题:Cholec80 采用 CC-BY-NC-SA 4.0 许可证,禁止商业用途。在商业产品中使用基于 Cholec80 训练的模型存在法律风险。
症状:商业团队开发了基于 Cholec80 的手术辅助系统后,法务审查发现许可协议禁止商用。
解决:
- 研究用途:确保使用仅限于非商业学术研究
- 商业替代:考虑使用 CC-BY 许可的数据集(如部分 M2CAI 数据)或自行采集数据
- 许可咨询:联系 CAMMA 团队咨询商业许可可能性
⚠️ 坑点 5:单一中心数据导致泛化性不足(分类:偏倚陷阱)
问题:所有 80 个视频均来自斯特拉斯堡大学医院,由 13 位外科医生主刀。不同医院的手术设备、术者习惯、手术流程顺序可能不同,导致模型跨中心泛化性下降。Bar et al. 报告跨中心准确率下降约 10%。
症状:在 Cholec80 测试集上达 90%+ 准确率的模型,迁移到其他医院的视频时准确率降至 80-85%。
解决:
- 外部验证:在 M2CAI16-workflow 或 AutoLaparo 上评估跨数据集泛化性
- 域自适应:使用 Domain Adaptation 技术(如 DANN、AdaBN)
- 数据增强:使用颜色抖动、随机裁剪等增强提高泛化性
参考:Bar et al., “Cross-domain surgical workflow recognition”
⚠️ 坑点 6:器械标注仅二值无空间信息(分类:标签理解)
问题:原始 Cholec80 的器械标注仅为二值存在性(present/absent),无边界框或分割掩码。若需器械定位任务,原始标注不足。
症状:模型可以判断"画面中有 Hook",但无法定位 Hook 在画面中的位置。
解决:
- 使用 Cholec80-Boxes:测试集前 5 个视频的边界框标注
- 使用 CholecSeg8K:8,080 帧语义分割标注(13 类含 2 种器械)
- 使用 CholecInstanceSeg:41.9k 帧实例分割标注
- 自行标注:使用 SAM 等工具辅助标注
参考:Hong et al. (2020), CholecSeg8K, arXiv:2012.12453; CholecInstanceSeg, arXiv:2406.16039
§6.6 数据增强安全表
| 增强方法 | 安全性 | 说明 |
|---|---|---|
| RandomHorizontalFlip | ✅ 安全 | 腹腔镜视野无方向依赖 |
| RandomBrightness (±0.2) | ✅ 安全 | 模拟光照变化 |
| RandomContrast (±0.2) | ✅ 安全 | 模拟设备差异 |
| RandomSaturation (±0.2) | ✅ 安全 | 模拟组织颜色差异 |
| ColorJitter (hue ±0.1) | ⚠️ 谨慎 | 过大 hue 偏移可能改变组织颜色语义 |
| RandomRotation (±10°) | ✅ 安全 | 腹腔镜可旋转 |
| RandomResizedCrop | ✅ 安全 | 模拟视野缩放 |
| RandomGaussianBlur | ✅ 安全 | 模拟失焦 |
| RandomVerticalFlip | ❌ 危险 | 破坏解剖学方向(肝在上、肠在下) |
| RandomErasing | ⚠️ 谨慎 | 可能擦除关键解剖标志 |
| MixUp / CutMix | ❌ 危险 | 混合不同手术帧可能产生非真实场景 |
§6.7 模型推荐配置
| 模型 | Backbone | 时序模块 | 预期准确率 | 论文 |
|---|---|---|---|---|
| EndoNet (基线) | AlexNet | HMM | ~81.7% | Twinanda et al., 2017 |
| TMRNet | ResNet-50 | TCN + Memory | ~90.1% | Jin et al., 2021 |
| Trans-SVNet | ResNet-50 + TCN | Transformer | ~90.3% | Jin et al., 2021 |
| ASFormer | — | Transformer | ~92.5% | Yi et al., 2023 |
| SF-TMN | ResNet-50 | SlowFast TCN | ~95.4% | Zhang et al., 2023 |
| LoViT | ViT | L-Trans + G-Informer | ~91.5% | Liu et al., 2024 |
| SKiT | ResNet-50 | Structured TCN | ~93.4% | 2024 |
| Surgformer | ResNet | Hierarchical Attention | ~93.4% | 2024 |
| SurgFM (基础模型) | ViT (大规模预训练) | — | ~92.7% | 2025 |
§6.8 硬件配置建议
| 任务 | GPU 显存 | 训练时间 | 说明 |
|---|---|---|---|
| 阶段识别(CNN + TCN) | 8-12 GB | 4-8 小时 | ResNet-50 + MS-TCN,batch=32 |
| 阶段识别(Transformer) | 16-24 GB | 8-16 小时 | LoViT/Surgformer,batch=24 |
| 器械检测(多标签分类) | 8 GB | 2-4 小时 | ResNet-50,batch=64 |
| 多任务联合训练 | 12-16 GB | 6-12 小时 | 阶段 + 器械联合 |
| SurgFM 基础模型微调 | 24+ GB | 2-4 小时 | 预训练权重微调 |
§6.9 评估指标
<details>
<summary>📋 评估指标代码(阶段识别 + 器械检测)</summary>
import numpy as np
from sklearn.metrics import precision_score, recall_score, accuracy_score
from sklearn.metrics import average_precision_score
# ==================== 阶段识别评估 ====================
def phase_recognition_metrics(y_true, y_pred, num_phases=7, relaxed=False,
boundary_window=10):
"""计算手术阶段识别指标
Args:
y_true: 真实标签 (N,)
y_pred: 预测标签 (N,)
num_phases: 阶段数
relaxed: 是否使用 relaxed boundaries(阶段转换 ±boundary_window 秒内不计错误)
boundary_window: relaxed 边界窗口(秒,=帧数 @ 1 fps)
"""
if relaxed:
# 找到阶段转换点
boundaries = np.where(np.diff(y_true) != 0)[0] + 1
mask = np.ones(len(y_true), dtype=bool)
for b in boundaries:
start = max(0, b - boundary_window)
end = min(len(y_true), b + boundary_window)
mask[start:end] = False
y_true_masked = y_true[mask]
y_pred_masked = y_pred[mask]
else:
y_true_masked = y_true
y_pred_masked = y_pred
accuracy = accuracy_score(y_true_masked, y_pred_masked)
precision = precision_score(y_true_masked, y_pred_masked,
average=''''''''''''''''''''''''''''''''macro'''''''''''''''''''''''''''''''', zero_division=0)
recall = recall_score(y_true_masked, y_pred_masked,
average=''''''''''''''''''''''''''''''''macro'''''''''''''''''''''''''''''''', zero_division=0)
# Jaccard(逐阶段计算后取平均)
jaccards = []
for p in range(num_phases):
tp = np.sum((y_true_masked == p) & (y_pred_masked == p))
fp = np.sum((y_true_masked != p) & (y_pred_masked == p))
fn = np.sum((y_true_masked == p) & (y_pred_masked != p))
if tp + fp + fn > 0:
jaccards.append(tp / (tp + fp + fn))
jaccard = np.mean(jaccards) if jaccards else 0.0
return {
''''''''''''''''''''''''''''''''accuracy'''''''''''''''''''''''''''''''': accuracy,
''''''''''''''''''''''''''''''''precision'''''''''''''''''''''''''''''''': precision,
''''''''''''''''''''''''''''''''recall'''''''''''''''''''''''''''''''': recall,
''''''''''''''''''''''''''''''''jaccard'''''''''''''''''''''''''''''''': jaccard
}
# ==================== 器械检测评估 ====================
def tool_detection_metrics(y_true, y_scores, num_tools=7):
"""计算器械存在检测指标(mAP)
Args:
y_true: 真实标签 (N, 7) 二值矩阵
y_scores: 预测概率 (N, 7)
num_tools: 器械数
"""
tool_names = [''''''''''''''''''''''''''''''''Grasper'''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''Bipolar'''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''Hook'''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''Scissors'''''''''''''''''''''''''''''''',
''''''''''''''''''''''''''''''''Clipper'''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''Irrigator'''''''''''''''''''''''''''''''', ''''''''''''''''''''''''''''''''Specimen Bag'''''''''''''''''''''''''''''''']
aps = []
for i in range(num_tools):
if len(np.unique(y_true[:, i])) > 1:
ap = average_precision_score(y_true[:, i], y_scores[:, i])
else:
ap = 0.0
aps.append(ap)
results = {''''''''''''''''''''''''''''''''mAP'''''''''''''''''''''''''''''''': np.mean(aps)}
for i, name in enumerate(tool_names):
results[f''''''''''''''''''''''''''''''''AP_{name}''''''''''''''''''''''''''''''''] = aps[i]
return results
# ==================== 逐视频评估 ====================
def evaluate_per_video(predictions, ground_truths, video_ids,
task=''''''''''''''''''''''''''''''''phase'''''''''''''''''''''''''''''''', relaxed=False):
"""逐视频评估并计算标准差
返回 mean ± std 格式(标准差跨视频计算)
"""
video_results = []
unique_videos = sorted(set(video_ids))
for vid in unique_videos:
mask = [i for i, x in enumerate(video_ids) if x == vid]
if task == ''''''''''''''''''''''''''''''''phase'''''''''''''''''''''''''''''''':
metrics = phase_recognition_metrics(
ground_truths[mask], predictions[mask], relaxed=relaxed)
video_results.append(metrics[''''''''''''''''''''''''''''''''accuracy''''''''''''''''''''''''''''''''])
elif task == ''''''''''''''''''''''''''''''''tool'''''''''''''''''''''''''''''''':
metrics = tool_detection_metrics(
ground_truths[mask], predictions[mask])
video_results.append(metrics[''''''''''''''''''''''''''''''''mAP''''''''''''''''''''''''''''''''])
mean = np.mean(video_results)
std = np.std(video_results)
return mean, std
# 使用示例
# y_true_phase = np.array([0, 0, 1, 1, 2, ...]) # 7 类阶段标签
# y_pred_phase = np.array([0, 1, 1, 1, 2, ...])
# metrics = phase_recognition_metrics(y_true_phase, y_pred_phase, relaxed=True)
# print(f"Accuracy: {metrics[''''''''''''''''''''''''''''''''accuracy'''''''''''''''''''''''''''''''']:.4f}")
# print(f"Jaccard: {metrics[''''''''''''''''''''''''''''''''jaccard'''''''''''''''''''''''''''''''']:.4f}")
</details>
§6.10 MLOps 笔记
- 推理延迟:术中实时阶段识别需要 < 100ms 的推理延迟,建议使用轻量级 backbone(如 ResNet-18)+ 简单 TCN
- 流式推理:实际部署中视频以流方式输入,需要维护时序窗口缓存(如最近 16 帧)
- 模型版本管理:不同评估协议下的模型不可直接比较,建议在模型库中标注评估协议
- 数据版本管理:Cholec80 自 2017 年发布以来无版本更新,但衍生数据集(CholecSeg8K、CholecT50 等)持续扩展,需追踪标注版本
§7 质量评估与局限性(Quality & Limitations)
§7.1 已知偏倚
| 偏倚类型 | 描述 | 严重程度 | 缓解措施 |
|---|---|---|---|
| 选择偏倚(单中心) | 所有 80 例手术来自同一家医院(斯特拉斯堡大学医院),设备、术式、流程标准化程度高 | 🔴 高 | 在外部数据集上验证;使用域自适应技术 |
| 术者偏倚 | 13 位术者均来自同一家医院,可能共享特定手术习惯 | 🟡 中 | 扩大术者多样性(需新数据采集) |
| 类别不平衡(器械) | Scissors 出现频率极低,训练数据不足 | 🟡 中 | 加权损失、过采样、Focal Loss |
| 类别不平衡(阶段) | P2 和 P4 占 ~73%,P5 和 P7 各仅 ~4% | 🟡 中 | 加权损失、时序平滑 |
| 标注者偏倚 | 单一标注者,无 IAA | 🟡 中 | 多标注者交叉验证(需重新标注) |
| 人口统计缺失 | 未公开年龄、性别、种族等信息 | 🟡 中 | 无法进行公平性评估 |
§7.2 标注质量评估
| 标注类型 | 标注者 | 准确率评估 | 一致性 | 局限性 |
|---|---|---|---|---|
| 阶段标注 | 1 位资深外科医生 | 无独立验证 | 无 IAA | 边界主观性强;单一标注者视角 |
| 器械标注 | 同上 | 无独立验证 | 无 IAA | "半数尖端可见"标准主观;器械遮挡时判定困难 |
§7.3 泛化性讨论
| 场景 | 失效风险 | 证据 |
|---|---|---|
| 跨医院部署 | 🔴 高 | Bar et al. 报告跨中心准确率下降 ~10% |
| 跨术种迁移 | 🔴 高 | Cholec80 仅含胆囊切除术,迁移到其他术种需重新标注 |
| 不同腹腔镜设备 | 🟡 中 | 设备品牌未公开,无法评估设备域偏移 |
| 急诊/复杂病例 | 🟡 中 | 数据集可能仅含择期手术,不含急诊或复杂病例 |
| 不同手术流程顺序 | 🟡 中 | 7 阶段顺序固定,但实际手术可能因并发症跳过或重复阶段 |
§7.4 伦理考量
- 患者隐私:视频仅包含腹腔内手术视野,无患者面部或身份信息。但术者手部可能出现在画面中。
- 知情同意:数据集未公开患者知情同意流程,推测已获得 IRB 批准(斯特拉斯堡大学医院)
- 非商业许可:CC-BY-NC-SA 4.0 限制商业应用,可能影响技术转化
- 术者评估:数据集含 13 位术者的视频,若用于术者技能评估可能引发伦理问题
§7.5 公平性评估
无法进行公平性评估——Cholec80 未公开任何患者人口统计数据(年龄、性别、种族、BMI 等),无法评估模型在不同子群体间的性能差异。这是该数据集的重大局限之一。
§7.6 数据漂移提示
- 手术技术演进:2014-2016 年采集的手术视频可能不代表当前的手术技术(如荧光引导手术、4K 腹腔镜等)
- 设备更新:腹腔镜摄像系统在过去 10 年有显著升级(分辨率、HDR、NBI 等),旧设备视频可能与新设备存在域差异
- 术式演变:新型器械(如吻合器、能量平台)的引入可能改变手术流程
§7.7 DAIMS 24 项数据就绪度评估表
| # | 评估项 | 状态 | 说明 |
|---|---|---|---|
| 1 | 数据集版本标识 | ✅ | v1.0(2017 IEEE TMI 正式版) |
| 2 | 数据集 URL/DOI | ✅ | DOI: 10.1109/TMI.2016.2593957 |
| 3 | 数据格式文档 | ✅ | PNG/TXT 格式,官方 GitHub 有代码示例 |
| 4 | 数据字典 | ✅ | 7 阶段 + 7 器械,定义明确 |
| 5 | 标注者信息 | ⚠️ | 仅 1 位标注者,无 IAA |
| 6 | 标注协议 | ⚠️ | "半数尖端可见"标准描述简略 |
| 7 | 数据划分 | ✅ | 标准 40:40 划分 |
| 8 | 数据大小/统计 | ✅ | 80 视频,~184,500 帧 |
| 9 | 许可证 | ✅ | CC-BY-NC-SA 4.0(明确但限制商业) |
| 10 | 设备信息 | ⚠️ | 腹腔镜品牌/型号未公开 |
| 11 | 采集协议 | ⚠️ | 采集参数(分辨率混合)未统一说明 |
| 12 | 患者人口统计 | ❌ | 完全未公开 |
| 13 | 知情同意/伦理 | ⚠️ | 未公开 IRB 信息 |
| 14 | 数据脱敏 | ✅ | 仅腹腔内视野,无患者身份信息 |
| 15 | 偏倚声明 | ✅ | 单中心、13 术者(但无人口统计偏倚分析) |
| 16 | 已知局限性 | ✅ | 单中心、非商业许可 |
| 17 | 更新计划 | ❌ | 自 2017 年无更新 |
| 18 | 引用格式 | ✅ | BibTeX 在 CAMMA 网站提供 |
| 19 | 相关数据集 | ✅ | CholecSeg8K、CholecT50 等衍生数据集丰富 |
| 20 | 评估基准 | ✅ | 标准 40:40 划分 + 4 指标(Acc/P/R/J) |
| 21 | 公平性评估 | ❌ | 无人口统计数据,无法评估 |
| 22 | 外部验证 | ✅ | 多篇论文在 M2CAI16、AutoLaparo 上验证 |
| 23 | 代码可用性 | ✅ | 官方 TF-Cholec80 GitHub 仓库 |
| 24 | 预训练模型 | ✅ | 多个开源模型(EndoNet、TMRNet 等) |
DAIMS 评分:18 / 24
评分解读:良好 — 接近优秀,但在公平性和标注者多样性方面有显著缺口。对你意味着什么:Cholec80 是计算手术学领域的事实标准基准,标准划分清晰、官方代码可用、衍生生态丰富。主要扣分项集中在:单一标注者无 IAA(#5)、设备信息未公开(#10)、无患者人口统计数据无法公平性评估(#12, #21)、非商业许可限制(#9)。建议在训练前执行以下操作:(1) 使用 Focal Loss 或加权损失处理器械类别不平衡;(2) 在 M2CAI16 或 AutoLaparo 上进行外部验证;(3) 如需商业应用,提前咨询 CAMMA 团队或考虑替代数据集。
§7.8 外部验证矩阵
| 外部数据集 | 来源机构 | 样本量 | 评估任务 | 性能指标 | 相对内部测试集变化 | 关键发现 |
|---|---|---|---|---|---|---|
| M2CAI16-workflow | MICCAI 2016 挑战赛 | 41 视频 | 阶段识别 | Acc ~87-91% | -3 ~ -5% | 跨数据集性能下降,设备/术式差异 |
| AutoLaparo | 多来源 | 21 视频 | 阶段识别 | Acc ~81-85% | -8 ~ -12% | 不同手术流程定义(10 阶段 vs 7 阶段) |
| GraSP | 多来源 | 17 视频 | 器械分割 | — | N/A | 不同标注粒度(分割 vs 二值存在) |
| CATARACTS | 多来源 | 50 视频 | 器械检测 | — | N/A | 不同术种(白内障),零样本迁移 |
§8 基准性能与生态(Benchmarks & Ecosystem)
§8.1 排行榜
手术阶段识别(Cholec80,标准 40:40 划分)
| 排名 | 模型 | 准确率 (%) | Jaccard (%) | 年份 | 评估方式 | 完整引用 | 代码 |
|---|---|---|---|---|---|---|---|
| 1 | SF-TMN (ASFormer) | 95.43 | — | 2023 | Relaxed | Zhang et al., 2023, arXiv:2306.08859 | GitHub |
| 2 | EfficientNetV2-Transformer | 94.9 | — | 2023 | Relaxed | 2023 | — |
| 3 | SKiT | 93.4 | 82.6 | 2024 | Relaxed | 2024 | GitHub |
| 4 | Surgformer | 93.4 | 84.1 | 2024 | Relaxed | Gao et al., 2024, arXiv:2408.03867 | — |
| 5 | Self-KD | 93.24 | — | 2023 | Relaxed | 2023 | — |
| 6 | SurgFM (基础模型) | 92.7 | — | 2025 | Relaxed | 2025, arXiv:2503.19740 | — |
| 7 | Swin Transformer-LSTM | 92.8 | — | 2023 | Relaxed | 2023 | — |
| 8 | ViPeR | 91.7 | — | 2025 | Relaxed | Chandra et al., 2025, IEEE Access | GitHub |
| 9 | LoViT | 91.5 | 81.2 | 2024 | Relaxed | Liu et al., 2024, Medical Image Analysis | GitHub |
| 10 | TMRNet | 90.1 | 79.1 | 2021 | Relaxed | Jin et al., 2021, IPCAI | GitHub |
| 11 | Trans-SVNet | 90.3 | 79.3 | 2021 | Relaxed | Jin et al., 2021, MICCAI | GitHub |
| 12 | TeCNO | 88.6 | 75.1 | 2020 | Relaxed | Czempiel et al., 2020, MICCAI | — |
| 13 | EndoNet (原始) | 81.7 | — | 2017 | Relaxed | Twinanda et al., 2017, IEEE TMI | GitHub |
⚠️ 重要警告:以上排名基于 relaxed boundaries 评估(阶段转换 ±10 秒窗口内不计错误)。在 unrelaxed 评估下,准确率通常降低 1-3 个百分点。不同论文使用的数据划分(32:8:40 vs 40:40)也会影响结果。直接跨论文比较绝对数值前,务必确认评估协议一致。 参见 Funke et al. (2023), “Metrics Matter in Surgical Phase Recognition”。
器械存在检测(Cholec80,标准 40:40 划分)
| 排名 | 模型 | mAP (%) | 年份 | 完整引用 | 代码 |
|---|---|---|---|---|---|
| 1 | SurgFM (基础模型) | 93.7 | 2025 | arXiv:2503.19740 | — |
| 2 | EndoNet (原始) | 81.0 | 2017 | Twinanda et al., 2017, IEEE TMI | GitHub |
器械检测任务的排行榜数据较少,因多数论文聚焦阶段识别。SurgFM 基础模型在器械检测上的 mAP 提升了 12.7 个百分点(93.7% vs 81.0%)。
§8.2 SOTA 总结与选型建议
| 使用场景 | 推荐模型 | 准确率 | 理由 |
|---|---|---|---|
| 复现经典基线 | EndoNet | ~81.7% | 原始论文基线,理解多任务学习范式 |
| 快速实验 | TMRNet / Trans-SVNet | ~90% | 官方代码完善,社区广泛使用 |
| 追求 SOTA | SF-TMN (ASFormer) | ~95.4% | 当前最佳公开结果 |
| 基础模型路线 | SurgFM | ~92.7% | 大规模预训练,数据效率高 |
| 实时推理 | GSViT | ~86.3% | 单帧推理,12.1ms 延迟 |
§8.3 评估协议
标准评估协议(EndoNet 论文确立):
- 数据划分:前 40 个视频训练(video01-40),后 40 个视频测试(video41-80),无验证集
- 阶段识别指标:Accuracy、Precision、Recall、Jaccard(逐阶段计算后取平均)
- 器械检测指标:mAP(7 种器械的 Average Precision 均值)
- 边界处理:原始论文未使用 relaxed boundaries,但后续论文广泛采用 ±10 秒窗口
- 标准差:跨 40 个测试视频计算(而非跨实验重复)
§8.4 相关数据集
| 数据集 | 关系 | 标注类型 | 规模 | 说明 |
|---|---|---|---|---|
| CholecSeg8K | 衍生 | 语义分割(13 类) | 8,080 帧 | 基于 Cholec80 的 17 个视频片段 |
| CholecT50 | 衍生 | 动作三元组 | 50 视频 | 含 45 个 Cholec80 视频 + 5 个新视频 |
| CholecT45 | 衍生 | 动作三元组 | 45 视频 | CholecT50 子集(公开版) |
| Cholec80-Boxes | 扩展 | 边界框 | 5 视频 | 测试集前 5 个视频的器械边界框 |
| CholecInstanceSeg | 扩展 | 实例分割 | 41.9k 帧 | 器械实例 ID + 分割掩码 |
| M2CAI16-workflow | 子集 | 阶段标注 | 41 视频 | MICCAI 2016 挑战赛数据 |
| M2CAI16-tool | 子集 | 器械标注 | — | MICCAI 2016 器械检测挑战赛 |
| AutoLaparo | 独立 | 阶段标注 | 21 视频 | 不同手术流程定义(10 阶段) |
§8.5 关键论文
-
Twinanda, A.P., Shehata, S., Mutter, D., Marescaux, J., de Mathelin, M., & Padoy, N. (2017). “EndoNet: A Deep Architecture for Recognition Tasks on Laparoscopic Videos.” IEEE Transactions on Medical Imaging, 36(1), 86-97. DOI: 10.1109/TMI.2016.2593957
— 奠基论文:提出 Cholec80 数据集和 EndoNet 多任务 CNN 架构,首次将深度学习应用于腹腔镜视频的手术阶段识别和器械检测 -
Jin, Y., Dou, Q., Chen, H., et al. (2021). “SV-RCNet: Workflow Recognition From Surgical Videos Using Recurrent Convolutional Network.” IEEE TMI.
— 时序建模:引入 RCNN + LSTM 架构,将时序信息引入阶段识别 -
Jin, Y., Li, Y., et al. (2021). “TMRNet: Temporal Memory Reasoning for Surgical Workflow Recognition.” IPCAI.
— 记忆增强:引入 temporal memory module,在无需完整视频历史的情况下实现 ~90% 准确率 -
Czempiel, T., Paschali, M., et al. (2020). “TeCNO: Surgical Phase Recognition with Temporal Convolutional Networks.” MICCAI.
— TCN 架构:用 TCN 替代 LSTM,训练更快且性能相当 -
Funke, I., Rivoir, D., & Speidel, S. (2023). “Metrics Matter in Surgical Phase Recognition.” arXiv:2305.13961.
— 评估协议:系统揭示了 Cholec80 上评估不一致问题,提供标准化评估代码 -
Zhang, B., Sarhan, M.H., et al. (2023). “SF-TMN: SlowFast Temporal Modeling Network for Surgical Phase Recognition.” arXiv:2306.08859.
— SOTA 方法:SlowFast 双路径时序建模,当前最佳公开结果 95.43% -
Liu, Y., et al. (2024). “LoViT: Long Video Transformer for Surgical Phase Recognition.” Medical Image Analysis.
— 长视频 Transformer:针对手术长视频设计的 Transformer 架构 -
Surg-3M/SurgFM (2025). “Surg-3M: A Dataset and Foundation Model for Perception in Surgical Settings.” arXiv:2503.19740.
— 基础模型:大规模手术视觉基础模型,在 Cholec80 上达 92.7% 准确率和 93.7% mAP
§8.6 社区活跃度
| 平台 | 指标 | 数值(截至 2026-08) |
|---|---|---|
| Papers with Code | 基准任务数 | 4+(阶段识别、器械检测等) |
| GitHub (CAMMA-public) | 仓库数 | 10+(TF-Cholec80、TMRNet、Trans-SVNet 等) |
| Google Scholar | EndoNet 论文引用 | 1,000+ |
| MICCAI 挑战赛 | CholecTriplet 系列 | 2021-2023 连续举办 |
§8.7 生态快照
| 资源 | 类型 | 链接 | Star/Fork(截至 2026-08) | 为什么值得关注 |
|---|---|---|---|---|
| CAMMA-public/TF-Cholec80 | 官方代码 | GitHub | 200+/80+ | 官方 TensorFlow 实现,含数据加载和 EndoNet 模型 |
| CAMMA-public/Trans-SVNet | 官方代码 | GitHub | 150+/40+ | Trans-SVNet + ASFormer 实现,含预训练权重 |
| CAMMA-public/TMRNet | 官方代码 | GitHub | 100+/30+ | TMRNet 实现,含记忆增强模块 |
| MRUIL/LoViT | 研究代码 | GitHub | 50+/15+ | LoViT 长视频 Transformer 实现 |
| PhaseMetrics | 评估工具 | GitLab | — | 标准化阶段识别评估代码,解决评估不一致问题 |
| CAMMA Datasets | 数据集门户 | Website | — | 所有 Cholec 系列数据集的统一申请入口 |
§9 相关资源与引用(Resources & Citation)
§9.1 BibTeX
@article{twinanda2017endonet,
title={EndoNet: A Deep Architecture for Recognition Tasks on Laparoscopic Videos},
author={Twinanda, Andru P. and Shehata, Sherif and Mutter, Didier and Marescaux, Jacques and de Mathelin, Michel and Padoy, Nicolas},
journal={IEEE Transactions on Medical Imaging},
volume={36},
number={1},
pages={8697},
year={2017},
publisher={IEEE},
doi={10.1109/TMI.2016.2593957}
}
§9.2 官方资源
| 资源 | 链接 |
|---|---|
| CAMMA 数据集主页 | https://camma.unistra.fr/datasets/ |
| Cholec80 数据申请 | https://camma.unistra.fr/datasets/(填写申请表) |
| 官方 GitHub (TF-Cholec80) | https://github.com/CAMMA-public/TF-Cholec80 |
| EndoNet 论文 (IEEE Xplore) | https://ieeexplore.ieee.org/document/7519080 |
| EndoNet 论文 (arXiv) | https://arxiv.org/abs/1602.03012 |
§9.3 衍生数据集资源
| 数据集 | 链接 | 论文 |
|---|---|---|
| CholecSeg8K | Kaggle / HuggingFace | Hong et al., 2020, arXiv:2012.12453 |
| CholecT50 | CAMMA 网站 | Nwoye et al., 2022, Medical Image Analysis |
| CholecInstanceSeg | arXiv | 2024 |
| Cholec80-Boxes | Zenodo | 社区扩展 |
§9.4 相关千方百科条目
- M2CAI16 挑战赛数据集
- AutoLaparo 手术流程数据集
- CATARACTS 白内障手术数据集
- EndoVis Challenges 内窥镜视觉挑战赛
§9.5 推荐阅读顺序
- EndoNet 论文(Twinanda et al., 2017)→ 理解数据集和基线方法
- Metrics Matter 论文(Funke et al., 2023)→ 理解评估协议陷阱
- TMRNet / Trans-SVNet 论文 → 理解时序建模进展
- SF-TMN 论文(Zhang et al., 2023)→ 理解当前 SOTA 方法
- SurgFM 论文(2025)→ 理解基础模型在手术 AI 中的应用
§9.6 许可证信息
Cholec80 采用 CC-BY-NC-SA 4.0(署名-非商业-相同方式共享 4.0)许可证:
- ✅ 允许:非商业研究使用、修改、分发
- ❌ 禁止:商业用途
- 📋 要求:衍生作品须采用相同许可证,须标注原始来源
§9.7 引用本百科
千方病案医数集. "Cholec80 — 腹腔镜胆囊切除术视频数据集 AI-Ready Wikipedia."
https://www.qianfanghub.com/ai-ready-dataset/cholec80/78
§10 AI 使用声明卡(AI Usage Card)
§10.1 撰写页面时使用的 AI 模型
| 模型 | 版本 | 用途 |
|---|---|---|
| Claude | Sonnet 4 | 全文撰写、代码生成、数据分析 |
| WebSearch | — | 文献检索、SOTA 数据收集、事实核查 |
§10.2 AI 参与范围
全文撰写(代码 + 文本 + 表格 + 评估)
§10.3 AI 参考的输入文档
- Twinanda et al. (2017), “EndoNet: A Deep Architecture for Recognition Tasks on Laparoscopic Videos”, IEEE TMI
- CAMMA 官方数据集页面:https://camma.unistra.fr/datasets/
- Funke et al. (2023), “Metrics Matter in Surgical Phase Recognition”, arXiv:2305.13961
- Awesome Medical Dataset - Cholec80:https://github.com/openmedlab/Awesome-Medical-Dataset
- Frontiers (2026), “Bibliometric analysis of deep learning for surgical instrument segmentation”
- 多篇 SOTA 论文(TMRNet、Trans-SVNet、LoViT、Surgformer、SF-TMN、SurgFM、ViPeR)
- SASVi 论文(Springer, 2025)— 视频平均时长数据来源
- CholecInstanceSeg 论文(arXiv:2406.16039)— 衍生数据集信息
§10.4 人工校验表
| 内容模块 | 审核者 | 审核方式 | 审核状态 |
|---|---|---|---|
| §2 医学背景 | 千方病案医学编辑部 | 交叉审核 | ✅ 已通过 |
| §3 数据规格 | 千方病案医学编辑部 | 与 CAMMA 官方文档交叉比对 | ✅ 已验证 |
| §6 代码示例 | 千方病案医学编辑部 | 逻辑审查 | ✅ 已通过 |
| §7 DAIMS 评估 | 千方病案医学编辑部 | 逐项核对 | ✅ 已验证 |
| §8 排行榜 | 千方病案医学编辑部 | 与原始论文交叉比对 | ✅ 已验证 |
页面状态:published(全部内容已完成审核并发布)
