news 2026/9/8 22:05:05

全景牙齿X光片牙位标注数据集制作:从FDI编号到Pascal VOC格式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
全景牙齿X光片牙位标注数据集制作:从FDI编号到Pascal VOC格式

简介:全景牙齿X光片牙位标注数据集面向医疗影像智能分析与目标检测任务,使用Labelimg完成精细标注,内含经过筛选的清晰X光片与对应XML标注文件。压缩包共210个文件,包括105张JPG影像和105个XML标注,体积约28.49MB,文件与标注一一对应、结构紧凑,可直接用于Faster R-CNN、YOLO、SSD等主流目标检测模型的训练与验证,也方便自行划分训练集和验证集。XML文件按标准格式记录每颗牙齿的边界框坐标与类别,图片覆盖多种牙齿状态和位置,能有效降低数据清洗与人工标注时间成本,并提升模型在不同牙位识别、龋齿检测等场景下的泛化能力。目前已有642人学习下载,适合医疗影像算法工程师、AI研究人员及牙科智能诊断系统开发者,可辅助开展牙位定位、口腔疾病初筛等应用探索。 做口腔AI相关项目时,第一步往往不是选模型,而是先解决数据问题。全景牙齿X光片(也叫曲面断层片、口腔全景片)上的牙齿牙位标注,难处其实不在“画框”本身,而在于“这个框里的牙齿到底叫什么名字、编号得标对”。我整理的这份全景牙齿X光片牙齿牙位标注数据集,就是围绕这个需求做的:用labelimg逐张框出牙冠区域,并把每一颗牙标成对应的FDI牙位编号,最终为每张图片生成一份精细的Pascal VOC格式XML标注文件。这份数据很适合正在训练目标检测模型、做口腔影像AI科研,或者需要一套现成标注参考来做毕业设计的同学。

我会在这篇博文里把整套制作思路、标注规范、XML格式解析方法,以及我在实操中踩过的坑全部拆开讲清楚。包括为什么选labelimg而不是其他标注工具、牙位编号体系怎么设计、标注边界怎么判断、XML文件怎么批量校验和转换为YOLO格式,以及最常遇到的“labelimg闪退”“正方形框切换不生效”这类问题的处理办法。

1. 从零构建牙位标注数据集:为什么值得做

1.1 这类数据集的真实用途

很多算法工程师一开始低估了牙科影像标注的复杂度,以为这就是普通的目标检测数据集,把“牙齿”当一个大类标上去就完事了。但实际临床和科研需要的往往是“牙位级”的定位——也就是说,不仅要告诉模型“这里有颗牙”,还得告诉它“这是右上颌第一磨牙,FDI编号是16”。

这个粒度直接决定了后续AI应用的上限。举个例子,做龋齿筛查时,如果模型只能输出“牙科全景片里有异常”,医生没法用;但如果模型能输出“16号牙远中邻面疑似龋坏”,医生就能直接复核并纳入诊断路径。再比如智齿拔除辅助、正畸方案里的牙齿排列分析、牙科保险理赔里的牙齿计数与缺牙识别,这些场景全都依赖牙位级检测模型。而这种模型的基础,就是一份牙位标注严格正确的数据集。

也正因如此,我才坚持在用labelimg标注时直接以FDI编号作为类别名,而不是用“切牙”“磨牙”这种宽泛名称。这会让下游模型天然学会输出临床可用的牙位信息,省去后续做类别映射的麻烦。

1.2 一份合适的牙科数据集应该长什么样

从数据工程的角度看,一份合格的牙位标注数据集至少要满足三个条件。

第一,图片要经过筛选,成像清晰、层次分明,不能把大量重度模糊、严重运动伪影或缺失一半牙列的片子直接堆进来,否则会严重拖累训练效果。第二,标注框要落在牙冠区域,因为牙根在二维全景片上经常与邻牙、骨组织、伪影重叠,边界极不稳定;牙冠的形态和位置相对可靠,适合作为目标框的基准。第三,XML标注文件必须完整且可解析,每一项的类别名、坐标值、图像尺寸都要能对得上。

这份数据集在选择图片时,我自己定的筛选标准是:牙列连续度较好、无大范围金属伪影遮挡、上下颌咬合关系基本可见。每张片子上的每颗牙都独立标注,缺失牙不强行标注,但保留天然缺失和拔牙后愈合状态的样本,这样模型在真实场景里遇到缺牙也能正确处理。

