python实现提取COCO,VOC数据集中特定的类


Posted in Python onMarch 10, 2020

1.python提取COCO数据集中特定的类

安装pycocotools github地址:https://github.com/philferriere/cocoapi

pip install git+https://github.com/philferriere/cocoapi.git#subdirectory=PythonAPI

提取特定的类别如下:

from pycocotools.coco import COCO
import os
import shutil
from tqdm import tqdm
import skimage.io as io
import matplotlib.pyplot as plt
import cv2
from PIL import Image, ImageDraw
 
#the path you want to save your results for coco to voc
savepath="/media/huanglong/Newsmy/COCO/" #保存提取类的路径,我放在同一路径下
img_dir=savepath+'images/'
anno_dir=savepath+'Annotations/'
# datasets_list=['train2014', 'val2014']
datasets_list=['train2014']
 
classes_names = ['person'] #coco有80类,这里写要提取类的名字,以person为例
#Store annotations and train2014/val2014/... in this folder
dataDir= '/media/huanglong/Newsmy/COCO/' #原coco数据集
 
headstr = """\
<annotation>
 <folder>VOC</folder>
 <filename>%s</filename>
 <source>
 <database>My Database</database>
 <annotation>COCO</annotation>
 <image>flickr</image>
 <flickrid>NULL</flickrid>
 </source>
 <owner>
 <flickrid>NULL</flickrid>
 <name>company</name>
 </owner>
 <size>
 <width>%d</width>
 <height>%d</height>
 <depth>%d</depth>
 </size>
 <segmented>0</segmented>
"""
objstr = """\
 <object>
 <name>%s</name>
 <pose>Unspecified</pose>
 <truncated>0</truncated>
 <difficult>0</difficult>
 <bndbox>
  <xmin>%d</xmin>
  <ymin>%d</ymin>
  <xmax>%d</xmax>
  <ymax>%d</ymax>
 </bndbox>
 </object>
"""
 
tailstr = '''\
</annotation>
'''
 
#if the dir is not exists,make it,else delete it
def mkr(path):
 if os.path.exists(path):
 shutil.rmtree(path)
 os.mkdir(path)
 else:
 os.mkdir(path)
mkr(img_dir)
mkr(anno_dir)
def id2name(coco):
 classes=dict()
 for cls in coco.dataset['categories']:
 classes[cls['id']]=cls['name']
 return classes
 
def write_xml(anno_path,head, objs, tail):
 f = open(anno_path, "w")
 f.write(head)
 for obj in objs:
 f.write(objstr%(obj[0],obj[1],obj[2],obj[3],obj[4]))
 f.write(tail)
 
 
def save_annotations_and_imgs(coco,dataset,filename,objs):
 #eg:COCO_train2014_000000196610.jpg-->COCO_train2014_000000196610.xml
 anno_path=anno_dir+filename[:-3]+'xml'
 img_path=dataDir+dataset+'/'+filename
 print(img_path)
 dst_imgpath=img_dir+filename
 
 img=cv2.imread(img_path)
 #if (img.shape[2] == 1):
 # print(filename + " not a RGB image")
 # return
 shutil.copy(img_path, dst_imgpath)
 
 head=headstr % (filename, img.shape[1], img.shape[0], img.shape[2])
 tail = tailstr
 write_xml(anno_path,head, objs, tail)
 
 
def showimg(coco,dataset,img,classes,cls_id,show=True):
 global dataDir
 I=Image.open('%s/%s/%s'%(dataDir,dataset,img['file_name']))
 #通过id,得到注释的信息
 annIds = coco.getAnnIds(imgIds=img['id'], catIds=cls_id, iscrowd=None)
 # print(annIds)
 anns = coco.loadAnns(annIds)
 # print(anns)
 # coco.showAnns(anns)
 objs = []
 for ann in anns:
 class_name=classes[ann['category_id']]
 if class_name in classes_names:
  print(class_name)
  if 'bbox' in ann:
  bbox=ann['bbox']
  xmin = int(bbox[0])
  ymin = int(bbox[1])
  xmax = int(bbox[2] + bbox[0])
  ymax = int(bbox[3] + bbox[1])
  obj = [class_name, xmin, ymin, xmax, ymax]
  objs.append(obj)
  draw = ImageDraw.Draw(I)
  draw.rectangle([xmin, ymin, xmax, ymax])
 if show:
 plt.figure()
 plt.axis('off')
 plt.imshow(I)
 plt.show()
 
 return objs
 
