93 lines
3.5 KiB
Python
93 lines
3.5 KiB
Python
import cv2
|
|
import json
|
|
import numpy as np
|
|
|
|
def should_merge(rect1, rect2, vertical_threshold=5, overlap_threshold=0.5):
|
|
# 检查垂直距离
|
|
vertical_close = abs(rect1[1] + rect1[3] - rect2[1]) <= vertical_threshold or \
|
|
abs(rect2[1] + rect2[3] - rect1[1]) <= vertical_threshold
|
|
|
|
# 检查水平重叠
|
|
overlap = min(rect1[0] + rect1[2], rect2[0] + rect2[2]) - max(rect1[0], rect2[0])
|
|
total_width = max(rect1[0] + rect1[2], rect2[0] + rect2[2]) - min(rect1[0], rect2[0])
|
|
overlap_ratio = overlap / min(rect1[2], rect2[2])
|
|
|
|
return vertical_close and overlap_ratio >= overlap_threshold
|
|
|
|
def merge_rectangles(rectangles, vertical_threshold=10, overlap_threshold=0.5):
|
|
merged = []
|
|
while rectangles:
|
|
current = rectangles.pop(0)
|
|
merged.append(current)
|
|
i = 0
|
|
while i < len(rectangles):
|
|
if should_merge(current, rectangles[i], vertical_threshold, overlap_threshold):
|
|
merge_target = rectangles.pop(i)
|
|
new_left = min(current[0], merge_target[0])
|
|
new_top = min(current[1], merge_target[1])
|
|
new_right = max(current[0] + current[2], merge_target[0] + merge_target[2])
|
|
new_bottom = max(current[1] + current[3], merge_target[1] + merge_target[3])
|
|
current = [new_left, new_top, new_right - new_left, new_bottom - new_top]
|
|
merged[-1] = current
|
|
else:
|
|
i += 1
|
|
return merged
|
|
|
|
# 加载JSON数据
|
|
with open('./coordinates.json', 'r') as f:
|
|
data = json.load(f)
|
|
|
|
# 加载图片
|
|
image_path = './example2.jpeg' # 请替换为您的图片路径
|
|
image = cv2.imread(image_path)
|
|
|
|
# 收集所有矩形
|
|
rectangles = []
|
|
for word in data['words_result']:
|
|
loc = word['location']
|
|
rectangles.append([loc['left'], loc['top'], loc['width'], loc['height']])
|
|
|
|
# 合并矩形
|
|
merged_rectangles = merge_rectangles(rectangles)
|
|
|
|
# 对矩形进行排序(从左上到右下)
|
|
merged_rectangles.sort(key=lambda r: (r[1], r[0]))
|
|
|
|
# 在图片上绘制合并后的矩形和序号
|
|
font = cv2.FONT_HERSHEY_SIMPLEX
|
|
font_scale = 0.5
|
|
font_thickness = 1
|
|
padding = 2
|
|
|
|
for i, rect in enumerate(merged_rectangles, 1):
|
|
left, top, width, height = rect
|
|
cv2.rectangle(image, (left, top), (left + width, top + height), (0, 0, 255), 1)
|
|
|
|
# 确定序号的位置
|
|
label = str(i)
|
|
(label_width, label_height), _ = cv2.getTextSize(label, font, font_scale, font_thickness)
|
|
|
|
# 尝试将序号放在左上角
|
|
label_x = max(left, padding)
|
|
label_y = max(top - padding, label_height + padding)
|
|
|
|
# 如果左上角放不下,尝试右上角
|
|
if label_x + label_width > left + width or label_y - label_height < top:
|
|
label_x = min(left + width - label_width - padding, image.shape[1] - label_width - padding)
|
|
label_y = max(top - padding, label_height + padding)
|
|
|
|
# 如果右上角也放不下,放在左下角
|
|
if label_y - label_height < top:
|
|
label_y = min(top + height + label_height + padding, image.shape[0] - padding)
|
|
|
|
# 绘制白色背景
|
|
cv2.rectangle(image, (label_x - padding, label_y - label_height - padding),
|
|
(label_x + label_width + padding, label_y + padding), (255, 255, 255), -1)
|
|
|
|
# 绘制序号
|
|
cv2.putText(image, label, (label_x, label_y), font, font_scale, (0, 0, 255), font_thickness)
|
|
|
|
# 保存结果图片
|
|
cv2.imwrite('./output_image_numbered.jpg', image)
|
|
|
|
print("处理完成,结果已保存为 'output_image_numbered.jpg'") |