概要
统计小目标数量以及占比,可以分类别统计。只需要一个xml即可输出统计。但是一般可能会有多个xml,就需要手动更改并汇总了。
输出结果展示
代码
import os
import xml.etree.ElementTree as ET
from collections import defaultdict
def compute_small_object_percentage(path_annotations):
small_threshold = 0.03 # 面积小于3%的视为小目标
super_small_threshold = 0.01 # 面积小于1%的视为超小目标
over_labels = 0
total_area_ratio = 0.0
class_small_labels = defaultdict(int)
class_super_small_labels = defaultdict(int)
class_total_labels = defaultdict(int)
for xml_filename in os.listdir(path_annotations):
xml_path = os.path.join(path_annotations, xml_filename)
tree = ET.parse(xml_path)
root = tree.getroot()
image_width = int(root.find('size').find('width').text)
image_height = int(root.find('size').find('height').text)
image_area = image_width * image_height
for obj in root.findall('object'):
over_labels += 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)
width = xmax - xmin
height = ymax - ymin
area = width * height
area_ratio = area / image_area
total_area_ratio += area_ratio
label_name = obj.find('name').text
if area_ratio < super_small_threshold:
class_super_small_labels[label_name] += 1
class_small_labels[label_name] += 1
elif area_ratio < small_threshold:
class_small_labels[label_name] += 1
class_total_labels[label_name] += 1
if over_labels > 0:
average_area_ratio = total_area_ratio / over_labels
print("总标签数:", over_labels)
print("平均面积率:", average_area_ratio)
# 打印每个类别的小目标和超小目标数量和比率
for class_name in class_small_labels.keys():
total_class_labels = class_total_labels[class_name]
class_small_percentage = (class_small_labels[class_name] / total_class_labels) * 100
class_super_small_percentage = (class_super_small_labels[class_name] / total_class_labels) * 100
print(f"类别 {class_name}: 总数 {total_class_labels}, 小目标数量 {class_small_labels[class_name]}({class_small_percentage:.2f}%), 超小目标数量 {class_super_small_labels[class_name]}({class_super_small_percentage:.2f}%)")
else:
print("没有找到标签文件。")
def main():
path_annotations = r"D:\YOLO\Annotations"# 请将路径更改为您的XML文件所在的目录
compute_small_object_percentage(path_annotations)
if __name__ == '__main__':
main()