参考:使用Segment Anything(SAM)模型进行自动标注_sam自动标注-CSDN博客
在使用过程中发现了一些问题:
1.标注过程中出现闪退,terminal报错:
TypeError: Argument 'bb' has incorrect type (expected numpy.ndarray, got list)
问题原因:
salt/dataset_explorer.py文件中annotation['segmentation']列表的格式出错
def add_annotation(self, image_id, category_id, mask, poly=True):
if mask is None:
return
annotation = parse_mask_to_coco(
image_id, self.global_annotation_id, mask, category_id, poly=poly
)
self.__add_to_our_annotation_dict(annotation)
self.coco_json["annotations"].append(annotation)
self.global_annotation_id += 1
打印字典annotation:
{'id': 479, 'image_id': 150, 'category_id': 1, 'bbox': [0.0, 157.0, 110.0, 162.0], 'area': 17820.0, 'iscrowd': 0, 'segmentation': [[81.0, 157.5, 81.0, 157.5], [0.0, 222.5, 6.0, 221.5, 12.0, 217.5, 19.0, 214.5, 25.0, 208.5, 32.0, 205.5, 37.0, 206.5, 48.0, 206.5, 49.0, 207.5, 59.0, 207.5, 60.0, 208.5, 75.0, 208.5, 76.0, 209.5, 88.0, 209.5, 89.0, 210.5, 95.0, 210.5, 99.0, 212.5, 104.0, 213.5, 106.5, 218.0, 106.5, 232.0, 107.5, 233.0, 107.5, 250.0, 108.5, 251.0, 108.5, 269.0, 109.5, 270.0, 109.5, 288.0, 108.5, 290.0, 101.0, 296.5, 100.0, 296.5, 93.0, 303.5, 92.0, 303.5, 88.5, 308.0, 77.0, 317.5, 74.0, 318.5, 69.0, 318.5, 64.0, 317.5, 59.0, 315.5, 55.0, 315.5, 50.0, 313.5, 45.0, 313.5, 44.0, 312.5, 32.0, 310.5, 27.0, 308.5, 22.0, 308.5, 17.0, 307.5, 12.0, 305.5, 7.0, 305.5, 6.0, 304.5, 0.0, 303.5]]}
发现'segmentation'中第一个元素为[81.0, 157.5, 81.0, 157.5],表示分割出的对象起始坐标和结束坐标分别为[81.0, 157.5,]和[81.0, 157.5],即sam选中了一个像素点,此时会将分割格式的标注误认为边界框格式的标注,以下是文心一言的解释:
当处理图像标注数据时,尤其是在使用像COCO(Common Objects in Context)这样的数据集时,对象通常会有两种常见的标注方式:边界框(bounding box)和分割(segmentation)。
边界框(Bounding Box):
边界框是一个矩形区域,它用四个数值来定义:(x1, y1, width, height)
。其中 (x1, y1)
是矩形左上角的坐标,width
和 height
分别是矩形的宽度和高度。这种标注方式简单快捷,但不够精确,因为它不能准确描述对象的形状。
分割(Segmentation):
分割是一种更精确的标注方式,它使用多边形来逼近对象的形状。在JSON格式的数据中,这种分割通常表示为一个点的列表,其中每个点都是 (x, y)
坐标。例如,一个五角星可能有五个顶点,每个顶点都有一个 (x, y)
坐标,这些坐标会组成分割的列表。
当代码中提到“如果 segmentation 的第一个元素长度为4”,这通常意味着在处理分割数据时,程序预期会看到一个由多个点组成的列表,但实际上却遇到了一个长度为4的列表。由于边界框通常由四个数值定义(尽管它们描述的是一个矩形区域,而不是点列表),因此这种长度为4的列表很可能是误写为了边界框格式的分割。
解决:salt/dataset_explorer.py文件中
def add_annotation(self, image_id, category_id, mask, poly=True):
if mask is None:
return
annotation = parse_mask_to_coco(
image_id, self.global_annotation_id, mask, category_id, poly=poly
)
# todo 直接删除像素点
################################################################
i = 0
while i < len(annotation['segmentation']):
if len(annotation['segmentation'][i]) == 4:
print(annotation['segmentation'][i])
annotation['segmentation'].pop(i)
else:
i += 1
#################################################################
self.__add_to_our_annotation_dict(annotation)
self.coco_json["annotations"].append(annotation)
self.global_annotation_id += 1
2.图像未标注,执行撤回时闪退
解决:salt/dataset_explorer.py文件中
def __delet_to_our_annotation_dict(self, image_id):
# 检查该图像中的标注情况,未标注返回True
if image_id not in self.annotations_by_image_id:
return True
elif len(self.annotations_by_image_id[image_id]) == 0:
return True
else:
self.annotations_by_image_id[image_id].pop(-1)
return False
def delet_annotation(self, image_id):
empty = self.__delet_to_our_annotation_dict(image_id)
# 未标注则打印stop
if empty:
print("stop!!!")
return
else:
self.coco_json["annotations"].pop(-1)
self.global_annotation_id -= 1
3.其他
顺序标注图片,方便标注视频生成的图片
打印图片名称及数量
A,D左右切换图片时自动保存结果
更改键位,方便操作:空格标注,shift撤回
增加快进(x键)快退(z键)
可输入初始处理的图片编号,并跳转
·改键可在salt/interface.py中自行操作
4.使用技巧
鼠标右键可删除区域
撤回操作仅限当前图片,若对之前标注的图片撤回会删除最后一次标注!!!
转换好的xml标签文件可直接在labelimg中查看并修改(将标注文件的保存地址改为你的标注文件位置),个人认为比cocoviewer好用
5.下载
文件中不包含权重sam_vit_h_4b8939.pth,请自行下载,下载好后放入文件夹即可:https://dl.fbaipublicfiles.com/segment_anything/sam_vit_h_4b8939.pth
项目文件在夸克网盘:https://pan.quark.cn/s/8d1e07867e08