Python CV 视觉图像数据标签(xml)在原图的可视化操作

CV离不开数据集,对于拿到公开的数据集抑或是人家整理的数据集时,我们有必要清楚现有的数据集标签质量如何。因此,我们可以用以下脚本去对我们现有的数据标签在原图上进行可视化操作。

本人基于企业实际工程项目,以.xml标签数据可视化例子来验证,整理代码如下:

  1. 给出我的数据路径,以便大家阅读以及改写代码

VOCdevkit
    L Annotation
        L 000.xml
    L ImageSets
    L JPEGImages
        L 000.jpg

  1. 代码如下(适用于#Python #Pytorch)
import xml.etree.ElementTree as ET  # 读取xml。
import os
from PIL import Image, ImageDraw, ImageFont


def parse_rec(filename):
    tree = ET.parse(filename)  # 解析读取xml函数
    objects = []
    img_dir = []
    for xml_name in tree.findall('filename'):
        img_path = os.path.join(pic_path, xml_name.text)
        img_dir.append(img_path)
    for obj in tree.findall('object'):
        obj_struct = {}
        obj_struct['name'] = obj.find('name').text
        obj_struct['pose'] = obj.find('pose').text
        obj_struct['truncated'] = int(obj.find('truncated').text)
        obj_struct['difficult'] = int(obj.find('difficult').text)
        bbox = obj.find('bndbox')
        obj_struct['bbox'] = [int(bbox.find('xmin').text),
                              int(bbox.find('ymin').text),
                              int(bbox.find('xmax').text),
                              int(bbox.find('ymax').text)]
        objects.append(obj_struct)

    return objects, img_dir


# 可视化
def visualise_gt(objects, img_dir):
    for id, img_path in enumerate(img_dir):
        img_path = img_path + '.jpg'
        img = Image.open(img_path)
        draw = ImageDraw.Draw(img)
        for a in objects:
            xmin = int(a['bbox'][0])
            ymin = int(a['bbox'][1])
            xmax = int(a['bbox'][2])
            ymax = int(a['bbox'][3])
            label = a['name']
            draw.rectangle((xmin, ymin, xmax, ymax), fill=None, outline=(0, 255, 0), width=2)
            draw.text((xmin - 10, ymin - 15), label, fill=(0, 255, 0), font=font)  # 利用ImageDraw的内置函数,在图片上写入文字
        img.show()


fontPath = "C:\Windows\Fonts\Consolas\consola.ttf"  # 字体路径
# root = 'F:/dataset/AQM'
root = './VOCdevkit/VOC2007'
ann_path = os.path.join(root, 'Annotations')  # xml文件所在路径
pic_path = os.path.join(root, 'JPEGImages')  # 样本图片路径

font = ImageFont.truetype(fontPath, 16)

for filename in os.listdir(ann_path):
    xml_path = os.path.join(ann_path, filename)
    object, img_dir = parse_rec(xml_path)
    visualise_gt(object, img_dir)

搞定!撒花!
有学习需要的欢迎交流!

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,那我假设你的数据集中每张图片只对应一个标注文件,以下是可以实现分析样本大小分布、样本比例分布和样本 GT 与锚框的 IoU 分布的 Python 代码: ```python import os import cv2 import xml.etree.ElementTree as ET import numpy as np import matplotlib.pyplot as plt # 图像和标注文件所在目录 image_dir = "images" annotation_dir = "annotations" # 获取所有图像和标注文件路径 image_paths = [os.path.join(image_dir, file) for file in os.listdir(image_dir)] annotation_paths = [os.path.join(annotation_dir, file) for file in os.listdir(annotation_dir)] # 样本数据列表,每个元素为一个样本(图像、标注文件路径、锚框等信息) samples = [] # 遍历每个图像和标注文件,生成样本数据 for image_path, annotation_path in zip(image_paths, annotation_paths): # 加载图像和标注文件 image = cv2.imread(image_path) tree = ET.parse(annotation_path) root = tree.getroot() # 获取图像大小 image_h, image_w, _ = image.shape # 获取所有边界框的信息 bboxes = [] for obj in root.findall("object"): bbox = obj.find("bndbox") xmin = int(bbox.find("xmin").text) ymin = int(bbox.find("ymin").text) xmax = int(bbox.find("xmax").text) ymax = int(bbox.find("ymax").text) bboxes.append([xmin, ymin, xmax, ymax]) # 生成样本数据 if len(bboxes) > 0: samples.append({ "image_path": image_path, "annotation_path": annotation_path, "image_size": (image_w, image_h), "bboxes": np.array(bboxes) }) # 计算每个样本的大小和正负样本比例 sample_sizes = [] sample_ratios = [] for sample in samples: image_w, image_h = sample["image_size"] bbox_w = sample["bboxes"][:, 2] - sample["bboxes"][:, 0] bbox_h = sample["bboxes"][:, 3] - sample["bboxes"][:, 1] sample_sizes.append(image_w * image_h) sample_ratios.append(len(bbox_w[bbox_w > 0]) / len(bbox_w[bbox_w == 0])) # 绘制直方图 fig, axs = plt.subplots(1, 3, figsize=(15, 5)) axs[0].hist(sample_sizes, bins=20, color='steelblue', edgecolor='k') axs[0].set_xlabel('Sample Size') axs[0].set_ylabel('Frequency') axs[0].set_title('Distribution of Sample Sizes') axs[1].hist(sample_ratios, bins=20, color='steelblue', edgecolor='k') axs[1].set_xlabel('Positive/Negative Ratio') axs[1].set_ylabel('Frequency') axs[1].set_title('Distribution of Sample Ratios') ious = [] for sample in samples: image = cv2.imread(sample["image_path"]) for bbox in sample["bboxes"]: iou = calculate_iou(bbox, gt_bbox) ious.append(iou) axs[2].hist(ious, bins=20, color='steelblue', edgecolor='k') axs[2].set_xlabel('IoU') axs[2].set_ylabel('Frequency') axs[2].set_title('Distribution of IoUs') plt.show() ``` 其中,`image_dir` 和 `annotation_dir` 分别指定了图像和标注文件所在的目录,`calculate_iou` 函数计算两个边界框的 IoU。可视化结果包括三个直方图,分别对应样本大小分布、样本比例分布和样本 GT 与锚框的 IoU 分布。注意,这里使用了 `subplots` 函数在一张图中绘制了三个直方图。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值