for dataset in datasets_list:
 #./COCO/annotations/instances_train2014.json
 annFile='{}/annotations/instances_{}.json'.format(dataDir,dataset)
 
 #COCO API for initializing annotated data
 coco = COCO(annFile)

 #show all classes in coco
 classes = id2name(coco)
 print(classes)
 #[1, 2, 3, 4, 6, 8]
 classes_ids = coco.getCatIds(catNms=classes_names)
 print(classes_ids)
 for cls in classes_names:
 #Get ID number of this class
 cls_id=coco.getCatIds(catNms=[cls])
 img_ids=coco.getImgIds(catIds=cls_id)
 print(cls,len(img_ids))
 # imgIds=img_ids[0:10]
 for imgId in tqdm(img_ids):
  img = coco.loadImgs(imgId)[0]
  filename = img['file_name']
  # print(filename)
  objs=showimg(coco, dataset, img, classes,classes_ids,show=False)
  print(objs)
  save_annotations_and_imgs(coco, dataset, filename, objs)

2. 将上一步提取的COCO 某一类 xml转为COCO标准的json文件:

# -*- coding: utf-8 -*-
# @Time : 2019/8/27 10:48
# @Author :Rock
# @File : voc2coco.py
# just for object detection
import xml.etree.ElementTree as ET
import os
import json

coco = dict()
coco['images'] = []
coco['type'] = 'instances'
coco['annotations'] = []
coco['categories'] = []

category_set = dict()
image_set = set()

category_item_id = 0
image_id = 0
annotation_id = 0


def addCatItem(name):
 global category_item_id
 category_item = dict()
 category_item['supercategory'] = 'none'
 category_item_id += 1
 category_item['id'] = category_item_id
 category_item['name'] = name
 coco['categories'].append(category_item)
 category_set[name] = category_item_id
 return category_item_id


def addImgItem(file_name, size):
 global image_id
 if file_name is None:
 raise Exception('Could not find filename tag in xml file.')
 if size['width'] is None:
 raise Exception('Could not find width tag in xml file.')
 if size['height'] is None:
 raise Exception('Could not find height tag in xml file.')
 img_id = "%04d" % image_id
 image_id += 1
 image_item = dict()
 image_item['id'] = int(img_id)
 # image_item['id'] = image_id
 image_item['file_name'] = file_name
 image_item['width'] = size['width']
 image_item['height'] = size['height']
 coco['images'].append(image_item)
 image_set.add(file_name)
 return image_id


def addAnnoItem(object_name, image_id, category_id, bbox):
 global annotation_id
 annotation_item = dict()
 annotation_item['segmentation'] = []
 seg = []
 # bbox[] is x,y,w,h
 # left_top
 seg.append(bbox[0])
 seg.append(bbox[1])
 # left_bottom
 seg.append(bbox[0])
 seg.append(bbox[1] + bbox[3])
 # right_bottom
 seg.append(bbox[0] + bbox[2])
 seg.append(bbox[1] + bbox[3])
 # right_top
 seg.append(bbox[0] + bbox[2])
 seg.append(bbox[1])

 annotation_item['segmentation'].append(seg)

 annotation_item['area'] = bbox[2] * bbox[3]
 annotation_item['iscrowd'] = 0
 annotation_item['ignore'] = 0
 annotation_item['image_id'] = image_id
 annotation_item['bbox'] = bbox
 annotation_item['category_id'] = category_id
 annotation_id += 1
 annotation_item['id'] = annotation_id
 coco['annotations'].append(annotation_item)