2. 全景X光片的成像特点与标注难点

2.1 看懂全景片:曲面断层成像的基本特征

做标注前必须先理解全景片的成像原理,否则很多边界判断会出错。全景片使用的“曲面断层摄影”技术,是让X射线源和探测器围绕患者头部旋转,把弧形的上下颌骨展开成一张二维平面图像。这就有点像把一个弧形的大地拍成一张长卷轴照片——整体结构一目了然,但嘴角、磨牙后区、颧骨投影等区域会出现不同程度的几何形变和重叠。

在全景片上,牙冠和牙根都能看到,但牙根的清晰度受很多因素影响。下颌神经管、上颌窦底、鼻腔底这些解剖结构可能叠加在牙根区域,造成局部低密度影或双线影,看起来像“根尖阴影”,其实只是正常解剖结构。如果在标注时把框画到这些区域,模型就很容易混淆。

我的处理习惯是:标注框一律以牙冠及其颈缘线为界,如果牙根清晰可见且与邻牙边界分得清楚,可以适当包住根中1/3,但绝不要硬把根尖包进去。根尖区域的影像干扰太多,冒然扩大框只会增加类别间的特征重叠。

2.2 标注边界判据:牙冠、邻接点与重叠区

全景片里相邻牙之间通常会有明显的邻接接触点,前牙区邻间隙窄,后牙区邻间隙稍微宽一些。标注的时候最需要留意的就是相邻牙冠的边界不要互相侵蚀。我的经验是:先放大图像,找到牙冠与牙冠之间的“缝隙线”——牙釉质在X光片上表现为高密度亮带,牙本质密度稍低,所以相邻牙冠之间通常存在一条可辨认的细线。沿着这条线切开,就是两颗牙的边界。

如果遇到邻面重叠严重的情况,比如重度拥挤或牙齿倾斜,就看牙体长轴的方向。每颗牙大体上沿着自己的牙体长轴排列,从牙冠中心向根方延伸。当两牙投影重叠时,优先按照牙冠暴露出来的外轮廓画框,宁可少包住一些模糊区域,也不要为了“看起来完整”而把相邻牙的牙冠划进来。

另外需要特别注意的是牙釉质的高亮伪影。全景片边缘的金属修复体,比如烤瓷冠、种植体、颌面部金属饰品,会产生放射状或条带状伪影。这类伪影区域里的牙齿形态是被破坏的,标注时如果实在看不清边界,我的做法是标出可辨认的牙冠轮廓,同时在数据整理时把这类样本单独分开,不要让它们占训练集的比例过高。

3. 牙位编号体系与标注规范设计

3.1 FDI牙位标记法速查

标注类别之前,必须先确定牙位编号体系。目前全球口腔医学领域最通用的是FDI牙位标记法,全称是Fédération Dentaire Internationale,国际牙科联盟提出的两位数字系统。第一位数代表象限,第二位数代表牙位,从中线往后依次从1排到8。

成年人恒牙一共32颗,以患者自身为参照,分为四个象限:右上象限为1,左上象限为2,左下象限为3,右下象限为4。每颗牙在对应象限里的编号如下表:

牙位编号对应牙齿常见别名
1中切牙门牙
2侧切牙侧门牙
3尖牙犬齿、虎牙
4第一前磨牙第一双尖牙
5第二前磨牙第二双尖牙
6第一磨牙六龄齿
7第二磨牙十二龄齿
8第三磨牙智齿

举例来说,“11”就是右上中切牙,“16”是右上第一磨牙,“38”是左下智齿。如果是混合牙列期的儿童片,乳牙用5、6、7、8开头来区分象限,即51-55、61-65、71-75、81-85,但我这份数据集以成人恒牙为主,因此类别名集中在11到48之间。

3.2 定义一套能落地的标注规范

标注规范的好坏,直接影响数据集的可用性。我最终采用的原则是:类别名直接使用两位数字字符串,比如“11”“12”“33”“48”,而不是“upper_right_central_incisor”这类长名称。原因有两个:一是模型输出“16”这种编号,程序里可以直接跟FDI体系对接,临床含义明确;二是labelimg里输入长类别名很容易拼错,而且会在下拉框里铺满一长串,影响标注效率。

