网题 做问卷的网站自己做的网页发布
news/
2025/9/23 22:13:18/
文章来源:
网题 做问卷的网站,自己做的网页发布,一份完整app运营推广方案,视频网站自己怎么做的背景
在目标检测任务中#xff0c;评估不同对象之间的重叠情况是至关重要的#xff0c;而IOU#xff08;Intersection Over Union#xff09;是衡量这种重叠程度的重要指标。本文将介绍如何编写一个Python脚本#xff0c;通过并行化处理DOTA格式的标注文件#xff0c;统…背景
在目标检测任务中评估不同对象之间的重叠情况是至关重要的而IOUIntersection Over Union是衡量这种重叠程度的重要指标。本文将介绍如何编写一个Python脚本通过并行化处理DOTA格式的标注文件统计同类别对象之间的IOU超过某个阈值的对数。 代码功能
本文代码的核心功能包括
解析DOTA格式标注文件提取对象类别和多边形坐标。计算同类对象之间的IOU并统计超过设定阈值的情况。使用多进程并行化处理提高对大规模数据的处理效率。将最终的结果保存为CSV格式方便后续分析。
完整代码
import os
import logging
from shapely.geometry import Polygon
import numpy as np
from itertools import combinations
from concurrent.futures import ProcessPoolExecutor, as_completed
import argparse
import pandas as pd# 配置日志
logging.basicConfig(levellogging.INFO,format%(asctime)s [%(levelname)s] %(message)s,handlers[logging.StreamHandler()]
)def parse_args():解析命令行参数。parser argparse.ArgumentParser(description进行标注文件的IOU分析统计同类别对象之间的重叠数量。)parser.add_argument(--anno_folder, typestr, requiredTrue, help标注文件夹路径)parser.add_argument(--output_csv, typestr, defaultiou_overlap_results.csv, help输出CSV文件路径)parser.add_argument(--iou_threshold, typefloat, default0.01, helpIOU阈值超过此值视为重叠)parser.add_argument(--num_workers, typeint, defaultNone, help并行处理的进程数默认为CPU核心数)parser.add_argument(--by_class, actionstore_true, help是否按类别统计重叠数量)return parser.parse_args()def parse_annotation_file(file_path, class_mapNone):解析标注文件提取对象的类别和多边形坐标。参数file_path (str): 标注文件的路径。class_map (set, optional): 需要筛选的类别集合。默认为None表示不筛选。返回:list of tuples: 每个元组包含类别和对应的Shapely多边形。objects []try:with open(file_path, r) as file:for line_num, line in enumerate(file, 1):parts line.strip().split()if len(parts) 9:logging.warning(f{file_path} 第{line_num}行格式不正确跳过。)continuetry:# 假设坐标为前8个元素类别为第9个元素coords list(map(float, parts[:8]))dota_type parts[8]if class_map and dota_type not in class_map:continue# 将坐标转换为Shapely多边形polygon Polygon(np.array(coords).reshape(-1, 2))if not polygon.is_valid:logging.warning(f{file_path} 第{line_num}行的多边形无效跳过。)continueobjects.append((dota_type, polygon))except ValueError as ve:logging.error(f{file_path} 第{line_num}行坐标转换错误: {ve})except Exception as e:logging.error(f读取文件 {file_path} 时发生错误: {e})return objectsdef compute_iou(poly1, poly2):计算两个多边形的IOU。参数poly1 (Polygon): 第一个多边形。poly2 (Polygon): 第二个多边形。返回:float: 两个多边形的IOU值。intersection poly1.intersection(poly2).areaunion poly1.union(poly2).areaif union 0:return 0return intersection / uniondef analyze_file(file_path, by_classFalse, class_mapNone, iou_threshold0.01):分析单个标注文件统计同类别对象之间的IOU超过阈值的对数。参数file_path (str): 标注文件的路径。by_class (bool, optional): 是否按类别统计。默认为False。class_map (set, optional): 需要筛选的类别集合。默认为None表示所有类别。iou_threshold (float, optional): IOU阈值。默认为0.01。返回:list of dicts: 每个字典包含文件名、类别如果按类别统计和重叠对数。filename os.path.basename(file_path)objects parse_annotation_file(file_path, class_map)results []if by_class:# 按类别分组class_dict {}for dota_type, polygon in objects:class_dict.setdefault(dota_type, []).append(polygon)for dota_type, polygons in class_dict.items():overlap_count 0num_objects len(polygons)if num_objects 2:# 少于两个对象无需比较results.append({filename: filename,class: dota_type,overlap_count: 0})continue# 使用组合生成所有可能的对象对for poly1, poly2 in combinations(polygons, 2):iou compute_iou(poly1, poly2)if iou iou_threshold:overlap_count 1results.append({filename: filename,class: dota_type,overlap_count: overlap_count})else:# 不按类别统计所有对象之间的重叠polygons [polygon for _, polygon in objects]overlap_count 0num_objects len(polygons)if num_objects 2:for poly1, poly2 in combinations(polygons, 2):iou compute_iou(poly1, poly2)if iou iou_threshold:overlap_count 1results.append({filename: filename,overlap_count: overlap_count})return resultsdef main():args parse_args()anno_folder args.anno_folderoutput_csv args.output_csviou_threshold args.iou_thresholdnum_workers args.num_workersby_class args.by_class# 定义类别映射如果需要筛选特定类别可以在这里修改# 例如class_map {embankment_dota, gravity_dota}class_map None # 设置为None表示分析所有类别# class_map {embankment_dota} # 只分析 embankment_dota 类别# 获取所有标注文件all_files [os.path.join(anno_folder, f) for f in os.listdir(anno_folder) if os.path.isfile(os.path.join(anno_folder, f))]logging.info(f找到 {len(all_files)} 个标注文件。)# 准备并行处理results []with ProcessPoolExecutor(max_workersnum_workers) as executor:future_to_file {executor.submit(analyze_file, file_path, by_class, class_map, iou_threshold): file_path for file_path in all_files}for future in as_completed(future_to_file):file_path future_to_file[future]try:file_results future.result()results.extend(file_results)logging.info(f完成分析文件: {os.path.basename(file_path)})except Exception as exc:logging.error(f分析文件 {os.path.basename(file_path)} 时发生异常: {exc})# 将结果写入CSVif results:df pd.DataFrame(results)df.to_csv(output_csv, indexFalse)logging.info(f分析结果已保存到 {output_csv})else:logging.warning(没有生成任何分析结果。)if __name__ __main__:main()代码详解
接下来我们将详细解释该脚本的每个部分。
1. 配置日志和命令行参数解析
我们首先配置了日志系统以便记录运行时的相关信息。日志系统可以帮助我们实时跟踪程序的执行状态和潜在问题。
import logginglogging.basicConfig(levellogging.INFO,format%(asctime)s [%(levelname)s] %(message)s,handlers[logging.StreamHandler()]
)然后定义了命令行参数解析函数 parse_args()用于接收用户输入的文件夹路径、IOU阈值、输出文件路径、并行进程数等参数
def parse_args():parser argparse.ArgumentParser(description进行标注文件的IOU分析统计同类别对象之间的重叠数量。)parser.add_argument(--anno_folder, typestr, requiredTrue, help标注文件夹路径)parser.add_argument(--output_csv, typestr, defaultiou_overlap_results.csv, help输出CSV文件路径)parser.add_argument(--iou_threshold, typefloat, default0.01, helpIOU阈值超过此值视为重叠)parser.add_argument(--num_workers, typeint, defaultNone, help并行处理的进程数默认为CPU核心数)parser.add_argument(--by_class, actionstore_true, help是否按类别统计重叠数量)return parser.parse_args()2. 解析DOTA格式文件
DOTA标注文件包含多个对象的坐标和类别通常以文本行的形式存储。我们通过 parse_annotation_file() 函数读取文件内容并提取每个对象的类别和多边形坐标。
def parse_annotation_file(file_path, class_mapNone):解析标注文件提取对象的类别和多边形坐标。参数file_path (str): 标注文件的路径。class_map (set, optional): 需要筛选的类别集合。默认为None表示不筛选。返回:list of tuples: 每个元组包含类别和对应的Shapely多边形。objects []try:with open(file_path, r) as file:for line_num, line in enumerate(file, 1):parts line.strip().split()if len(parts) 9:logging.warning(f{file_path} 第{line_num}行格式不正确跳过。)continuetry:# 假设坐标为前8个元素类别为第9个元素coords list(map(float, parts[:8]))dota_type parts[8]if class_map and dota_type not in class_map:continue# 将坐标转换为Shapely多边形polygon Polygon(np.array(coords).reshape(-1, 2))if not polygon.is_valid:logging.warning(f{file_path} 第{line_num}行的多边形无效跳过。)continueobjects.append((dota_type, polygon))except ValueError as ve:logging.error(f{file_path} 第{line_num}行坐标转换错误: {ve})except Exception as e:logging.error(f读取文件 {file_path} 时发生错误: {e})return objects
通过这个函数我们可以将文件中的每个对象转化为一个Shapely库支持的多边形对象方便后续计算IOU。
3. 计算IOU
IOU交并比的计算公式如下 我们利用Shapely库中的 intersection() 和 union() 方法来计算两个多边形的交集和并集面积。
def compute_iou(poly1, poly2):intersection poly1.intersection(poly2).areaunion poly1.union(poly2).areaif union 0:return 0return intersection / union4. 文件分析与并行化处理
analyze_file() 函数用于分析单个标注文件统计同类别对象之间的IOU超过设定阈值的对数。支持按类别统计或整体统计。
def analyze_file(file_path, by_classFalse, class_mapNone, iou_threshold0.01):分析单个标注文件统计同类别对象之间的IOU超过阈值的对数。参数file_path (str): 标注文件的路径。by_class (bool, optional): 是否按类别统计。默认为False。class_map (set, optional): 需要筛选的类别集合。默认为None表示所有类别。iou_threshold (float, optional): IOU阈值。默认为0.01。返回:list of dicts: 每个字典包含文件名、类别如果按类别统计和重叠对数。filename os.path.basename(file_path)objects parse_annotation_file(file_path, class_map)results []if by_class:# 按类别分组class_dict {}for dota_type, polygon in objects:class_dict.setdefault(dota_type, []).append(polygon)for dota_type, polygons in class_dict.items():overlap_count 0num_objects len(polygons)if num_objects 2:# 少于两个对象无需比较results.append({filename: filename,class: dota_type,overlap_count: 0})continue# 使用组合生成所有可能的对象对for poly1, poly2 in combinations(polygons, 2):iou compute_iou(poly1, poly2)if iou iou_threshold:overlap_count 1results.append({filename: filename,class: dota_type,overlap_count: overlap_count})else:# 不按类别统计所有对象之间的重叠polygons [polygon for _, polygon in objects]overlap_count 0num_objects len(polygons)if num_objects 2:for poly1, poly2 in combinations(polygons, 2):iou compute_iou(poly1, poly2)if iou iou_threshold:overlap_count 1results.append({filename: filename,overlap_count: overlap_count})return results
推荐工具 在本文代码中我们使用了以下Python库它们在处理几何计算、多进程处理、文件解析等方面发挥了重要作用。如果你对这些库不太熟悉可以通过以下链接获取更多信息和文档。 Shapely - 进行几何对象的构造和操作比如多边形的交集、并集等计算。 官方文档Shapely Documentation安装方法pip install shapely NumPy - 科学计算库用于处理数值数组。在这里我们用它来将多边形的坐标转换为二维数组。 官方文档NumPy Documentation安装方法pip install numpy itertools - Python标准库中的组合工具用于生成多边形配对计算它们之间的IOU。 官方文档itertools Documentation concurrent.futures - Python标准库中的并发工具用于多进程并行处理标注文件。 官方文档concurrent.futures Documentation 结论
通过这篇博客我们详细介绍了如何使用Python并行化处理DOTA格式的标注文件并统计对象之间的IOU重叠情况。该脚本不仅具有较强的灵活性支持按类别或整体统计还充分利用多进程加速大数据量的处理。希望这篇博客能够帮助你在实际项目中更高效地处理和分析目标检测任务中的标注文件。 ---
希望这篇博客对您有所帮助如果您喜欢这篇文章请点赞或关注我会持续分享更多实用的 Python 技术内容
---
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/914048.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!