【图片resize】图片三种缩放方式/letterbox_image实现

本文介绍了图像预处理中两种常见的缩放方式:直接缩放和不变形缩放(Letterbox)。直接缩放可能导致图像变形,而不变形缩放通过填充灰边保持原始比例。YOLOv3和YOLOv5分别采用两端填充和一端填充的策略。代码示例展示了如何实现这两种方法,并提供了相应的Python实现。
摘要由CSDN通过智能技术生成

1 总体简介

对图像进行预处理操作的时候,一般有两种缩放方式。

  • 一种是直接宽、高缩放至想要的宽、高,这种方式快捷,但可能会导致图像变形

  • 一种是等比例缩放,然后用灰色边缘填充
    step1: 计算宽高缩放比例,选择较小的那个缩放系数;
    step2: 计算缩放后的尺寸: 原始图片的长宽都乘以较小的缩放系数;
    step3:计算短边需要填充的灰边数,将短边的两边各自填充一半的灰行即可。

2 实现效果

2.1 直接缩放,不怕变形

针对直接缩放的方式,主要代码如下,全部代码实现见最下方

new_image = image.resize((target_w, target_h), Image.BICUBIC)

变形resize

2.2 不变形缩放/letterbox_image

2.2.1 不变形缩放,两端填充灰边

yolov3使用这个方案
不变形resize,两端填充灰边

2.2.2 不变形缩放,一端填充灰边

Yolov5使用这个方案,是Yolov5推理速度能够很快的一个trick
不变形resize,一端填充灰边

很多图片的长宽比不同导致缩放填充后,两端的黑边大小都不同。而如果填充的比较多,则存在信息冗余,影响推理速度。YOLOv5作者对letterbox的缩放策略进行了修改,对原图自适应的添加最少的黑边。

计算方法:

  1. 计算原始图片宽高与输入尺寸的缩放比例rw和rh,选取r = min(rw,rh)后把原图按r进行缩放
  2. 原图宽和高中一定有一边完全贴合输入尺寸,没有达到输入尺寸的一边计算与输入尺寸的差值,然后进行上下(or左右)的填充。

3 代码运行

import matplotlib.pyplot as plt
from PIL import Image

# ------------------------------------------------------------------------#
#   对输入图像进行resize,他人测试发现,不用letterbox_image直接resize的效果更好
# ------------------------------------------------------------------------#
def resize_image(image, size, letterbox_image):
    iw, ih  = image.size
    w, h    = size      # w=200, h=300
    if letterbox_image:
        scale   = min(w/iw, h/ih)
        nw      = int(iw*scale)
        nh      = int(ih*scale)

        image   = image.resize((nw,nh), Image.BICUBIC)
        # 新建一张image,第二个参数表示尺寸,第三个参数表示颜色
        new_image = Image.new('RGB', size, (128,128,128))       
        
        # --------------------------------------------------------------#
        # 	不变形resize,两端填充灰边
        #   image.paste函数表示将一张图片覆盖到另一张图片的指定位置去
        #   a.paste(b, (50,50))   将b的左上顶点贴到a的坐标为(50,50)的位置,
        #	左上顶点为(0,0), b超出a的部分会被自动舍弃
        # --------------------------------------------------------------#
        # new_image.paste(image, ((w-nw)//2, (h-nh)//2))   
        
        # ---------------------------------------------------#
        # 	不变形resize,一端填充灰边
        # ---------------------------------------------------#
        new_image.paste(image, (0, 0))      
    else:
        new_image = image.resize((w, h), Image.BICUBIC)
    return new_image


img_PIL = Image.open("Avatar.jpg")
# ---------------------------------------------------#
# 第二参数表示目标尺寸,第三参数表示是否使用letterbox
# ---------------------------------------------------#
img = resize_image(img_PIL, (200, 300), True)   

plt.imshow(img)
plt.show()
  • 6
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值