【目标检测实用脚本系列】标注图片裁切成boundingbox的小图

【目标检测实用脚本系列】将labelImg标注的xml标签,按标签名建立文件夹,并将对应的裁切小图保存到文件夹中

目标检测中数据是至关重要的一个环节,使用当前脚本可以快捷的将已经标注好的xml标签,按标签名切分成图像以便查验,切出来的标签图片如下:

在这里插入图片描述
脚本如下,只需要将第46、48、50行路径改为自己的路径即可:

import cv2
import xml.etree.ElementTree as ET
import os
import glob
from tqdm import tqdm
import shutil

def count_num(indir):
    label_list = []
    # 提取xml文件列表
    os.chdir(indir)
    annotations = os.listdir('.')
    annotations = glob.glob(str(annotations) + '*.xml')
    # 新建字典,用于存放各类标签名及其对应的数目
    dict = {
    
    }
    # 遍历xml文件
    for i, file in enumerate(annotations):

        # actual parsing
        in_file = open(file, encoding='utf-8')
        tree = ET.parse(in_file)
        root = tree.getroot()

        # 遍历文件的所有标签
        for obj in root.iter('object'):
            name = obj.find('name').text
            if (name in dict.keys()):
                # 如果标签不是第一次出现,则+1
                dict[name] += 1
            else:
                # 如果标签是第一次出现,则将该标签名对应的value初始化为1
                dict[name] = 1

    # 打印结果
    print("各类标签的数量分别为:")
    for key in dict.keys():
        print(key + ': ' + str(dict[key]))
        label_list.append(key)
    print("标签类别如下:")
    print(label_list)
    return label_list


if __name__ == '__main__':
    # 原始图片路径
    img_path = '/home/lzj/fall_dataset/JPEGImages'
    # 原始标签路径
    xml_path = '/home/lzj/fall_dataset/Annotations'
    # 待存放新图片的路径
    obj_img_path = '/home/lzj/fall_dataset/cut_xml'

    # 调用函数统计各类标签数目
    label_list = count_num(xml_path)
    # 判断所在目录下是否有该文件名的文件夹
    if not os.path.exists(obj_img_path):
        os.makedirs(obj_img_path)
        print(f"已经创建文件夹{
      
      obj_img_path}")
    # 新建以标签名字命名的文件夹
    for label in label_list:
        new_label_path = os.path.join(obj_img_path, label)
        if not os.path.exists(new_label_path):
            os.makedirs(new_label_path)
            print(f"已经创建文件夹{
      
      new_label_path}")

    # 遍历图片文件夹
    for img_file in tqdm(os.listdir(img_path)):
        # 判断文件是否为图片格式
        if img_file[-4:] in ['.png', '.jpg', '.bmp', '.jpeg']:
            # 将图片路径与图片名进行拼接
            img_filename = os.path.join(img_path, img_file)
            # 读取图片
            img_cv = cv2.imread(img_filename)

            # 分割出图片名,如“000.png” 图片名为“000”
            img_name = (os.path.splitext(img_file)[0])
            # 利用标签路径、图片名、xml后缀拼接出完整的标签路径名
            xml_name = os.path.join(xml_path, ('%s.xml' % img_name))

            # 判断与图片同名的标签是否存在,因为图片不一定每张都打标
            if os.path.exists(xml_name):
                # 利用ET读取xml文件
                root = ET.parse(xml_name).getroot()
                # 目标框个数统计,防止目标文件覆盖
                count = 0
                # 遍历所有目标框
                for obj in root.iter('object'):
                    # 获取目标框名称,即label名
                    name = obj.find('name').text
                    # 找到框目标
                    xmlbox = obj.find('bndbox')
                    # 将框目标的四个顶点坐标取出
                    x0 = xmlbox.find('xmin').text
                    y0 = xmlbox.find('ymin').text
                    x1 = xmlbox.find('xmax').text
                    y1 = xmlbox.find('ymax').text

                    # 把对应标签存放到指定的目录下
                    now_path = os.path.join(obj_img_path, name)
                    # cv2裁剪出目标框中的图片
                    obj_img = img_cv[int(y0):int(y1), int(x0):int(x1)]
                    # 保存裁剪图片
                    cv2.imwrite(os.path.join(now_path, ('%s_%s' % (img_name, count) + '.jpg')), obj_img)
                    count += 1  # 目标框统计值自增1

运行后的结果如下:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45921929/article/details/129581837
今日推荐