在cv的项目以目标检测,图像分类为例,都需要把图像resize成固定大小然后传入网络去提取特征,如何对你要训练的数据的一些特性合理的使用resize成为比较关键的前处理因素。
首先回顾一下传统的reszie操作
PIL
补充:PIL读取的数据自动就是RGB图像不需要再进行调整
from PIL import Image
from torchvision import datasets, models, transforms
import numbers
img=Image.open('xxz.jpg')
transform = transforms.Compose([
transforms.Resize((299, 299)),
# transforms.ToTensor(),
])
img=transform(img)
img.show()
Opencv
补充:opencv读取图像是BGR需要通过cv2.cvtColor(img, cv2.COLOR_BGR2RGB)调整成RGB
import cv2
img = cv2.imread('')
img = cv2.resize(img, (299, 299))
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
展示:
可以看到将张图片调整到了我们想要的大小,但是模样相比原图似乎有些奇怪

不失帧的resize操作
有的时候对图片进行这种直接resize可能改变图片本身的模样,所以需要换一种reszie的方式
不失真的resize是配合中心裁剪一起使用的
PIL的 Image.resize()函数
img.resize((width, height),Image.BILINEAR))
from PIL import Image
import numbers
img=Image.open('xxz.jpg')
def crop(img, i, j, h, w):
return img.crop((j, i, j + w, i + h))
def center_crop(img, output_size):
if isinstance(output_size, numbers.Number):
output_size = (int(output_size), int(output_size))
w, h = img.size
th, tw = output_size
i = int(round((h - th) / 2.))
j = int(round((w - tw) / 2.))
return crop(img, i, j, th, tw)
def resize(img, size, interpolation=Image.BILINEAR):
if isinstance(size, int):
print(isinstance(size, int))
w, h = img.size
if (w <= h and w == size) or (h <= w and h == size):
return img
if w < h:
ow = size
oh = int(size * h / w)
return img.resize((ow, oh), interpolation)
else:
oh = size
ow = int(size * w / h)
return img.resize((ow, oh), interpolation)
else:
return img.resize(size[::-1], interpolation)
def letterbox_image(image, size):
w, h = size
iw, ih = image.size
if h == w:
new_image = resize(image, h)
else:
new_image = resize(image, [h ,w])
new_image = center_crop(new_image, [h ,w])
return new_image
img=letterbox_image(img, [299,299])
img.show()
利用双线性插值进行resize操作,先通过这个reszie操作等比例放大图像,再通过中心裁剪获得一个(width, height)的图像,如下图所示,第一张图为原图,第二张是正常resize的图像,三四为不失真resize+中心裁剪获得的图像。

ps:要根据自己的数据集进行一个合理的使用