将labelme格式数据转化为标准的coco数据集格式方式
labelme标注图像生成的json格式:
{ "version":"3.11.2", "flags":{}, "shapes":[#每个对象的形状 {#第一个对象 "label":"malignant", "line_color":null, "fill_color":null, "points":[#边缘是由点构成,将这些点连在一起就是对象的边缘多边形 [ 371,#第一个点x坐标 257#第一个点y坐标 ], ... [ 412, 255 ] ], "shape_type":"polygon"#形状类型:多边形 }, { "label":"malignant",#第一个对象的标签 "line_color":null, "fill_color":null, "points":[#第二个对象 [ 522, 274 ], ... [ 561, 303 ] ], "shape_type":"polygon" }, { "label":"malignant",#第二个对象的标签 "line_color":null, "fill_color":null, "imagePath":"../../val2017/000001.jpg",#原始图片的路径 "imageData":"somethingtoolong",#原图像数据通过该字段可以解析出原图像数据 "imageHeight":768, "imageWidth":1024 }
coco标准数据集格式:
COCO通过大量使用AmazonMechanicalTurk来收集数据。COCO数据集现在有3种标注类型:objectinstances(目标实例),objectkeypoints(目标上的关键点),andimagecaptions(看图说话),使用JSON文件存储。
基本的JSON结构体类型
这3种类型共享下面所列的基本类型,包括image、categories、annotation类型。
Images类型:
"images":[ { "height":768, "width":1024, "id":1,#图片id "file_name":"000002.jpg" } ]
categories类型:
"categories":[ { "supercategory":"Cancer",#父类 "id":1,#标签类别id,0表示背景 "name":"benign"#子类 }, { "supercategory":"Cancer", "id":2, "name":"malignant" } ],
annotations类型:
"annotations":[ { "segmentation":[#坐标点的坐标值 [ 418, 256, 391, 293, 406, 323, 432, 340, 452, 329, 458, 311, 458, 286, 455, 277, 439, 264, 418, 293, 391, 256 ] ], "iscrowd":0,#单个的对象(iscrowd=0)可能需要多个polygon来表示 "image_id":1,#和image的id保持一致 "bbox":[#标注的边框值bbox是将segmentation包起来的水平矩形 391.0, 256.0, 67.0, 84.0 ], "area":5628.0,#标注的边框面积 "category_id":1,#所属类别id "id":1#标注边框的id:1,2,3...,n } ]
labelme转化为coco
#-*-coding:utf-8-*- #!/usr/bin/envpython importargparse importjson importmatplotlib.pyplotasplt importskimage.ioasio importcv2 fromlabelmeimportutils importnumpyasnp importglob importPIL.Image classMyEncoder(json.JSONEncoder): defdefault(self,obj): ifisinstance(obj,np.integer): returnint(obj) elifisinstance(obj,np.floating): returnfloat(obj) elifisinstance(obj,np.ndarray): returnobj.tolist() else: returnsuper(MyEncoder,self).default(obj) classlabelme2coco(object): def__init__(self,labelme_json=[],save_json_path='./tran.json'): ''' :paramlabelme_json:所有labelme的json文件路径组成的列表 :paramsave_json_path:json保存位置 ''' self.labelme_json=labelme_json self.save_json_path=save_json_path self.images=[] self.categories=[] self.annotations=[] #self.data_coco={} self.label=[] self.annID=1 self.height=0 self.width=0 self.save_json() defdata_transfer(self): fornum,json_fileinenumerate(self.labelme_json): withopen(json_file,'r')asfp: data=json.load(fp)#加载json文件 self.images.append(self.image(data,num)) forshapesindata['shapes']: label=shapes['label'] iflabelnotinself.label: self.categories.append(self.categorie(label)) self.label.append(label) points=shapes['points']#这里的point是用rectangle标注得到的,只有两个点,需要转成四个点 #points.append([points[0][0],points[1][1]]) #points.append([points[1][0],points[0][1]]) self.annotations.append(self.annotation(points,label,num)) self.annID+=1 defimage(self,data,num): image={} img=utils.img_b64_to_arr(data['imageData'])#解析原图片数据 #img=io.imread(data['imagePath'])#通过图片路径打开图片 #img=cv2.imread(data['imagePath'],0) height,width=img.shape[:2] img=None image['height']=height image['width']=width image['id']=num+1 #image['file_name']=data['imagePath'].split('/')[-1] image['file_name']=data['imagePath'][3:14] self.height=height self.width=width returnimage defcategorie(self,label): categorie={} categorie['supercategory']='Cancer' categorie['id']=len(self.label)+1#0默认为背景 categorie['name']=label returncategorie defannotation(self,points,label,num): annotation={} annotation['segmentation']=[list(np.asarray(points).flatten())] annotation['iscrowd']=0 annotation['image_id']=num+1 #annotation['bbox']=str(self.getbbox(points))#使用list保存json文件时报错(不知道为什么) #list(map(int,a[1:-1].split(',')))a=annotation['bbox']使用该方式转成list annotation['bbox']=list(map(float,self.getbbox(points))) annotation['area']=annotation['bbox'][2]*annotation['bbox'][3] #annotation['category_id']=self.getcatid(label) annotation['category_id']=self.getcatid(label)#注意,源代码默认为1 annotation['id']=self.annID returnannotation defgetcatid(self,label): forcategorieinself.categories: iflabel==categorie['name']: returncategorie['id'] return1 defgetbbox(self,points): #img=np.zeros([self.height,self.width],np.uint8) #cv2.polylines(img,[np.asarray(points)],True,1,lineType=cv2.LINE_AA)#画边界线 #cv2.fillPoly(img,[np.asarray(points)],1)#画多边形内部像素值为1 polygons=points mask=self.polygons_to_mask([self.height,self.width],polygons) returnself.mask2box(mask) defmask2box(self,mask): '''从mask反算出其边框 mask:[h,w]0、1组成的图片 1对应对象,只需计算1对应的行列号(左上角行列号,右下角行列号,就可以算出其边框) ''' #np.where(mask==1) index=np.argwhere(mask==1) rows=index[:,0] clos=index[:,1] #解析左上角行列号 left_top_r=np.min(rows)#y left_top_c=np.min(clos)#x #解析右下角行列号 right_bottom_r=np.max(rows) right_bottom_c=np.max(clos) #return[(left_top_r,left_top_c),(right_bottom_r,right_bottom_c)] #return[(left_top_c,left_top_r),(right_bottom_c,right_bottom_r)] #return[left_top_c,left_top_r,right_bottom_c,right_bottom_r]#[x1,y1,x2,y2] return[left_top_c,left_top_r,right_bottom_c-left_top_c, right_bottom_r-left_top_r]#[x1,y1,w,h]对应COCO的bbox格式 defpolygons_to_mask(self,img_shape,polygons): mask=np.zeros(img_shape,dtype=np.uint8) mask=PIL.Image.fromarray(mask) xy=list(map(tuple,polygons)) PIL.ImageDraw.Draw(mask).polygon(xy=xy,outline=1,fill=1) mask=np.array(mask,dtype=bool) returnmask defdata2coco(self): data_coco={} data_coco['images']=self.images data_coco['categories']=self.categories data_coco['annotations']=self.annotations returndata_coco defsave_json(self): self.data_transfer() self.data_coco=self.data2coco() #保存json文件 json.dump(self.data_coco,open(self.save_json_path,'w'),indent=4,cls=MyEncoder)#indent=4更加美观显示 labelme_json=glob.glob('./Annotations/*.json') #labelme_json=['./Annotations/*.json'] labelme2coco(labelme_json,'./json/test.json')
以上这篇将labelme格式数据转化为标准的coco数据集格式方式就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。