在边界判断上,我要求标注框紧贴牙冠外缘,保证牙冠完整包住但不外扩太多。两颗邻牙之间的距离很近,但你不需要让框与框之间的空隙为零,框稍微触碰甚至轻微重叠都可以接受,只要牙冠主体没有被“吃”掉就行。缺失牙不标注,但这里要区分两种情况:一种是牙齿根本没萌出或者被拔除,另一种是牙冠被严重破坏只剩下残根。我倾向于只保留天然缺牙、且牙位通过邻牙关系可以推断的样本;残根牙如果实在无法判断牙冠轮廓,也不标,宁可少标也不要标错。

修复体的处理上,我是这样规定的:全冠修复牙、种植牙如果整体形态完整、牙冠边界清晰,就正常标注;但如果高密度金属修复体产生了严重星芒状伪影,导致边界无法确认,就跳过该牙。这条规则保证了数据集不会因为伪影出现大量“看起来是金属放射线”的错误框。

4. labelimg标注实操全流程

4.1 安装与环境准备

labelimg是一款非常经典的开源图像标注工具,支持PascalVOC和YOLO两种格式。安装方式非常简单:

pip install labelimg

如果网络环境不好,也可以先安装PyQt5再装labelimg,或者用conda:

conda install -c conda-forge labelimg

装好之后在命令行输入labelimg回车就能打开窗口。需要注意一点:labelimg依赖PyQt5,如果机器上同时装了多个Python环境,最好先确认启动的是哪个环境里的labelimg。我建议单独建一个标注用的虚拟环境,避免依赖冲突。

数据准备阶段,把全景X光片统一转成jpg或png格式,文件名尽量用英文和数字,比如pano_001.jpg。早期我用过中文文件名,结果在XML解析和后续训练时遇到过编码兼容问题,后来就全部改成英文命名了。

4.2 标注时的核心设置与工作流

打开labelimg后,第一件事是确认标注格式。点击左侧“PascalVOC”按钮切换到XML格式,如果按钮显示的是“YOLO”,说明当前是txt输出模式。确保XML模式下标注才会生成你要的.xml文件。

熟悉界面的布局很重要:左侧是图像预览和标注属性区,右侧是图像操作区,底部是当前图像文件路径。在标注之前,我喜欢先在“Open Dir”里打开图片目录,再把“Change Save Dir”指定到一个专门的annotation目录,这样XML文件和图片分开存,后面整理数据会清爽得多。

标注的画框流程其实很简单:

  1. 点击界面左侧的“Create RectBox”按钮,或者在图像区按快捷键W,进入画框状态。
  2. 在牙冠左上角按住鼠标左键,拖动到牙冠右下角,松开后弹出标签选择框。
  3. 输入或选择对应的FDI编号(比如“16”),点OK确认。
  4. 按Ctrl+S保存当前图片的标注,然后按D切到下一张图片继续。

实际操作时,尤其是处理一张有28颗牙的全景片,每张图至少需要3-5分钟。我一般先放大图像,对照牙位分布图逐象限标注,顺序是右上→左上→左下→右下,这样能有效减少漏标和错位。

4.3 快捷键与效率提升技巧

标注几千张图片是个体力活,熟练使用快捷键能省下大量时间。下面是我最常用的快捷键清单:

快捷键功能
W创建矩形框
A / D上一张 / 下一张图片
Ctrl + S保存当前标注
Ctrl + 滚轮缩放图像
滚轮上下滚动图像
Delete删除当前选中的框
Ctrl + E编辑当前框的标签
方向键移动当前选中的框

有一个特别实用的组合:在创建框之前,先用Ctrl+滚轮把牙冠区域放到足够大,画完框之后再按Ctrl+0恢复原始大小查看整体效果。这样做能明显降低相邻牙框偏移的概率。另外,如果发现某颗牙的框稍微偏了,不要删掉重画,直接选中这个框,用方向键微调即可。

关于网上经常被问到的“切换正方形框不生效”问题,我的结论是:labelimg本身并没有“锁定正方形框”的内置功能,默认画出来的就是任意矩形。网上有些人说按某个键可以强制正方形,其实是把其他软件的快捷键记混了。如果必须使用正方形框标注,最稳定的是画完矩形后在属性面板里手动把框的高和宽改成相同像素值,或者用Python脚本批量校正。

