# -*- 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. ecmall 2.3.0 最新补丁20140618

    特别提示:补丁下载地址为:http://download.ecshop.com开头,该地址为ecmall下载站,如果非以http://download.ecshop.com开头,请勿下载,同时请反馈给 ...

  2. 在ng中的select的使用方法的讲解

    项目中我们可能会使用到条件过滤选择框之类的东西,最简单的就是input.select. 关于select的使用我们通常会需要从数据库中返回数据进行动态绑定. 此时我们会有两种方式: 1)使用ng-re ...

  3. 自定义DelegatingHandler为ASP.NET Web Api添加压缩与解压的功能

    HTTP协议中的压缩 Http协议中使用Accept-Encoding和Content-Encoding头来表示期望Response内容的编码和当前Request的内容编码.而Http内容的压缩其实是 ...

  4. 手动封装OpenCV1.0的IplImage读取保存功能遇到的小问题

    最近准备重新学习图像处理的知识,主要目的是自己实现一遍图像处理的算法,所以除了读取.保存图像外的操作都自己写,没想到直接封装OpenCV的读取.保存功能的第一步就出错.关键代码如下 void MyIm ...

  5. Server Tomcat v9.0 Server at localhost failed to start.

    最近老是出现这样的问题,在网上找了很多方法都不行,试着把Tomcat重新配置了一下就好了,事后找到一个博客,试了一下也可以使用

  6. 【CSS】文字超出显示省略号&连续字符换行

    方法1.多行控制(css3) .text { width: 100%; word-break: break-all; display: -webkit-box; -webkit-line-clamp: ...

  7. PTA 1004 Counting Leaves (30)(30 分)(dfs或者bfs)

    1004 Counting Leaves (30)(30 分) A family hierarchy is usually presented by a pedigree tree. Your job ...

  8. Tomcat常用设置

    远程Dbug调试: TOMCAT配置(只需设置一次): 1.在服务器的$TOMCAT_HOME/bin/catalina.sh中增加: CATALINA_OPTS="-server -Xde ...

  9. 第十二章 Ganglia监控Hadoop及Hbase集群性能(安装配置)

    1 Ganglia简介 Ganglia 是 UC Berkeley 发起的一个开源监视项目,设计用于测量数以千计的节点.每台计算机都运行一个收集和发送度量数据(如处理器速度.内存使用量等)的名为 gm ...

  10. input标签存在的兼容问题?

    当input标签在type为text时,在Firefox和Safari中的默认高度为22像素(包括上下边框)宽度为146像素(包括左右边框),而在IE中的默认高度为24像素,而宽度却和Firefox和 ...