文件目录如下:
如图,目的是把COCO文件夹下的子文件夹内的标注文件(图片和标注文件都在这些子文件夹下)转换成VOC格式,然后统一重命名放到VOC文件夹下。
main代码:
import os
import numpy as np
import codecs
import json
from glob import glob
import cv2
import shutil
BASEDIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# src_dir #coco格式标注的数据
src_dir = os.path.join(BASEDIR, "COCO")
# target_dir # VOC格式标注数据
xml_dir = os.path.join(BASEDIR, "VOC", "labels")
target_image_dir = os.path.join(BASEDIR, "VOC", "images")
if not os.path.exists(xml_dir):
os.makedirs(xml_dir)
if not os.path.exists(target_image_dir):
os.makedirs(target_image_dir)
# 将src_dir中COCO标注数据转成VOC标注数据,将VOC格式标注文件以及对应图片存储到target_dir,图片名字被修改
class_dirs = os.listdir(src_dir) # smoke, fall, phone
count = 0 # 用于计数和图片的命名
for class_dir in class_dirs:
json_names = list(filter(lambda x: x.endswith('.json'), os.listdir(os.path.join(src_dir, class_dir))))
for json_name in json_names:
json_path = os.path.join(src_dir, class_dir, json_name)
json_info = json.load(open(json_path, "r", encoding="utf-8"))
# print(json_info)
# print(json_info["shapes"][0]["points"][0][0])
# points = np.array(json_info["shapes"][0]["points"])
# label = json_info["shapes"][0]["label"]
# xmin = min(points[:, 0])
# xmax = max(points[:, 0])
# ymin = min(points[:, 1])
# ymax = max(points[:, 1])
# print(xmin,ymin,xmax,ymax)
src_image_name = json_info["imagePath"] # src_dir中图片的名字
src_image_path = os.path.join(src_dir, class_dir, src_image_name)
# print(os.path.join(src_dir, class_dir, src_image_name))
height, width, channel = cv2.imread(src_image_path).shape
#zfill用于把数字变成如00001的形式
target_image_name ="{}.jpg".format(str(count).zfill(5)) # target_dir中图片的名字
target_image_path = os.path.join(target_image_dir, target_image_name)
print("将图片{}复制到{}".format(src_image_path, target_image_path))
shutil.copy(src_image_path, target_image_path)
xml_name = "{}.xml".format(str(count).zfill(5)) # target_dir中图片对应的xml文件的名字
# print(target_image_name, xml_name)
xml_path = os.path.join(xml_dir, xml_name)
print("将图片{}的标注信息写入到{}".format(target_image_path, xml_path))
with codecs.open(xml_path, "w", "utf-8") as xml:
xml.write('\n')
xml.write('\t' + 'human_action' + ' \n')
xml.write('\t' + target_image_name + ' \n')
xml.write('\t\n')
xml.write('\t\t' + str(width) + ' \n')
xml.write('\t\t' + str(height) + ' \n')
xml.write('\t\t' + str(channel) + ' \n')
xml.write('\t \n')
for bbox_shape in json_info["shapes"]: #有多个框
points = np.array(bbox_shape["points"])
label = bbox_shape["label"]
xmin = min(points[:, 0])
xmax = max(points[:, 0])
ymin = min(points[:, 1])
ymax = max(points[:, 1])
if xmax <= xmin:
pass
elif ymax <= ymin:
pass
else:
xml.write('\t\n')
xml.write(' ')
print("已完成第{}张图片".format(count))
count += 1