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")
效果展示
原图 结果图