将labelme格式数据转化为标准的coco数据集格式方式


Posted in Python onFebruary 17, 2020

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":"something too long ",# 原图像数据 通过该字段可以解析出原图像数据
 "imageHeight": 768,
 "imageWidth": 1024
}

coco标准数据集格式:

COCO通过大量使用Amazon Mechanical Turk来收集数据。COCO数据集现在有3种标注类型:object instances(目标实例), object keypoints(目标上的关键点), and image captions(看图说话),使用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/env python
 
import argparse
import json
import matplotlib.pyplot as plt
import skimage.io as io
import cv2
from labelme import utils
import numpy as np
import glob
import PIL.Image
 
class MyEncoder(json.JSONEncoder):
 def default(self, obj):
  if isinstance(obj, np.integer):
   return int(obj)
  elif isinstance(obj, np.floating):
   return float(obj)
  elif isinstance(obj, np.ndarray):
   return obj.tolist()
  else:
   return super(MyEncoder, self).default(obj)
 
class labelme2coco(object):
 def __init__(self, labelme_json=[], save_json_path='./tran.json'):
  '''
  :param labelme_json: 所有labelme的json文件路径组成的列表
  :param save_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()
 
 def data_transfer(self):
 
  for num, json_file in enumerate(self.labelme_json):
   with open(json_file, 'r') as fp:
    data = json.load(fp) # 加载json文件
    self.images.append(self.image(data, num))
    for shapes in data['shapes']:
     label = shapes['label']
     if label not in self.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
 
 def image(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
 
  return image
 
 def categorie(self, label):
  categorie = {}
  categorie['supercategory'] = 'Cancer'
  categorie['id'] = len(self.label) + 1 # 0 默认为背景
  categorie['name'] = label
  return categorie
 
 def annotation(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
  return annotation
 
 def getcatid(self, label):
  for categorie in self.categories:
   if label == categorie['name']:
    return categorie['id']
  return 1
 
 def getbbox(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)
  return self.mask2box(mask)
 
 def mask2box(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格式
 
 def polygons_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)
  return mask
 
 def data2coco(self):
  data_coco = {}
  data_coco['images'] = self.images
  data_coco['categories'] = self.categories
  data_coco['annotations'] = self.annotations
  return data_coco
 
 def save_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数据集格式方式就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python基础教程之循环介绍
Aug 29 Python
Python中的choice()方法使用详解
May 15 Python
Django Admin实现三级联动的示例代码(省市区)
Jun 22 Python
python 输入一个数n,求n个数求乘或求和的实例
Nov 13 Python
pandas 透视表中文字段排序方法
Nov 16 Python
python 接收处理外带的参数方法
Dec 03 Python
使用 Python 清理收藏夹里已失效的网站
Dec 03 Python
Pytorch实现基于CharRNN的文本分类与生成示例
Jan 08 Python
tensorflow对图像进行拼接的例子
Feb 05 Python
python爬虫基础知识点整理
Jun 02 Python
Python用K-means聚类算法进行客户分群的实现
Aug 23 Python
Python try except else使用详解
Jan 12 Python
开启Django博客的RSS功能的实现方法
Feb 17 #Python
Python3打包exe代码2种方法实例解析
Feb 17 #Python
Django 博客实现简单的全文搜索的示例代码
Feb 17 #Python
Python使用qrcode二维码库生成二维码方法详解
Feb 17 #Python
django2.2 和 PyMySQL版本兼容问题
Feb 17 #Python
基于python3的socket聊天编程
Feb 17 #Python
python词云库wordCloud使用方法详解(解决中文乱码)
Feb 17 #Python
You might like
discuz图片顺序混乱解决方案
2015/07/29 PHP
picChange 图片切换特效的函数代码
2010/05/06 Javascript
jquery中focus()函数实现当对象获得焦点后自动把光标移到内容最后
2013/09/29 Javascript
js查找节点的方法小结
2015/01/13 Javascript
移动端js触摸事件详解
2016/09/18 Javascript
javascript中的后退和刷新实现方法
2016/11/10 Javascript
JS前端开发判断是否是手机端并跳转操作(小结)
2017/02/05 Javascript
JS 调试中常见的报错问题解决方法
2017/05/20 Javascript
Node.js v8.0.0正式发布!看看带来了哪些主要新特性
2017/06/02 Javascript
AngularJS自定义过滤器用法经典实例总结
2018/05/17 Javascript
Vue中使用webpack别名的方法实例详解
2018/06/19 Javascript
Django+Vue跨域环境配置详解
2018/07/06 Javascript
浅谈Vue服务端渲染框架Nuxt的那些事
2018/12/21 Javascript
element-ui table组件如何使用render属性的实现
2019/11/04 Javascript
利用JS如何获取form表单数据
2019/12/19 Javascript
[04:10]2018年度CS GO玩家最喜爱的主播-完美盛典
2018/12/16 DOTA
python3.3教程之模拟百度登陆代码分享
2014/01/16 Python
从零学python系列之从文件读取和保存数据
2014/05/23 Python
Python脚本实现代码行数统计代码分享
2015/03/10 Python
python中numpy包使用教程之数组和相关操作详解
2017/07/30 Python
疯狂上涨的Python 开发者应从2.x还是3.x着手?
2017/11/16 Python
python使用rpc框架gRPC的方法
2018/08/24 Python
详解pandas如何去掉、过滤数据集中的某些值或者某些行?
2019/05/15 Python
pip 安装库比较慢的解决方法(国内镜像)
2019/10/06 Python
Python单链表原理与实现方法详解
2020/02/22 Python
基于Python绘制美观动态圆环图、饼图
2020/06/03 Python
解决TensorFlow训练模型及保存数量限制的问题
2021/03/03 Python
HTML5实现WebSocket协议原理浅析
2014/07/07 HTML / CSS
HTML5 通过Vedio标签实现视频循环播放的示例代码
2020/08/05 HTML / CSS
Camper鞋西班牙官方网上商店:西班牙马略卡岛的鞋类品牌
2019/03/14 全球购物
怎么样写好简历中的自我评价
2013/10/25 职场文书
报关专员求职信范文
2014/02/22 职场文书
2014入党积极分子批评与自我批评思想汇报
2014/09/20 职场文书
2014年学校食堂工作总结
2014/11/25 职场文书
2016年幼儿园教师师德承诺书
2016/03/25 职场文书
浅谈mysql执行过程以及顺序
2021/05/12 MySQL