数据集制作
将不统一尺寸的图片数据集批量处理为固定大小图片,使所有图片分辨率一致,分辨率大小可手动设置
代码修改路径后即可实现
功能:批量裁剪图片数据集,将修改后的每个图片保存在指定文件夹下,为指定的分辨率大小,
代码片
.
VERSION = "Photo Resizer v1.0 build 2010-8-25"
import os
import sys
import time
import glob
from PIL import Image
class PicResizer:
"""根据指定的目录,对该目录下的所有照片进行大小调整
"""
def __init__(self, picpath, bakpath):
'''初始化参数'''
self.picpath = picpath
self.bakpath = bakpath
logfile = bakpath + "/log" + time.strftime("%Y%m%d%H%M") + ".txt"
self.log = open(logfile, "a")
def pic_walker(self, path):
'''获取指定目录下的所有JPG照片,不递归深入查找'''
target = []
for files in glob.glob(path + "/*.jpg"):
filepath, filename = os.path.split(files) # todo: mark
target.append(filename) # 将文件中所有的图片获取出来 放入target CV_QE_10.jpg
return target
def check_folder(self, subFolderName):
'''检查目标文件夹是否存在,不存在则创建之'''
foldername = self.bakpath + '/' + subFolderName
print(foldername)
if not os.path.isdir(foldername):
os.mkdir(foldername)
return foldername
def pic_info(self, img):
'''获取照片的尺寸'''
w, h = img.size
if w>h:
return w, h, 0 # 横版照片
else:
return w, h, 1 # 竖版照片
def comp_num(self, x, y):
'''比较两个实数
如果是用直接比较话会出现经典的整数除得0问题
'''
x = float(x)
y = float(y)
return float(x/y)
def pic_resize(self, picname, p_w, p_h):
'''根据设定的尺寸,对指定照片进行像素调整'''
# 获取指定照片的规格,一般是1024,768
img = Image.open(picname)
w, h, isVertical = self.pic_info(img)
# 判断照片横竖,为竖版的话对调w,h
if isVertical:
p_w, p_h = p_h, p_w
# 如果照片调整比例合适,直接输出
if self.comp_num(p_h, p_w) == self.comp_num(h, w):
target = img.resize(
(int(p_w), int(p_h)),
Image.ANTIALIAS # hack: 参数呐!高保真必备!
)
# ANTIALIAS: a high-quality downsampling filter
# BILINEAR: linear interpolation in a 2x2 environment
# BICUBIC: cubic spline interpolation in a 4x4 environment
return target
# 比例不合适就需要对照片进行计算,保证输出照片的正中位置
if self.comp_num(p_h, p_w) > self.comp_num(h, w):
# 240/320 > 360/576 偏高照片的处理
# 以高为基准先调整照片大小
p_w_n = p_h * self.comp_num(w,h) # 根据新高按比例设置新宽
temp_img = img.resize(
(int(p_w_n), int(p_h)),
Image.ANTIALIAS
)
# 获取中间选定大小区域
c = (p_w_n - p_w)/2 # 边条大小
box = (c, 0, c+p_w, p_h) # 选定容器
box = tuple(map(int, box)) # 转换成crop需要的int形参数
target = temp_img.crop(box)
return target
else:
# 偏宽的照片
# 以宽为基准先调整照片大小
p_h_n = p_w * self.comp_num(h, w) # 根据新宽按比例设置新高
temp_img = img.resize(
(int(p_w), int(p_h_n)),
Image.ANTIALIAS
)
# 获取新图像
c = (p_h_n - p_h)/2
box = (0, c, p_w, c+p_h)
box = tuple(map(int, box))
target = temp_img.crop(box)
return target
def run_auto(self, *args):
'''运行调整照片尺寸进程
接纳规格列表,每个规格为一个tuple
'''
# 获取所有图片列表
imglist = self.pic_walker(self.picpath)
# 处理照片
for img in imglist:
imgfile = self.picpath + "/" + img # 完整照片名称
try:
for std in args:
w, h = std[0], std[1] # 获取目标照片规格
# 定义目标文件
# opfile = self.check_folder(str(w)+"x"+str(h)) + "/" + img # 这里需要注意
opfile = self.check_folder("CV_QueenElizabeth1") + "/" + img # 这里需要注意
tempimg = self.pic_resize(imgfile, int(w), int(h))
tempimg.save(opfile, 'jpeg')
# self.log.write(str(img) + "\tOK\n")
except:
self.log.write(str(img) + "\tErr\n")
print('-->' + img)
print("Done.")
def main():
# picpath = "F:/code/Classification/data1/ClassifyImage/CV_QueenElizabeth/CV_QE_3.jpg"
picpath = "F:/code/Classification/data1/ClassifyImage/CV_QueenElizabeth"
# 修改为你的目标路径
bakpath = "F:/code/Classification/data1/ClassifyImage/"
# 实例一个进程并运行
resizer = PicResizer(picpath, bakpath)
# resizer.run_auto((320, 240), (240, 200))
resizer.run_auto((300, 300))
if __name__ == "__main__":
sys.exit(main())
``