ymj_bim_test/utils.py

95 lines
3.5 KiB
Python
Raw Normal View History

2025-02-27 17:31:43 +08:00
import json
import logging
import cv2
2025-02-28 15:15:33 +08:00
"""
根据裁剪之后的图片,每个点的坐标需要重新计算,以新的图片的宽高作为坐标系
"""
def re_cal_point(point,offset):
# 相当于所有的x坐标向左平移了offset个距离
point['x'] = point['x'] - offset
2025-02-27 17:31:43 +08:00
2025-02-28 15:15:33 +08:00
"""
过滤矩形
1 高度过大的不要
2 整个矩形全部身体都在裁剪区域之外的不要
返回值:
1 过滤之后的矩形
2 裁剪之后的图片
"""
def filter_rectangle(image_path, points):
# 高度过大矩形过滤参数
2025-02-27 17:31:43 +08:00
max_height_rate = 0.5 # 矩形高度占整个画面高度的最大比例,如果超过该比例,则认为是无效矩形
2025-02-28 15:15:33 +08:00
# 裁剪参数
2025-02-28 19:19:41 +08:00
left_x_cut_rate=0.1 # 左边界的裁剪比例,从左边开始裁剪百分之多少
right_x_cut_rate=0.1# 右边界的裁剪比例,从右边开始裁剪百分之多少
2025-02-27 17:31:43 +08:00
image = cv2.imread(image_path)
2025-02-28 15:15:33 +08:00
image_height = image.shape[0] # 获取图片高度
image_width = image.shape[1] # 获取图片宽度
image_x_min = int(image_width * left_x_cut_rate) # 左边界的裁剪点
image_x_max = int(image_width * (1 - right_x_cut_rate)) # 右边界的裁剪点
2025-02-27 17:31:43 +08:00
2025-02-28 15:15:33 +08:00
#开始过滤矩形
2025-02-27 17:31:43 +08:00
bad_point_index = []
2025-02-28 15:15:33 +08:00
print(f'开始过滤矩形,原有矩形数为{len(points)}')
2025-02-27 17:31:43 +08:00
for index in range(len(points)):
point = points[index]
2025-02-28 15:15:33 +08:00
2025-02-27 17:31:43 +08:00
# 高度过大过滤
if point['height'] > image_height * max_height_rate:
bad_point_index.append(index)
continue
2025-02-28 15:15:33 +08:00
# x坐标范围过滤,整个矩形全部身体都在裁剪区域之外的不要
x_min = point['x'] # 矩形四个矩形坐标中x的最小值
x_max = point['x'] + point['width'] # 矩形四个矩形坐标中x的最大值
# 如果矩形x的 最大值 小于 左边界,去除这个矩形
if x_max < image_x_min:
2025-02-27 17:31:43 +08:00
bad_point_index.append(index)
continue
2025-02-28 15:15:33 +08:00
# 如果矩形x的 最小值 大于 右边界,去除这个矩形
if x_min > image_x_max:
2025-02-27 17:31:43 +08:00
bad_point_index.append(index)
continue
2025-02-28 15:15:33 +08:00
# 过滤,只保留有效矩形
2025-02-27 17:31:43 +08:00
filtered_points = []
for i, point in enumerate(points):
2025-02-28 15:15:33 +08:00
# 如果当前矩形的索引在bad_point_index中则去除这个矩形
2025-02-27 17:31:43 +08:00
if i not in bad_point_index:
2025-02-28 15:15:33 +08:00
# 重新计算点的坐标
re_cal_point(point,image_x_min)
# 塞入结果
2025-02-27 17:31:43 +08:00
filtered_points.append(point)
2025-02-28 15:15:33 +08:00
print(f'过滤矩形结束,过滤之后的矩形数为{len(filtered_points)}')
# 图片裁剪
# 裁剪图片 (height方向不变宽度方向裁剪)
cropped_image = image[:, image_x_min:image_x_max]
# 展示
# cv2.imshow("cropped_image", cropped_image)
# cv2.imshow("image", image)
# for i in range(len(filtered_points)):
# p = filtered_points[i]
# cv2.rectangle(cropped_image, (p['x'], p['y']), (p['x'] + p['width'], p['y'] + p['height']), (0, 0, 255), 2)
# # 写编号
# cv2.putText(cropped_image, str(i), (p['x'], p['y']), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
# cv2.imshow("cropped_image_draw", cropped_image)
# cv2.waitKey(0)
return filtered_points, cropped_image
2025-02-27 17:31:43 +08:00
2025-02-28 15:15:33 +08:00
# 测试代码
2025-02-27 17:31:43 +08:00
# def read_from_json(file_path):
# with open(file_path, 'r') as f:
# loaded_array = json.load(f)
# return loaded_array
# cnts = read_from_json("data_sub/test_1/data_sub.json")
2025-02-28 15:15:33 +08:00
# filter_rectangle("data_sub/test_1/wide_image.png",cnts)