一、问题描述
最近使用 LabelImg 标注数据时,点击下一张图片直接闪退,并出现如下错误:
Traceback (most recent call last):
File "e:\python38\lib\site-packages\labelImg\labelImg.py", line 1376, in open_next_image
self.load_file(filename)
File "e:\python38\lib\site-packages\labelImg\labelImg.py", line 1111, in load_file
self.show_bounding_box_from_annotation_file(file_path)
File "e:\python38\lib\site-packages\labelImg\labelImg.py", line 1144, in show_bounding_box_from_annotation_file
self.load_yolo_txt_by_filename(txt_path)
File "e:\python38\lib\site-packages\labelImg\labelImg.py", line 1557, in load_yolo_txt_by_filename
t_yolo_parse_reader = YoloReader(txt_path, self.image)
File "e:\python38\lib\site-packages\libs\yolo_io.py", line 112, in __init__
self.parse_yolo_format()
File "e:\python38\lib\site-packages\libs\yolo_io.py", line 143, in parse_yolo_format
label, x_min, y_min, x_max, y_max = self.yolo_line_to_shape(class_index, x_center, y_center, w, h)
File "e:\python38\lib\site-packages\libs\yolo_io.py", line 125, in yolo_line_to_shape
label = self.classes[int(class_index)]
IndexError: list index out of range
二、问题原因分析
错误发生在:
label = self.classes[int(class_index)]
说明程序正在根据类别编号(class_index)从 classes.txt 中读取对应类别名称。
例如:
classes.txt
person
car
bus
那么类别编号只能是:
0
1
2
如果某个标注文件中出现:
3 0.5 0.5 0.2 0.3
此时 LabelImg 会尝试执行:
self.classes[3]
但实际上:
self.classes = ["person", "car", "bus"]
索引最大只能到 2。
因此就会出现:
IndexError: list index out of range
三、常见出现原因
情况1:修改了类别数量
例如最开始:
0 person
1 car
2 bus
3 bicycle
后来删除了:
bicycle
classes.txt 变成:
person
car
bus
但是旧标签文件中仍然存在:
3 0.52 0.41 0.12 0.15
此时打开对应图片就会报错。
情况2:数据集合并
多个数据集合并时:
数据集A:
0 person
1 car
数据集B:
0 person
1 car
2 bus
如果直接混合使用:
classes.txt
与
labels/*.txt
就容易出现类别编号越界的问题。
情况3:标注工具导出异常
某些转换脚本可能会生成:
99 0.5 0.5 0.2 0.2
或者
-1 0.5 0.5 0.2 0.2
导致 LabelImg 无法正常解析。
四、快速定位错误标签
数据量小时可以手动查找。
但如果有几万张图片,逐个打开根本不现实。
下面给出一个检测脚本。
import os
label_dir = r"D:\Document_CARS\data\11\11_20260129_HH_12634\labels"
classes_path = os.path.join(label_dir, "classes.txt")
with open(classes_path, "r", encoding="utf-8") as f:
num_classes = len(
[line.strip() for line in f if line.strip()]
)
print("类别数:", num_classes)
for root, _, files in os.walk(label_dir):
for f in files:
if not f.endswith(".txt"):
continue
if f == "classes.txt":
continue
path = os.path.join(root, f)
with open(path, "r", encoding="utf-8") as fp:
for line_no, line in enumerate(fp, 1):
line = line.strip()
if not line:
continue
try:
cls = int(line.split()[0])
if cls >= num_classes:
print("\n发现异常:")
print("文件:", path)
print("行号:", line_no)
print("内容:", line)
print("类别:", cls)
except Exception:
print("\n格式错误:")
print(path)
print(line)
五、运行效果
假设:
classes.txt
内容为:
person
car
bus
共 3 类。
而某标签文件存在:
5 0.534 0.427 0.231 0.145
运行后会输出:
类别数: 3
发现异常:
文件: xxx.txt
行号: 7
内容: 5 0.534 0.427 0.231 0.145
类别: 5
这样就能快速定位到问题文件。
六、解决办法
找到异常文件后:
方法1:修改类别编号
例如:
5 0.534 0.427 0.231 0.145
改为:
2 0.534 0.427 0.231 0.145