Python按照指定大小和比例居中裁剪和缩放图片

Python按照指定大小和比例居中裁剪和缩放图片,第1张

这个脚本的需求,源于某些场景下机器学习需要预先处理数据,例如端侧目标检测如果将训练数据集处理成与端侧图像输入相同的尺寸,会明显提高准确率。
上代码,使用了pillowpathlib。最后显示源文件夹、目标文件夹,转换的文件数量,以及文件列表。代码会自动遍历子文件夹,但是代码对重名文件不进行检测,如果子文件夹有重名文件,会默认覆盖同名的输出文件。
要求Python版本 >=3.6(我用了f表达式)
先看效果:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
###
# File: /Users/simonliu/Documents/python/imgresize.py
# Project: /Users/simonliu/Documents/python
# Created Date: 2022-05-05 23:00:44
# Author: Simon Liu
# -----
# Last Modified: 2022-05-07 23:35:41
# Modified By: Simon Liu
# -----
# Copyright (c) 2022 SimonLiu Inc.
# 
# 将文件夹下的图片居中剪裁为指定比例并缩放到指定大小
# -----
# HISTORY:
# Date      	By	Comments
# ----------	---	----------------------------------------------------------
###

from PIL import Image
from pathlib import Path
import time

# 目标尺寸
dst_w = 224
dst_h = 224

src_dir = 'Pictures/cat_data'
dst_dir = f'Pictures/cat_{dst_w}x{dst_h}'
p1 = Path.home()/Path(src_dir)
p2 = Path.home()/Path(dst_dir)
filecount = 0

# 此参数规定了最后文件列表每行显示的文件名数量。
display_each_line = 10

def resize_dir_images(dir):
    global p1,filecount
    for f in p1.glob("**/*"):
        if(f.is_file()):
            filecount += 1
            print('正在转换第 %d 个文件:%s       \r'%(filecount,f.name),end='')
            crop_and_resize(f)
            
            
def crop_and_resize(fp):
    """ 图片按照目标比例裁剪并缩放 """
    global dst_w,dst_h,p2
    im = Image.open(str(fp))
    src_w,src_h = im.size
    dst_scale = float(dst_h / dst_w) #目标高宽比
    src_scale = float(src_h / src_w) #原高宽比

    if src_scale >= dst_scale:
        #过高
        width = src_w
        height = int(width*dst_scale)
        x = 0
        y = (src_h - height) / 3
    else:
        #过宽
        height = src_h
        width = int(height*dst_scale)
        x = (src_w - width) / 2
        y = 0
    #裁剪
    box = (x,y,width+x,height+y)
    #这里的参数可以这么认为:从某图的(x,y)坐标开始截,截到(width+x,height+y)坐标
    newIm = im.crop(box)
    im = None
    #压缩
    ratio = float(dst_w) / width
    newWidth = int(width * ratio)
    newHeight = int(height * ratio)
    dst_file = p2/fp.name
    # print('dst_file:',dst_file)
    # newIm.resize((newWidth,newHeight),resample=LANCZOS).save(dst_file,quality=100)
    newIm.resize((newWidth,newHeight),Image.Resampling.LANCZOS).save(dst_file,quality=100)

def main():
    global p1,p2,filecount
    cnt = 0
    print('原始图片文件夹:',p1)
    print(f'目标文件夹:',p2)
    if p2.exists():
        print(f'目标文件夹 {p2} 已经存在...')
    else:
        print(f'创建目标文件夹: {p2} ')
        p2.mkdir(exist_ok=True, parents=True)
    time.sleep(1)
    print(f'目标分辨率:{dst_w}x{dst_h}')
    resize_dir_images(str(p1))
    dst_file_list = p2.iterdir()
    print(f'\n一共转换了{filecount}个文件\n已转换的文件列表:',end='')
    line_count = 0
    for f in sorted(dst_file_list, key = lambda f : f.stem):
        cnt += 1
        if cnt%display_each_line == 1:
            line_count += 1
            print('\n%d | %10s'%(line_count,f.name),end='')
        else:
            print('%10s'%f.name,end='')
    

if __name__ == '__main__':
    main()

参考文献:
python使用pil进行图像处理(等比例压缩、裁剪)实例代码

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/874750.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-13
下一篇 2022-05-13

发表评论

登录后才能评论

评论列表(0条)

保存