Home 中国女排世界杯视频 Python之图像转正方形

Python之图像转正方形

Python之图像转正方形

我们在做项目前,首先要制作数据集,而往往在制作数据集时都会对图片进行预处理,今天将我学习的PIL中将图片转成正方形并且保证图片不变形的三种方法,留作笔记,以便日后复查。

通过创建一张以图像长边为边长的大正方形纯色底图,再将图片直接粘贴到底图上,得到正方形图片。

#-*-coding:utf-8-*-

from PIL import Image

def convert_square_paste(image):

"""

convert to square with paste

:param image:Images that need to be processed

:return:After processing the picture

"""

width,height = image.size

new_image_length = max(width,height)#获取新图边长

new_image = Image.new("RGB",(new_image_length,new_image_length),(127,127,127))#生成一张正方形底图

pad_len = int(abs(width-height)/2)#预填充区域的大小

box = (0,pad_len) if width > height else (pad_len,0)

new_image.paste(image,box)

return new_image

用nn.ConstantPad2d方法,在输入张量的边界添加指定数量的数字,得到正方形图片。

nn.ConstantPad2方法介绍: m = nn.ConstantPad2d(padding, value) padding:为填充数量,如果为int,表示使用相同方法在所有边界填充padding个value; padding也可以为一个元组(left,right,top,bottom),表示在相应边界填充value; value:为填充的值。

#-*-coding:utf-8-*-

import torch.nn as nn

from torchvision import transforms

def convert_square_pad(image):

"""

convert to square with ConstantPad

"""

width, height = image.size

img = transforms.ToTensor()(image)

img = img.unsqueeze(0)#加轴

pad_len = int(abs(width - height) / 2)#预填充区域的大小

fill_area = (0,0,pad_len,pad_len) if width > height else (pad_len,pad_len,0,0)#需要填充区域,如果宽大于高则上下填充,否则左右填充

img = nn.ConstantPad2d(fill_area,127)(img)#填充像素常值为127

# img = nn.ZeroPad2d(m)(img)#直接填0

img = img.squeeze(0)#去轴

img = transforms.ToPILImage()(img)

return img

将图片转成Numpy,通过切片的方式,将图片转成正方形。

#-*-coding:utf-8-*-

from PIL import Image

import numpy as np

def convert_square_slice(image):

"""

convert to square with slice

"""

img = image.convert('RGB')

img = np.array(img, dtype=np.uint8) # 图片转numpy

img_h, img_w, img_c = img.shape

if img_h != img_w:

long_side = max(img_w, img_h)

short_side = min(img_w, img_h)

loc = int(abs(img_w - img_h)/2)

img = img.transpose((1, 0, 2)) if img_w < img_h else img #如果h>w则换轴,广播机制

background = np.zeros((long_side, long_side, img_c), dtype=np.uint8) # 创建正方形背景

background[loc: loc + short_side] = img[...] # 数据填充在中间位置

img = background.transpose((1, 0, 2)) if img_w < img_h else background

return Image.fromarray(img,"RGB")

效果展示

原图 结果图