import cv2
import numpy as np
from show_pic import get_rectangle_coordinates
class PictureBoxes:
def __init__(self, img, boxes):
self.img = img
self.boxes = boxes
def get_pic(self):
return self.img
def get_boxes(self):
return self.boxes
def resize_and_pad_image(
source: PictureBoxes, target_size=640, fill_color=(255, 255, 255), show=False,
):
"""
将图像调整为不超过指定大小(保持原比例),并在需要时用指定颜色填充空白区域。
:param source: 输入图像及边框
:param show: 是否显示变换后图像
:param target_size: 图像的目标最大边长(宽度或高度),默认值为640。
:param fill_color: 用于填充空白区域的BGR颜色,默认值为白色(255, 255, 255)。
"""
image = source.get_pic()
# 获取图像的原始尺寸
original_height, original_width = image.shape[:2]
# 如果大则使用双线性插值,小则使用重采样插值
if original_width > target_size or original_width > target_size:
opt = cv2.INTER_AREA
else:
opt = cv2.INTER_LINEAR
##
# 计算新尺寸,保持原比例
aspect_ratio = original_width / original_height
if original_width > original_height:
# 图像较宽
new_width = target_size
new_height = int(target_size / aspect_ratio)
# 计算缩放比例
r = target_size/original_width
else:
# 图像较高或正方形
new_height = target_size
new_width = int(target_size * aspect_ratio)
# 计算缩放比例
r = target_size / original_height
# 创建一个空白图像,大小为target_size x target_size,填充颜色为fill_color
padded_image = np.full((target_size, target_size, 3), fill_color, dtype=np.uint8)
# 计算粘贴位置,使图像居中
paste_left = (target_size - new_width) // 2
paste_top = (target_size - new_height) // 2
print([paste_left, paste_top])
# 将调整大小后的图像粘贴到空白图像上
padded_image[paste_top:paste_top + new_height, paste_left:paste_left + new_width] = cv2.resize(
image, (new_width, new_height), interpolation=opt
)
# 变换边界框大小
new_boxes = []
for box in source.get_boxes():
x, y, w, h = box
x = int(round(x * r + paste_left))
y = int(round(y * r + paste_top))
w = int(round(w * r))
h = int(round(h * r))
new_boxes.append([x, y, w, h])
ans = PictureBoxes(padded_image, new_boxes)
# 显示变换后的图像
if show:
img = padded_image
for box in new_boxes:
x, y, w, h = box
img = cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)
cv2.imshow("padded", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
return ans
if __name__ == '__main__':
img = cv2.imread('../A.jpg', cv2.IMREAD_UNCHANGED)
a = PictureBoxes(img, [get_rectangle_coordinates(img)])
b = resize_and_pad_image(a, show=True)
print(b.get_boxes())
有关show_pic包请看python实现图片选框选择
老演员刻晴
选框界面
我们选择刻晴手里的雷史莱姆
点击OK
处理后演示图片
实际函数返回的是定义的PictureBoxes类
其中由pic图片和由多个选框列表组成的列表[[x,y,w,h],[x,y,w,h]...]