# -*- 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
from shapely.geometry import Polygon

class labelme2coco(object):
  def __init__(self,labelme_json=[],save_json_path='./new.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'].split('_')
          label=shapes['label'][:-1]
          print(shapes['label'])
          print(label)
          if label not in self.label:
            self.categories.append(self.categorie(label))
            self.label.append(label)
          points=shapes['points']
          self.annotations.append(self.annotation(points,label,num))
          self.annID+=1
    print(self.label)

  def image(self,data,num):
    image={}
    img = utils.img_b64_to_array(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]

    self.height=height
    self.width=width

    return image

  def categorie(self,label):
    categorie={}
    categorie['supercategory'] = label
    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())]
    poly = Polygon(points)
    area_ = round(poly.area,6)
    annotation['area'] = area_
    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['category_id'] = self.getcatid(label)
    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) # indent=4 更加美观显示

labelme_json=glob.glob('./*.json')
# labelme_json=['./1.json']

labelme2coco(labelme_json,'./new.json')

labelme2COCO的更多相关文章

  1. labelme2coco问题:TypeError: Object of type 'int64' is not JSON serializable

    最近在做MaskRCNN 在自己的数据(labelme)转为COCOjson格式遇到问题:TypeError: Object of type 'int64' is not JSON serializa ...

  2. coco标注信息与labelme标注信息的详解、相互转换及可视化

    引言 在做实例分割或语义分割的时候,我们通常要用labelme进行标注,labelme标注的json文件与coco数据集已经标注好的json文件的格式和内容有差异.如果要用coco数据集的信息,就要对 ...

  3. [炼丹术]yolact训练模型学习总结

    yolact训练模型学习总结 一.YOLACT介绍(You Only Look At CoefficienTs) 1.1 简要介绍 yolact是一种用于实时实例分割的简单.全卷积模型. (A sim ...

随机推荐

  1. np.random的随机数函数

    np.random的随机数函数(1) 函数 说明 rand(d0,d1,..,dn) 根据d0‐dn创建随机数数组,浮点数, [0,1),均匀分布 randn(d0,d1,..,dn) 根据d0‐dn ...

  2. Centos6.5 恢复误删的系统面板

    在CentOS6.5下往面板上拖应用程序时,手贱了,点了"Delete This Panel".结果就悲剧了~面板不见了! 从网上搜了一下解决方法,列举一下. 1.新建面板 如果下 ...

  3. 如何将angular-ui-bootstrap的图片轮播组件封装成一个指令

    在项目开发中我们经常会遇到图片轮播的功能点: 如果我们开发人员自己原生手写,将会花费很多的时间,最终得不偿失. 接下来就详细说说如何使用angular-ui发热图片轮播模块,并且将它写成一个指令(便于 ...

  4. win10下安装并启动zookeeper

    下载直接到zk的官网(zookeeper.apache.org)即可,点击右边的Releases,在Download下再点Download进入镜像下载页面,在给出的链接列表里选择一个镜像地址,进去后选 ...

  5. jeecg中ajax传值的前端js和后台代码

    前端js: var b=1; $.ajax({ type : "POST", --Post请求方式 url : 'orderController.do?wuliao', --路径 ...

  6. Java里的常用运算符及其优先级顺序

    知道了八种基本数据类型后,在使用中弄清运算符的优先级是很有必要的.具体如下图:  这里需要注意的是,强制类型转换的优先级是位于乘除前面而处于单目运算符后面的,这是比较容易出错的地方.比如用Math.R ...

  7. 「自己开发直播」实现nginx-rtmp-module多频道输入输出与权限控制

    之前写了一篇文章,利用nginx和nginx-rtmp-module实现直播. 不过,之前只是做到了能够直播而已,只能一个人推流,并没有实现多人多频道输入输出,也没有权限控制,只要知道rtmp的URL ...

  8. java代码=====实现修改while()

    总结: package com.mmm; public class cse { public static void main(String[] args) { // int count=0;你妹,我 ...

  9. RAC的时间同步问题

    今天在两个节点上面安装RAC,在安装clusterware的时候OUI总是提示失败.查到资料的得知: 特此记录: 需要在在所有的集群节点上设置正确的日期和时间 在安装 Oracle 集群件.数据库以 ...

  10. Vue源码(一)

    入口文件 src/core/instance/index.js 中可以看到 function Vue (options) { if (process.env.NODE_ENV !== 'product ...