Spaces:
Running
on
Zero
Running
on
Zero
import numpy as np | |
import cv2 | |
def calculate_sr_hw_split_ratio( | |
HB_m_offset_list, HB_n_offset_list, | |
HB_m_scale_list, HB_n_scale_list | |
): | |
""" | |
Calculate SR_hw_split_ratio without overlapping regions. | |
Args: | |
HB_m_offset_list (List[float]): Offsets of bounding boxes in the horizontal dimension. | |
HB_n_offset_list (List[float]): Offsets of bounding boxes in the vertical dimension. | |
HB_m_scale_list (List[float]): Scales of bounding boxes in the horizontal dimension. | |
HB_n_scale_list (List[float]): Scales of bounding boxes in the vertical dimension. | |
Returns: | |
str: SR_hw_split_ratio based on the condition checks. | |
""" | |
def has_overlap(offset_list, scale_list): | |
""" | |
Check if any boxes in the given dimension overlap. | |
Args: | |
offset_list (List[float]): Offsets of bounding boxes in the dimension. | |
scale_list (List[float]): Scales of bounding boxes in the dimension. | |
Returns: | |
bool: True if there is overlap, False otherwise. | |
""" | |
for i in range(len(offset_list)): | |
for j in range(i + 1, len(offset_list)): | |
if not (offset_list[i] + scale_list[i] <= offset_list[j] or | |
offset_list[j] + scale_list[j] <= offset_list[i]): | |
return True | |
return False | |
def redistribute_regions(offset_list, scale_list): | |
""" | |
Redistribute the regions to ensure no overlap and full coverage. | |
Args: | |
offset_list (List[float]): Offsets of bounding boxes. | |
scale_list (List[float]): Scales of bounding boxes. | |
Returns: | |
List[float]: Adjusted proportions for each region. | |
""" | |
adjusted_ratios = [] | |
for i in range(len(offset_list)): | |
if i == 0: | |
split_ratio = offset_list[i] + scale_list[i] + (offset_list[i + 1] - offset_list[i] - scale_list[i]) / 2 | |
adjusted_ratios.append(split_ratio) | |
elif i+1 < len(offset_list): | |
mid_point = offset_list[i] + scale_list[i] + (offset_list[i + 1] - offset_list[i] - scale_list[i]) / 2 | |
region_ratio = mid_point - sum(adjusted_ratios) | |
adjusted_ratios.append(region_ratio) | |
else: | |
final_ratio = 1.0 - sum(adjusted_ratios) | |
adjusted_ratios.append(final_ratio) | |
normalized_ratios = [ratio / sum(adjusted_ratios) for ratio in adjusted_ratios] | |
return normalized_ratios | |
def generate_regions(adjusted_ratios, separator): | |
""" | |
Generate normalized regions as a string. | |
Args: | |
adjusted_ratios (List[float]): Adjusted proportions for each region. | |
separator (str): Separator for the output string. | |
Returns: | |
str: Normalized regions as a string. | |
""" | |
return separator.join(f"{region:.2f}" for region in adjusted_ratios) | |
# Check for overlaps | |
vertical_overlap = has_overlap(HB_m_offset_list, HB_m_scale_list) | |
horizontal_overlap = has_overlap(HB_n_offset_list, HB_n_scale_list) | |
# Determine which SR_hw_split_ratio to return | |
if not vertical_overlap and horizontal_overlap: | |
adjusted_ratios = redistribute_regions(HB_m_offset_list, HB_m_scale_list) | |
return generate_regions(adjusted_ratios, ",") | |
elif vertical_overlap and not horizontal_overlap: | |
adjusted_ratios = redistribute_regions(HB_n_offset_list, HB_n_scale_list) | |
return generate_regions(adjusted_ratios, ";") | |
elif not vertical_overlap and not horizontal_overlap: | |
adjusted_ratios = redistribute_regions(HB_m_offset_list, HB_m_scale_list) | |
return generate_regions(adjusted_ratios, ",") | |
else: | |
raise ValueError("Invalid condition: Both dimensions either overlap or do not overlap.") | |
def generate_parameters(bbox_inputs, prompt_width, prompt_height): | |
""" | |
Converts bbox_inputs to offset and scale lists for HB format. | |
Args: | |
bbox_inputs (List[List[int]]): List of bounding boxes, each defined by [x1, y1, x2, y2]. | |
prompt_width (int): Width of the entire image. | |
prompt_height (int): Height of the entire image. | |
Returns: | |
Tuple[List[float], List[float], List[float], List[float]]: | |
HB_m_offset_list, HB_n_offset_list, HB_m_scale_list, HB_n_scale_list. | |
""" | |
HB_m_offset_list = [box[0] / prompt_width for box in bbox_inputs] | |
HB_n_offset_list = [box[1] / prompt_height for box in bbox_inputs] | |
HB_m_scale_list = [(box[2] - box[0]) / prompt_width for box in bbox_inputs] | |
HB_n_scale_list = [(box[3] - box[1]) / prompt_height for box in bbox_inputs] | |
SR_hw_split_ratio = calculate_sr_hw_split_ratio(HB_m_offset_list, HB_n_offset_list, HB_m_scale_list, HB_n_scale_list) | |
return HB_m_offset_list, HB_n_offset_list, HB_m_scale_list, HB_n_scale_list, SR_hw_split_ratio | |
def visualize(HB_m_offset_list, HB_n_offset_list, HB_m_scale_list, HB_n_scale_list, SR_hw_split_ratio, prompt_width, prompt_height): | |
# 创建一个白色背景的图像 | |
image = np.ones((prompt_height, prompt_width, 3), dtype=np.uint8) * 255 | |
for m_offset, n_offset, m_scale, n_scale in zip(HB_m_offset_list, HB_n_offset_list, HB_m_scale_list, HB_n_scale_list): | |
x = int(m_offset * prompt_width) | |
y = int(n_offset * prompt_height) | |
width = int(m_scale * prompt_width) | |
height = int(n_scale * prompt_height) | |
# 绘制边界框 | |
cv2.rectangle(image, (x, y), (x + width, y + height), (255, 0, 0), 2) | |
if ',' in SR_hw_split_ratio: | |
split_ratios = [float(ratio) for ratio in SR_hw_split_ratio.split(',')] | |
orientation = 'vertical' | |
elif ';' in SR_hw_split_ratio: | |
split_ratios = [float(ratio) for ratio in SR_hw_split_ratio.split(';')] | |
orientation = 'horizontal' | |
else: | |
split_ratios = [float(SR_hw_split_ratio)] | |
orientation = 'horizontal' | |
colors = [(0, 0, 255), (0, 255, 0), (255, 255, 0), (125, 125, 0), (255, 0, 255),(0, 125, 255), (125, 255, 0), (255, 255, 125), (125, 0, 0), (125, 0, 255)] | |
current_pos = 0 | |
if orientation == 'vertical': | |
total_length = prompt_width | |
for i, ratio in enumerate(split_ratios): | |
region_width = int(ratio * total_length) | |
# 绘制分割区域 | |
cv2.rectangle(image, (current_pos, 0), (current_pos + region_width, prompt_height), colors[i % len(colors)], 2) | |
current_pos += region_width | |
else: | |
total_length = prompt_height | |
for i, ratio in enumerate(split_ratios): | |
region_height = int(ratio * total_length) | |
# 绘制分割区域 | |
cv2.rectangle(image, (0, current_pos), (prompt_width, current_pos + region_height), colors[i % len(colors)], 2) | |
current_pos += region_height | |
return image | |
if __name__ == "__main__": | |
bbox_inputs = [[5, 20, 100, 150], [160, 20, 190, 210], [230,5,290,290]] | |
# bbox_inputs = [[40, 5, 210, 160], [100, 180, 180, 270]] | |
prompt_width = 300 | |
prompt_height = 300 | |
HB_m_offset_list, HB_n_offset_list, HB_m_scale_list, HB_n_scale_list,SR_hw_split_ratio = generate_parameters(bbox_inputs, prompt_width, prompt_height) | |
print("HB_m_offset_list:", HB_m_offset_list) | |
print("HB_n_offset_list:", HB_n_offset_list) | |
print("HB_m_scale_list:", HB_m_scale_list) | |
print("HB_n_scale_list:", HB_n_scale_list) | |
print("SR_hw_split_ratio:",SR_hw_split_ratio) |