def parseXmlFiles(xml_path):
 for f in os.listdir(xml_path):
 if not f.endswith('.xml'):
  continue

 bndbox = dict()
 size = dict()
 current_image_id = None
 current_category_id = None
 file_name = None
 size['width'] = None
 size['height'] = None
 size['depth'] = None

 xml_file = os.path.join(xml_path, f)
 # print(xml_file)

 tree = ET.parse(xml_file)
 root = tree.getroot()
 if root.tag != 'annotation':
  raise Exception('pascal voc xml root element should be annotation, rather than {}'.format(root.tag))

 # elem is <folder>, <filename>, <size>, <object>
 for elem in root:
  current_parent = elem.tag
  current_sub = None
  object_name = None

  if elem.tag == 'folder':
  continue

  if elem.tag == 'filename':
  file_name = elem.text
  if file_name in category_set:
   raise Exception('file_name duplicated')

  # add img item only after parse <size> tag
  elif current_image_id is None and file_name is not None and size['width'] is not None:
  if file_name not in image_set:
   current_image_id = addImgItem(file_name, size)
   # print('add image with {} and {}'.format(file_name, size))
  else:
   raise Exception('duplicated image: {}'.format(file_name))
   # subelem is <width>, <height>, <depth>, <name>, <bndbox>
  for subelem in elem:
  bndbox['xmin'] = None
  bndbox['xmax'] = None
  bndbox['ymin'] = None
  bndbox['ymax'] = None

  current_sub = subelem.tag
  if current_parent == 'object' and subelem.tag == 'name':
   object_name = subelem.text
   if object_name not in category_set:
   current_category_id = addCatItem(object_name)
   else:
   current_category_id = category_set[object_name]

  elif current_parent == 'size':
   if size[subelem.tag] is not None:
   raise Exception('xml structure broken at size tag.')
   size[subelem.tag] = int(subelem.text)

  # option is <xmin>, <ymin>, <xmax>, <ymax>, when subelem is <bndbox>
  for option in subelem:
   if current_sub == 'bndbox':
   if bndbox[option.tag] is not None:
    raise Exception('xml structure corrupted at bndbox tag.')
   bndbox[option.tag] = int(option.text)

  # only after parse the <object> tag
  if bndbox['xmin'] is not None:
   if object_name is None:
   raise Exception('xml structure broken at bndbox tag')
   if current_image_id is None:
   raise Exception('xml structure broken at bndbox tag')
   if current_category_id is None:
   raise Exception('xml structure broken at bndbox tag')
   bbox = []
   # x
   bbox.append(bndbox['xmin'])
   # y
   bbox.append(bndbox['ymin'])
   # w
   bbox.append(bndbox['xmax'] - bndbox['xmin'])
   # h
   bbox.append(bndbox['ymax'] - bndbox['ymin'])
   # print('add annotation with {},{},{},{}'.format(object_name, current_image_id, current_category_id,
   #      bbox))
   addAnnoItem(object_name, current_image_id, current_category_id, bbox)


if __name__ == '__main__':
	#修改这里的两个地址,一个是xml文件的父目录;一个是生成的json文件的绝对路径
 xml_path = r'G:\dataset\COCO\person\coco_val2014\annotations\\'
 json_file = r'G:\dataset\COCO\person\coco_val2014\instances_val2014.json'
 parseXmlFiles(xml_path)
 json.dump(coco, open(json_file, 'w'))

3.python提取Pascal Voc数据集中特定的类

# -*- coding: utf-8 -*-
# @Function:There are 20 classes in VOC data set. If you need to extract specific classes, you can use this program to extract them.
 
