概要
将真实框显示在原图上,是批量的,如果不批量,直接跑一点断掉程序就行。
只需要输入原图,原xml标签,以及输出的路径即可,可以统计出类别和对应数量,并保存为txt。也有进度条,方便了解进度如何。
代码
import cv2
import os
import xml.etree.ElementTree as ET
from collections import defaultdict
from tqdm import tqdm # 导入tqdm库
# 初始化一个空的类别字典
CLASS_COUNTS = defaultdict(int)
# 初始化一个空的类别列表
CLASSES = []
def show_labels_img(images_dir, labels_dir, output_dir):
# 获取所有图片文件的列表
img_names = [f[:-4] for f in os.listdir(images_dir) if f.endswith(".jpg")]
# 使用tqdm创建进度条
for img_name in tqdm(img_names, desc="Processing Images"):
# 输入原图路径
img_path = os.path.join(images_dir, img_name + ".jpg")
img = cv2.imread(img_path)
# 输入原标签路径
label_path = os.path.join(labels_dir, img_name + ".xml")
if not os.path.exists(label_path):
continue
tree = ET.parse(label_path)
root = tree.getroot()
for obj in root.findall('object'):
label_name = obj.find('name').text
# 如果标签不在列表中,则添加到列表
if label_name not in CLASSES:
CLASSES.append(label_name)
# 增加类别计数
CLASS_COUNTS[label_name] += 1
bndbox = obj.find('bndbox')
xmin = int(bndbox.find('xmin').text)
ymin = int(bndbox.find('ymin').text)
xmax = int(bndbox.find('xmax').text)
ymax = int(bndbox.find('ymax').text)
color = (0, 0, 255)
pt1 = (xmin, ymin)
pt2 = (xmax, ymax)
# 绘制标签和边界框
cv2.rectangle(img, pt1, pt2, color, 2)
cv2.putText(img, label_name, (xmin, ymin - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)
# 输出新路径的图片
img_save_path = os.path.join(output_dir, img_name + "_with_labels.jpg")
cv2.imwrite(img_save_path, img)
# 打印并保存所有类别及其数量到txt文件
with open(os.path.join(output_dir, "classes_with_counts.txt"), "w") as classes_file:
for class_name in CLASSES:
count = CLASS_COUNTS[class_name]
print(f"{class_name}: {count}")
classes_file.write(f"{class_name}: {count}\n")
def main():
IMAGES_DIR = r"E:\data\damper\images" # 图片所在的文件夹路径
LABELS_DIR = r"E:\data\damper\xml"# 标签所在的文件夹路径
OUTPUT_DIR = r"E:\data\damper\groundtruth" # 保存结果的路径
os.makedirs(OUTPUT_DIR, exist_ok=True)
show_labels_img(IMAGES_DIR, LABELS_DIR, OUTPUT_DIR)
if __name__ == '__main__':
main()