将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中的字典详细介绍
Sep 18 Python
Python素数检测实例分析
Jun 15 Python
python中实现迭代器(iterator)的方法示例
Jan 19 Python
一张图带我们入门Python基础教程
Feb 05 Python
一个基于flask的web应用诞生(1)
Apr 11 Python
用python写个自动SSH登录远程服务器的小工具(实例)
Jun 17 Python
Django中使用Celery的教程详解
Aug 24 Python
python操作文件的参数整理
Jun 11 Python
python禁用键鼠与提权代码实例
Aug 16 Python
python global关键字的用法详解
Sep 05 Python
pytorch 模拟关系拟合——回归实例
Jan 14 Python
pytorch--之halfTensor的使用详解
May 24 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
PHP发送短信代码分享
2015/08/11 PHP
php gd等比例缩放压缩图片函数
2016/06/12 PHP
laravel Model 执行事务的实现
2019/10/10 PHP
(推荐一个超好的JS函数库)S.Sams Lifexperience ScriptClassLib
2007/04/29 Javascript
js getBoundingClientRect() 来获取页面元素的位置
2010/11/25 Javascript
JQuery打造省市下拉框联动效果
2014/05/18 Javascript
js获取字符串最后一位方法汇总
2014/11/13 Javascript
JavaScript学习笔记之数组随机排序
2016/03/23 Javascript
结合代码图文讲解JavaScript中的作用域与作用域链
2016/07/05 Javascript
jQuery实现动态文字搜索功能
2017/01/05 Javascript
Bootstrap实现各种进度条样式详解
2017/04/13 Javascript
jquery中有哪些api jQuery主要API
2017/11/20 jQuery
JavaScript类数组对象转换为数组对象的方法实例分析
2018/07/24 Javascript
Vue使用NPM方式搭建项目
2018/10/25 Javascript
python使用smtplib模块通过gmail实现邮件发送的方法
2015/05/08 Python
python 默认参数问题的陷阱
2016/02/29 Python
Python脚本实现12306火车票查询系统
2016/09/30 Python
简单谈谈Python中的闭包
2016/11/30 Python
Python字符串处理实例详解
2017/05/18 Python
Python初学时购物车程序练习实例(推荐)
2017/08/08 Python
使用Turtle画正螺旋线的方法
2017/09/22 Python
python 对类的成员函数开启线程的方法
2019/01/22 Python
使用python画出逻辑斯蒂映射(logistic map)中的分叉图案例
2020/12/11 Python
波兰最大的宠物用品网上商店:FERA.PL
2019/08/11 全球购物
销售代表求职自荐信
2013/10/01 职场文书
员工自我鉴定
2013/10/09 职场文书
汽车技术服务英文求职信范文
2014/01/02 职场文书
家长会主持词开场白
2014/03/18 职场文书
护士求职信
2014/07/05 职场文书
批评与自我批评范文
2014/10/15 职场文书
安全生产工作汇报
2014/10/28 职场文书
同学聚会开幕词
2019/04/02 职场文书
MySQL 分组查询的优化方法
2021/05/12 MySQL
Python爬虫:从m3u8文件里提取小视频的正确操作
2021/05/14 Python
JavaWeb 入门:Hello Servlet
2021/07/16 Java/Android
Elasticsearch 批量操作
2022/04/19 Python