import os
import shutil
ann_filepath='E:/VOCdevkit/VOC2012/Annotations/'
img_filepath='E:/VOCdevkit/VOC2012/JPEGImages/'
img_savepath='E:TrafficDatasets/JPEGImages/'
ann_savepath='E:TrafficDatasets/Annotations/'
if not os.path.exists(img_savepath):
 os.mkdir(img_savepath)
 
if not os.path.exists(ann_savepath):
 os.mkdir(ann_savepath)
names = locals()
classes = ['aeroplane','bicycle','bird', 'boat', 'bottle',
  'bus', 'car', 'cat', 'chair', 'cow','diningtable',
  'dog', 'horse', 'motorbike', 'pottedplant',
  'sheep', 'sofa', 'train', 'tvmonitor', 'person']
 
 
for file in os.listdir(ann_filepath):
 print(file)
 
 fp = open(ann_filepath + '\\' + file) #打开Annotations文件
 ann_savefile=ann_savepath+file
 fp_w = open(ann_savefile, 'w')
 lines = fp.readlines()
 
 ind_start = []
 ind_end = []
 lines_id_start = lines[:] 
 
 lines_id_end = lines[:]
 
 classes1 = '\t\t<name>bicycle</name>\n'
 classes2 = '\t\t<name>bus</name>\n'
 classes3 = '\t\t<name>car</name>\n'
 classes4 = '\t\t<name>motorbike</name>\n'
 classes5 = '\t\t<name>train</name>\n'
 
 #在xml中找到object块,并将其记录下来
 while "\t<object>\n" in lines_id_start:
 a = lines_id_start.index("\t<object>\n")
 ind_start.append(a) #ind_start是<object>的行数
 lines_id_start[a] = "delete"
 
 
 while "\t</object>\n" in lines_id_end:
 b = lines_id_end.index("\t</object>\n")
 ind_end.append(b) #ind_end是</object>的行数
 lines_id_end[b] = "delete"
 
 #names中存放所有的object块
 i = 0
 for k in range(0, len(ind_start)):
 names['block%d' % k] = []
 for j in range(0, len(classes)):
  if classes[j] in lines[ind_start[i] + 1]:
  a = ind_start[i]
  for o in range(ind_end[i] - ind_start[i] + 1):
   names['block%d' % k].append(lines[a + o])
  break
 i += 1
 #print(names['block%d' % k])
 
 
 #xml头
 string_start = lines[0:ind_start[0]]
 
 #xml尾
 if((file[2:4]=='09') | (file[2:4]=='10') | (file[2:4]=='11')):
 string_end = lines[(len(lines) - 11):(len(lines))]
 else:
 string_end = [lines[len(lines) - 1]] 
 
 
 #在给定的类中搜索,若存在则,写入object块信息
 a = 0
 for k in range(0, len(ind_start)):
 if classes1 in names['block%d' % k]:
  a += 1
  string_start += names['block%d' % k]
 if classes2 in names['block%d' % k]:
  a += 1
  string_start += names['block%d' % k]
 if classes3 in names['block%d' % k]:
  a += 1
  string_start += names['block%d' % k]
 if classes4 in names['block%d' % k]:
  a += 1
  string_start += names['block%d' % k]
 if classes5 in names['block%d' % k]:
  a += 1
  string_start += names['block%d' % k]
 
 string_start += string_end
 # print(string_start)
 for c in range(0, len(string_start)):
 fp_w.write(string_start[c])
 fp_w.close()
 #如果没有我们寻找的模块,则删除此xml,有的话拷贝图片
 if a == 0:
 os.remove(ann_savepath+file)
 else:
 name_img = img_filepath + os.path.splitext(file)[0] + ".jpg"
 shutil.copy(name_img, img_savepath)
 fp.close()

