1.python提取COCO数据集中特定的类
安装pycocotools github地址:https://github.com/philferriere/cocoapi
pip install git+https://github.com/philferriere/cocoapi.git#subdirectory=PythonAPI
若报错,pip install git+https://github.com/philferriere/cocoapi.git#subdirectory=PythonAPI
换成
pip install git+git://github.com/philferriere/cocoapi.git#subdirectory=PythonAPI
实在不行的话,手动下载
git clone https://github.com/pdollar/coco.git
cd coco/PythonAPI
python setup.py build_ext --inplace #安装到本地
python setup.py build_ext install # 安装到Python环境中
没有的库自己pip
注意skimage用pip install scikit-image -i https://pypi.tuna.tsinghua.edu.cn/simple
提取特定的类别如下:
# conding='utf-8'
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="/opt/10T/home/asc005/YangMingxiang/DenseCLIP_/data/COCO/" #save_path
img_dir=savepath+'images/'
anno_dir=savepath+'Annotations/'
# datasets_list=['train2014', 'val2014']
datasets_list=['train2017', 'val2017']classes_names = ['sheep'] #coco
#Store annotations and train2014/val2014/... in this folder
dataDir= '/opt/10T/home/asc005/YangMingxiang/DenseCLIP_/data/coco/' #origin cocoheadstr = """\
<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 classesdef 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.xmlanno_path=anno_dir+filename[:-3]+'xml'img_path=dataDir+dataset+'/'+filenameprint(img_path)dst_imgpath=img_dir+filenameimg=cv2.imread(img_path)#if (img.shape[2] == 1):# print(filename + " not a RGB image")# returnshutil.copy(img_path, dst_imgpath)head=headstr % (filename, img.shape[1], img.shape[0], img.shape[2])tail = tailstrwrite_xml(anno_path,head, objs, tail)def showimg(coco,dataset,img,classes,cls_id,show=True):global dataDirI=Image.open('%s/%s/%s'%(dataDir,dataset,img['file_name']))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 objsfor dataset in datasets_list:#./COCO/annotations/instances_train2014.jsonannFile='{}/annotations/instances_{}.json'.format(dataDir,dataset)#COCO API for initializing annotated datacoco = COCO(annFile)#show all classes in cococlasses = 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 classcls_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. 将上面获取的数据集划分为训练集和测试集
#conding='utf-8'
import os
import random
from shutil import copy2# origin
image_original_path = "/opt/10T/home/asc005/YangMingxiang/DenseCLIP_/data/COCO/images"
label_original_path = "/opt/10T/home/asc005/YangMingxiang/DenseCLIP_/data/COCO/Annotations"# parent_path = os.path.dirname(os.getcwd())
# parent_path = "D:\\AI_Find"
# train_image_path = os.path.join(parent_path, "image_data/seed/train/images/")
# train_label_path = os.path.join(parent_path, "image_data/seed/train/labels/")
train_image_path = os.path.join("/opt/10T/home/asc005/YangMingxiang/DenseCLIP_/data/COCO/train2017")
train_label_path = os.path.join("/opt/10T/home/asc005/YangMingxiang/DenseCLIP_/data/COCO/annotations/train2017")
test_image_path = os.path.join("/opt/10T/home/asc005/YangMingxiang/DenseCLIP_/data/COCO/val2017")
test_label_path = os.path.join("/opt/10T/home/asc005/YangMingxiang/DenseCLIP_/data/COCO/annotations/val2017")# test_image_path = os.path.join(parent_path, 'image_data/seed/val/images/')
# test_label_path = os.path.join(parent_path, 'image_data/seed/val/labels/')def mkdir():if not os.path.exists(train_image_path):os.makedirs(train_image_path)if not os.path.exists(train_label_path):os.makedirs(train_label_path)if not os.path.exists(test_image_path):os.makedirs(test_image_path)if not os.path.exists(test_label_path):os.makedirs(test_label_path)def main():mkdir()all_image = os.listdir(image_original_path)for i in range(len(all_image)):num = random.randint(1,5)if num != 2:copy2(os.path.join(image_original_path, all_image[i]), train_image_path)train_index.append(i)else:copy2(os.path.join(image_original_path, all_image[i]), test_image_path)val_index.append(i)all_label = os.listdir(label_original_path)for i in train_index:copy2(os.path.join(label_original_path, all_label[i]), train_label_path)for i in val_index:copy2(os.path.join(label_original_path, all_label[i]), test_label_path)if __name__ == '__main__':train_index = []val_index = []main()
3.将上一步提取的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 jsoncoco = 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 = 0def addCatItem(name):global category_item_idcategory_item = dict()category_item['supercategory'] = 'none'category_item_id += 1category_item['id'] = category_item_idcategory_item['name'] = namecoco['categories'].append(category_item)category_set[name] = category_item_idreturn category_item_iddef addImgItem(file_name, size):global image_idif 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_idimage_id += 1image_item = dict()image_item['id'] = int(img_id)# image_item['id'] = image_idimage_item['file_name'] = file_nameimage_item['width'] = size['width']image_item['height'] = size['height']coco['images'].append(image_item)image_set.add(file_name)return image_iddef addAnnoItem(object_name, image_id, category_id, bbox):global annotation_idannotation_item = dict()annotation_item['segmentation'] = []seg = []# bbox[] is x,y,w,h# left_topseg.append(bbox[0])seg.append(bbox[1])# left_bottomseg.append(bbox[0])seg.append(bbox[1] + bbox[3])# right_bottomseg.append(bbox[0] + bbox[2])seg.append(bbox[1] + bbox[3])# right_topseg.append(bbox[0] + bbox[2])seg.append(bbox[1])annotation_item['segmentation'].append(seg)annotation_item['area'] = bbox[2] * bbox[3]annotation_item['iscrowd'] = 0annotation_item['ignore'] = 0annotation_item['image_id'] = image_idannotation_item['bbox'] = bboxannotation_item['category_id'] = category_idannotation_id += 1annotation_item['id'] = annotation_idcoco['annotations'].append(annotation_item)def parseXmlFiles(xml_path):for f in os.listdir(xml_path):if not f.endswith('.xml'):continuebndbox = dict()size = dict()current_image_id = Nonecurrent_category_id = Nonefile_name = Nonesize['width'] = Nonesize['height'] = Nonesize['depth'] = Nonexml_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.tagcurrent_sub = Noneobject_name = Noneif elem.tag == 'folder':continueif elem.tag == 'filename':file_name = elem.textif file_name in category_set:raise Exception('file_name duplicated')# add img item only after parse <size> tagelif 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'] = Nonebndbox['xmax'] = Nonebndbox['ymin'] = Nonebndbox['ymax'] = Nonecurrent_sub = subelem.tagif current_parent == 'object' and subelem.tag == 'name':object_name = subelem.textif 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> tagif 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 = []# xbbox.append(bndbox['xmin'])# ybbox.append(bndbox['ymin'])# wbbox.append(bndbox['xmax'] - bndbox['xmin'])# hbbox.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'))