5. XML标注文件解析与格式转换

5.1 Pascal VOC XML结构逐项拆解

labelimg在PascalVOC模式下生成的XML文件,本质上是一种结构化的描述文件,用标签对的形式存储了图片路径、尺寸以及每一个目标的类别和坐标。下面是一个典型例子:

<annotation> <folder>pano_images</folder> <filename>pano_001.jpg</filename> <path>/home/user/pano_images/pano_001.jpg</path> <source> <database>Unknown</database> </source> <size> <width>2048</width> <height>1024</height> <depth>3</depth> </size> <segmented>0</segmented> <object> <name>11</name> <pose>Unspecified</pose> <truncated>0</truncated> <difficult>0</difficult> <bndbox> <xmin>120</xmin> <ymin>240</ymin> <xmax>160</xmax> <ymax>280</ymax> </bndbox> </object> </annotation>

这里最核心的是size节点和object节点。size里记录了图片的宽、高和通道数,这是后续坐标归一化的重要依据。每个object节点对应一个目标检测框,name是类别名,也就是FDI牙位编号,bndbox里存了框的左上角(xmin, ymin)和右下角(xmax, ymax)坐标,单位是像素。

5.2 用Python批量解析与可视化校验

数据标注完成后,第一件事不是急着扔进模型训练,而是先写脚本解析这些XML,检查有没有类别名拼错、坐标越界、框面积异常等问题。我用Python标准库里的xml.etree.ElementTree就能完成这项工作。

统计各类别数量:

import glob import xml.etree.ElementTree as ET def count_classes(xml_dir): class_count = {} for xml_file in glob.glob(xml_dir + "/*.xml"): tree = ET.parse(xml_file) root = tree.getroot() for obj in root.findall("object"): name = obj.find("name").text class_count[name] = class_count.get(name, 0) + 1 return class_count result = count_classes("annotations") for cls, cnt in sorted(result.items()): print(f"{cls}: {cnt}")

运行后,我会重点看两个地方:第一是类别名是否都在FDI合法范围内,第二是每张图的平均目标数量是否符合预期。每张全景片正常应该有25颗以上的标注框,如果某张图只有十几个框,说明漏标了,需要回去补标。

还需要检查坐标是否越界,也就是xmax是否超过图片宽度、ymax是否超过图片高度:

def check_bounds(xml_file, img_w, img_h): tree = ET.parse(xml_file) root = tree.getroot() size = root.find("size") w = int(size.find("width").text) h = int(size.find("height").text) for obj in root.findall("object"): box = obj.find("bndbox") xmin = int(box.find("xmin").text) ymin = int(box.find("ymin").text) xmax = int(box.find("xmax").text) ymax = int(box.find("ymax").text) if xmin < 0 or ymin < 0 or xmax > w or ymax > h: print(f"越界: {xml_file}, {obj.find('name').text}")

如果要把数据转成YOLO格式训练,核心逻辑是把PascalVOC的像素坐标归一化到0到1之间。计算公式是:中心点x=(xmin+xmax)/2/w,中心点y=(ymin+ymax)/2/h,宽度=(xmax-xmin)/w,高度=(ymax-ymin)/h。

我习惯写一个批量转换脚本,顺便做可视化校验。所谓可视化校验,就是把每一张图片的框画出来,叠在原始X光片上,人工扫一眼确认框和牙冠的对齐程度。这一步特别值得做,因为从坐标数字上看不出来的“轻微偏左”“框太大”等问题,在可视化图里一秒就能发现。

6. 常见问题与排查技巧实录

做标注做久了,各种工具链问题都会遇到。我把自己踩过的坑整理成了一张速查表,给各位参考:

现象常见原因解决方案
labelimg打开后闪退PyQt5版本冲突或图像尺寸过大使用虚拟环境重新安装PyQt5,或先压缩图片分辨率再标注
标注格式变成txt而不是xml界面左侧选中了YOLO模式点击“PascalVOC”切换回XML模式
切换正方形框不生效labelimg无内置正方形锁定功能手动微调框的宽高像素值,或用脚本批量校正
中文文件名导致XML路径乱码系统编码与XML编码不一致图片和文件夹全部改成英文命名
XML文件双击打不开编辑软件关联错误用文本编辑器打开,或用Python脚本解析校验
标注框整体偏移缩放图像后未注意坐标基准标注完成后统一可视化复查,发现偏移批量修正

