Files
2025-10-07 23:57:26 +08:00

71 lines
3.1 KiB
Python

import numpy as np
from PIL import Image
# 这个辅助函数与你原始代码中的完全相同,用于确定中间尺寸
def find_closest_aspect_ratio(aspect_ratio, target_ratios, width, height, image_size):
"""
Finds the closest aspect ratio from a list of target ratios.
This function is identical to the one in the preprocessing script.
"""
best_ratio_diff = float('inf')
best_ratio = (1, 1)
area = width * height
for ratio in target_ratios:
target_aspect_ratio = ratio[0] / ratio[1]
ratio_diff = abs(aspect_ratio - target_aspect_ratio)
if ratio_diff < best_ratio_diff:
best_ratio_diff = ratio_diff
best_ratio = ratio
elif ratio_diff == best_ratio_diff:
if area > 0.5 * image_size * image_size * ratio[0] * ratio[1]:
best_ratio = ratio
return best_ratio
def scale_bbox_to_original(bbox, orig_width, orig_height, image_size=448, min_num=1, max_num=12):
"""
Scales a bounding box from the model's output coordinate system back to the original image's coordinate system.
Args:
bbox (list or tuple): The bounding box [xmin, ymin, xmax, ymax] from the model output.
orig_size (tuple): The original image size as (width, height).
image_size (int): The base processing size for each patch (e.g., 448).
min_num (int): The min_num parameter used during preprocessing.
max_num (int): The max_num parameter used during preprocessing.
Returns:
list: The absolute bounding box coordinates [xmin, ymin, xmax, ymax] on the original image.
"""
model_xmin, model_ymin, model_xmax, model_ymax = bbox
# --- 步骤 1: 重新计算预处理时的中间尺寸 (target_width, target_height) ---
# 这部分逻辑必须与 `dynamic_preprocess` 函数完全一致,以确保尺寸计算同步。
aspect_ratio = orig_width / orig_height
# Generate the set of possible grid ratios
target_ratios = set(
(i, j) for n in range(min_num, max_num + 1) for i in range(1, n + 1) for j in range(1, n + 1) if
i * j <= max_num and i * j >= min_num)
target_ratios = sorted(target_ratios, key=lambda x: x[0] * x[1])
# Find the best grid layout that matches the original aspect ratio
target_aspect_ratio = find_closest_aspect_ratio(
aspect_ratio, target_ratios, orig_width, orig_height, image_size)
# Calculate the dimensions of the intermediate resized image
target_width = image_size * target_aspect_ratio[0]
target_height = image_size * target_aspect_ratio[1]
# --- 步骤 2: 计算缩放比例 ---
# 计算从“模型输出坐标系(中间大图)”到“原始图片坐标系”的缩放因子
scale_w = orig_width / target_width
scale_h = orig_height / target_height
# --- 步骤 3: 应用缩放 ---
# 将模型输出的 bbox 坐标乘以缩放因子,得到在原始图片上的绝对坐标
final_xmin = int(round(model_xmin * aspect_ratio))
final_ymin = int(round(model_ymin))
final_xmax = int(round(model_xmax * aspect_ratio))
final_ymax = int(round(model_ymax))
return (final_xmin, final_ymin, final_xmax, final_ymax)