如何在Python中调整大小,将图像填充为正方形并保持其长宽比
当我们使用卷积神经网络时,大多数时候,我们需要固定输入图像的大小以将其馈送到网络。通常的做法是将输入图像调整为给定尺寸(不再保持图像的宽高比),然后从调整后的图像中随机裁切出固定尺寸的色块。对于不需要精细细节的图像分类,此做法可能效果很好。但是对于图像检索,我们希望保持图像长宽比不变。在这篇文章中,我将总结一些使用填充将图像调整为正方形并保持其纵横比的方法。
主要思想是首先调整输入图像的大小,以使其最大大小等于给定的大小。然后,我们将调整大小的图像填充为正方形。Python中的许多软件包都可以轻松实现这一目标。
使用PIL
PIL是Python中流行的图像处理软件包。我们可以使用Image
模块或ImageOps
模块来实现我们想要的。
调整大小并填充Image模块
首先,我们创建一个空白的正方形图像,然后将调整大小后的图像粘贴到其上以形成一个新图像。代码是:
from PIL import Image, ImageOps
desired_size = 368
im_pth = "/home/jdhao/test.jpg"
im = Image.open(im_pth)
old_size = im.size # (width, height)
ratio = float(desired_size)/max(old_size)
new_size = tuple([int(x*ratio) for x in old_size])
# im.thumbnail(new_size, Image.ANTIALIAS)
im = im.resize(new_size, Image.ANTIALIAS)
new_im = Image.new("RGB", (desired_size, desired_size))
new_im.paste(im, ((desired_size-new_size[0])//2,
(desired_size-new_size[1])//2))
new_im.show()
调整大小并填充ImageOps模块
PILImageOps
模块具有expand() function ,可以在图像的4边添加边框。在应用此方法之前,我们需要计算尺寸调整后图像的4边的填充长度。
原图居中
delta_w = desired_size - new_size[0]
delta_h = desired_size - new_size[1]
padding = (delta_w//2, delta_h//2, delta_w-(delta_w//2), delta_h-(elta_h//2))
new_im = ImageOps.expand(im, padding)
new_im.show()
在两侧填充5个像素
image = Image.open(imagePath)
new_image = Image.new('RGB', (w+10, h), (255, 255, 255))
new_image .paste(image, (5, 0, w+5, h))
使用OpenCV
在OpenCV中,我们可以 copyMakeBorder 很方便地进行边界划分。调整图像大小和填充图像的完整代码如下:
import cv2
desired_size = 368
im_pth = "/home/jdhao/test.jpg"
im = cv2.imread(im_pth)
old_size = im.shape[:2]
ratio = float(desired_size)/max(old_size)
new_size = tuple([int(x*ratio) for x in old_size])
im = cv2.resize(im, (new_size[1], new_size[0]))
delta_w = desired_size - new_size[1]
delta_h = desired_size - new_size[0]
top, bottom = delta_h//2, delta_h-(delta_h//2)
left, right = delta_w//2, delta_w-(delta_w//2)
color = [0, 0, 0]
new_im = cv2.copyMakeBorder(im, top, bottom, left, right, cv2.BORDER_CONSTANT,
value=color)
cv2.imshow("image", new_im)
cv2.waitKey(0)
cv2.destroyAllWindows()