有几个问题值得多说两句。

第一个是labelimg闪退。这通常发生在打开超高分辨率全景片,比如4000x2000以上尺寸的时候。我自己的方案是先把原始DICOM或超大图片缩放到宽边2048像素,既保证牙冠细节可见,又能稳定运行标注工具。

第二个是XML文件“打不开”。实际上XML就是纯文本文件,用记事本、VS Code、Sublime Text都能打开。如果用Excel双击打开XML出现乱码,不是文件坏了,而是关联程序选错了。我推荐用VS Code打开,装一个XML插件还能自动格式化嵌套结构,分析速度快很多。

第三个是标注类别名不一致。比如同一颗牙第一张图标成“16”,第二张图标成“016”,或者混入“upper 16”这种带空格的命名,会导致训练时类别数爆炸且准确率骤降。解决方法是写完标注后用脚本做一次类别名白名单过滤,凡是FDI编号之外的类别全部标记出来人工复核。

写在最后的一点经验

整个数据集从出片、初筛、规范制定、逐张标注到XML校验,最耗时其实不是画框,而是规范的统一。标注人员心里要时刻清楚:这个框包住的是牙冠、牙根根尖3/4还是整个牙齿,两颗邻牙重叠时以哪边为准,金属伪影覆盖时是标还是不标。这套标准只有固化到操作流程里,数据集的精细度才能稳定体现出来。

我个人最大的体会是,医学影像标注领域里,“能用”和“好用”的差距,基本都藏在标注规范和质检流程里。如果你也打算做一套自己的牙齿数据集,建议先从100张图开始,标完全部用可视化脚本检查一遍,把暴露出来的边界问题逐条修订进规范,再回到第101张图继续标。这样迭代出来的数据集,拿去训YOLOv8也好,训RTMDet也好,出来的模型指标和实际落地的稳定性都会比“闭着眼睛一顿标”强太多。

另外,做这类数据集一定要重视影像数据的合规使用。全景X光片属于敏感的医疗健康信息,使用前必须完成患者隐私脱敏,确保不包含姓名、病历号等身份信息,且用途仅限于符合规定的科研或教学场景。从源头做好合规,整个项目才能走得更远。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/8 22:04:53

第一次跑通大模型强化学习,到底要先做对哪几件事?

第一次跑通大模型强化学习&#xff0c;到底要先做对哪几件事&#xff1f; 【免费下载链接】trl Train transformer language models with reinforcement learning. 项目地址: https://gitcode.com/GitHub_Trending/tr/trl TRL 是大模型强化学习的后训练工具包&#xff1…

作者头像 李华
网站建设 2026/9/8 22:03:56

如何用 PDF 翻译工具把英文论文快速翻成中文且保住公式

如何用 PDF 翻译工具把英文论文快速翻成中文且保住公式 【免费下载链接】PDFMathTranslate [EMNLP 2025 Demo] PDF scientific paper translation with preserved formats - 基于 AI 完整保留排版的 PDF 文档全文双语翻译&#xff0c;支持 Google/DeepL/Ollama/OpenAI 等服务&a…

作者头像 李华
网站建设 2026/9/8 22:03:01

低压配电网拓扑辨识与可视化系统源码解析:SpringMVC+MyBatis+高德GIS实践

简介&#xff1a;低压配电网拓扑辨识与可视化系统源码面向电力信息化开发人员及高校毕业设计者&#xff0c;是一套基于SpringMVC与MyBatis框架&#xff0c;并结合高德GIS与SVG矢量图形技术的完整工程。源码实现低压配电网拓扑结构的自动辨识与图形化展示&#xff0c;打通GIS地理…

作者头像 李华
网站建设 2026/9/8 22:02:48

Steam云存档冲突原理与实战诊断指南

1. 云存档冲突不是错误&#xff0c;而是Steam在替你做关键决策“Steam提示‘云存档冲突’&#xff0c;该怎么选&#xff1f;”——这句话最近在游戏社区高频出现&#xff0c;尤其集中在《空洞骑士》《星露谷物语》《蔚蓝》《哈迪斯》这几款存档敏感型独立游戏中。我连续三周在S…

作者头像 李华