以上这篇python实现提取COCO,VOC数据集中特定的类就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python实现的希尔排序算法实例
Jul 01 Python
python数据结构之链表的实例讲解
Jul 25 Python
Python标准库之itertools库的使用方法
Sep 07 Python
python 列表,数组,矩阵两两转换tolist()的实例
Apr 04 Python
Python OpenCV处理图像之图像直方图和反向投影
Jul 10 Python
Django生成PDF文档显示网页上以及PDF中文显示乱码的解决方法
Dec 17 Python
python学生管理系统的实现
Apr 05 Python
Python3.9 beta2版本发布了,看看这7个新的PEP都是什么
Jun 10 Python
Python实例方法、类方法、静态方法区别详解
Sep 05 Python
python调用win32接口进行截图的示例
Nov 11 Python
Django解决frame拒绝问题的方法
Dec 18 Python
Django使用channels + websocket打造在线聊天室
May 20 Python
Python 生成VOC格式的标签实例
Mar 10 #Python
python3用urllib抓取贴吧邮箱和QQ实例
Mar 10 #Python
python目标检测给图画框,bbox画到图上并保存案例
Mar 10 #Python
python opencv 检测移动物体并截图保存实例
Mar 10 #Python
Python标准库json模块和pickle模块使用详解
Mar 10 #Python
Python xlrd excel文件操作代码实例
Mar 10 #Python
python图片剪裁代码(图片按四个点坐标剪裁)
Mar 10 #Python
You might like
全新的PDO数据库操作类php版(仅适用Mysql)
2012/07/22 PHP
解析PHP无限级分类方法及代码
2013/06/21 PHP
PHP脚本监控Nginx 502错误并自动重启php-fpm
2015/05/13 PHP
TP(thinkPHP)框架多层控制器和多级控制器的使用示例
2018/06/13 PHP
JQuery textlimit 显示用户输入的字符数 限制用户输入的字符数
2009/05/14 Javascript
Jquery each方法跳出循环,并获取返回值(实例讲解)
2013/12/12 Javascript
Bootstrap按钮下拉菜单组件详解
2016/05/10 Javascript
js实现移动端微信页面禁止字体放大
2017/02/16 Javascript
bootstrap的常用组件和栅格式布局详解
2017/05/02 Javascript
vue-cli2.x项目优化之引入本地静态库文件的方法
2018/06/19 Javascript
vue文件运行的方法教学
2019/02/12 Javascript
JS如何生成动态列表
2020/09/22 Javascript
Nodejs实现微信分账的示例代码
2021/01/19 NodeJs
[04:02]2014DOTA2国际邀请赛 BBC每日综述中国战队将再度登顶
2014/07/21 DOTA
[01:13:51]TNC vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
[49:31]DOTA2-DPC中国联赛 正赛 Elephant vs LBZS BO3 第二场 1月29日
2021/03/11 DOTA
python开发的小球完全弹性碰撞游戏代码
2013/10/15 Python
Python中的列表知识点汇总
2015/04/14 Python
Python用threading实现多线程详解
2017/02/03 Python
Python基于回溯法子集树模板实现8皇后问题
2017/09/01 Python
Python3中的列表生成式、生成器与迭代器实例详解
2018/06/11 Python
Django实现表单验证
2018/09/08 Python
详解python校验SQL脚本命名规则
2019/03/22 Python
Python实现链表反转的方法分析【迭代法与递归法】
2020/02/22 Python
python基于pygame实现飞机大作战小游戏
2020/11/19 Python
纯CSS3实现圆角效果(含IE兼容解决方法)
2014/05/07 HTML / CSS
css3的过滤效果简单实例
2016/08/03 HTML / CSS
京东国际站:JOYBUY
2017/11/23 全球购物
中青班党性分析材料
2014/02/16 职场文书
购房意向书
2014/04/01 职场文书
社区护士演讲稿
2014/08/27 职场文书
个人查摆剖析材料
2014/10/16 职场文书
借条格式范本
2015/05/25 职场文书
大学生社会实践感想
2015/08/11 职场文书
《给予树》教学反思
2016/03/03 职场文书
导游词之无锡唐城
2019/12/12 职场文书