TypeError: Argument 'bb' has incorrect type (expected numpy.ndarray, got list)
from pycocotools.coco import COCO
import json
def check_coco_format(json_file_path):
# 加载JSON文件
with open(json_file_path, 'r') as f:
coco_data = json.load(f)
# 创建COCO实例
coco = COCO()
coco.dataset = coco_data
coco.createIndex()
# 验证格式
ann_ids = coco.getAnnIds()
img_ids = coco.getImgIds()
cat_ids = coco.getCatIds()
# 检查是否存在图像、注释和类别
if not img_ids:
print("错误:缺少图像数据。")
return False
if not ann_ids:
print("错误:缺少注释数据。")
return False
if not cat_ids:
print("错误:缺少类别数据。")
return False
# 验证注释中的图像ID和类别ID是否有效
for ann_id in ann_ids:
ann = coco.loadAnns(ann_id)[0]
if ann['image_id'] not in img_ids:
print(f"错误:注释 {ann_id} 中的图像ID无效。")
return False
if ann['category_id'] not in cat_ids:
print(f"错误:注释 {ann_id} 中的类别ID无效。")
return False
print("COCO格式验证通过。")
return True
# 在此处替换为你的coco_instances.json文件路径
json_file_path = 'path/to/your/coco_instancesxxx.json'
# 检查coco_instances.json文件的格式
check_coco_format(json_file_path)
如果检查成功,那么会返回”COCO格式验证通过。“结果。如果coco标注没有问题,那么进行下面的检查。
def frPyObjects(pyobj, h, w):
# encode rle from a list of python objects
if type(pyobj) == np.ndarray:
objs = frBbox(pyobj, h, w)
elif type(pyobj) == list and len(pyobj[0]) == 4:
objs = frBbox(pyobj, h, w)
elif type(pyobj) == list and len(pyobj[0]) > 4:
objs = frPoly(pyobj, h, w)
elif type(pyobj) == list and type(pyobj[0]) == dict \
and 'counts' in pyobj[0] and 'size' in pyobj[0]:
objs = frUncompressedRLE(pyobj, h, w)
# encode rle from single python object
elif type(pyobj) == list and len(pyobj) == 4:
objs = frBbox([pyobj], h, w)[0]
elif type(pyobj) == list and len(pyobj) > 4:
objs = frPoly([pyobj], h, w)[0]
elif type(pyobj) == dict and 'counts' in pyobj and 'size' in pyobj:
objs = frUncompressedRLE([pyobj], h, w)[0]
else:
raise Exception('input type is not supported.')
return objs
其中,可以看到该函数传入的第一个参数为“pyobj”,该参数对应coco_instancestrain.json/coco_instancesval.json标注文件中的每个segmentation对象,一个典型的segmentation对象格式如下:
{
"id": 414,
"image_id": 36,
"category_id": 2,
# 一个典型的segmentation对象
"segmentation": [
[
241.2121212121212,
173.93939393939394,
242.2121212121212,
173.93939393939394,
243.2121212121212,
173.93939393939394
]
],
"area": 97.0,
"bbox": [
236.0,
168.0,
11.0,
11.0
],
"iscrowd": 0
},
那么,如果报错“raise Exception(‘input type is not supported.’)”,说明frPyObjects()函数的所有if条件不满足,肯定存在个别segmentation对象的len(segmentation[0])的长度不满足大于4(那就是小于等于4,都需要进行判断),这里提供一个修改脚本,将不符合条件的segmentation列表修改为符合条件即可:
import json
import numpy as np
# 首先将frPyObjects()完整函数copy过来,用于之后的判断,对于每个if条件语句,打印对应的标注
def frPyObjects(i, pyobj):
# encode rle from a list of python objects
if type(pyobj) == np.ndarray:
print("{}, {}, {}".format(i, type(pyobj), len(pyobj[0])))
elif type(pyobj) == list and len(pyobj[0]) == 4:
print("{}, {}, {}".format(i, type(pyobj), len(pyobj[0])))
elif type(pyobj) == list and len(pyobj[0]) > 4:
print("{}, {}, {}".format(i, type(pyobj), len(pyobj[0])))
elif type(pyobj) == list and type(pyobj) == dict and 'counts' in pyobj[0] and 'size' in pyobj[0]:
print("{}, {}, {}".format(i, type(pyobj), len(pyobj[0])))
# encode rle from single python object
elif type(pyobj) == list and len(pyobj[0]) == 4:
print("{}, {}, {}".format(i, type(pyobj), len(pyobj[0])))
elif type(pyobj) == list and len(pyobj[0]) > 4:
print("{}, {}, {}".format(i, type(pyobj), len(pyobj[0])))
elif type(pyobj) == dict and 'counts' in pyobj and 'size' in pyobj:
print("{}, {}, {}".format(i, type(pyobj), len(pyobj[0])))
else:
print("{}, {}, {}".format(i, type(pyobj), len(pyobj[0])))
raise Exception('input type is not supported.')
# 然后传入你自己的coco格式标注文件绝对路径
JSON_LOC="path/to/your/coco.json"
#打开json文件
val_json = open(JSON_LOC, "r")
json_object = json.load(val_json)
val_json.close()
# 遍历coco.json文件中的所有segmentation对象,对于每个对象送入frPyObjects()函数进行检查,来找到不符合条件的segmentation对象
for i, instance in enumerate(json_object["annotations"]):
frPyObjects(i, instance["segmentation"])
# 之后,可以根据上述print()打印出来的不符合条件对象的id,来修改对应的segmentation列表(手动修改即可,不符合条件的数量一般很少)
json_object["annotations"][1510]["segmentation"] = [[230.83333333333331, 773.8888888888889, 231.83333333333331, 773.8888888888889, 237.22222222222223, 770.5555555555555]]
# 将修改后的json文件重新写回到coco_instancestrain.json/coco_instancesval.json中即可
val_json = open(JSON_LOC, "w")
json.dump(json_object, val_json)
val_json.close()
一般来说,经过上述步骤就可以实现对coco格式的实例分割标注文件进行一个全面检查,重新运行程序,应该就不会报错了。