目标检测 YOLOv5 - 模型推理预处理 letterbox

复制代码
import cv2
import numpy as np

def letterbox(im, new_shape=(640, 640), color=(114, 114, 114), auto=True, scaleFill=False, scaleup=True, stride=32):
    # Resize and pad image while meeting stride-multiple constraints
    shape = im.shape[:2]  # current shape [height, width]
    if isinstance(new_shape, int):
        new_shape = (new_shape, new_shape)

    # Scale ratio (new / old)
    r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])
    if not scaleup:  # only scale down, do not scale up (for better val mAP)
        r = min(r, 1.0)

    # Compute padding
    ratio = r, r  # width, height ratios
    new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r))
    dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1]  # wh padding
    if auto:  # minimum rectangle
        dw, dh = np.mod(dw, stride), np.mod(dh, stride)  # wh padding
    elif scaleFill:  # stretch
        dw, dh = 0.0, 0.0
        new_unpad = (new_shape[1], new_shape[0])
        ratio = new_shape[1] / shape[1], new_shape[0] / shape[0]  # width, height ratios

    dw /= 2  # divide padding into 2 sides
    dh /= 2

    if shape[::-1] != new_unpad:  # resize
        im = cv2.resize(im, new_unpad, interpolation=cv2.INTER_LINEAR)
    top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1))
    left, right = int(round(dw - 0.1)), int(round(dw + 0.1))
    im = cv2.copyMakeBorder(im, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)  # add border
    return im, ratio, (dw, dh)

# Example usage:
# Load an image
image = cv2.imread(r".\data\images\bus.jpg")

# Resize and pad the image
resized_image, _, _ = letterbox(image, new_shape=(640, 640))

# Save the resized and padded image
cv2.imwrite("../resized_and_padded_image.jpg", resized_image)

auto=True时候结果,此时输出的不是640*640,而是480*640,原图810*1080的,把最长的边缩小到640,而短边按照比列处理.对应模型不是必须要求输入640*640

auto为False时候的结果为,此时的模型输入必须是640*640,短边进行padding,像素为(114,114,114)

目标检测 YOLOv5 - 模型推理预处理 letterbox_yolov5 letterbox-CSDN博客

在训练的是后构造的数据集是调用的这个类,这个类的auto为False

在detect的时候,调用的是loadimages

这个时候的的auto是true

处理不同的图像上的坐标信息,进行坐标变换

复制代码
def scale_coords(img1_shape, coords, img0_shape, ratio_pad=None):  # resize的图, 坐标, 原图, padding的比例
    # Rescale coords (xyxy) from img1_shape to img0_shape
    if ratio_pad is None:  # calculate from img0_shape
        gain = min(img1_shape[0] / img0_shape[0], img1_shape[1] / img0_shape[1])  # gain  = old / new
        pad = (img1_shape[1] - img0_shape[1] * gain) / 2, (img1_shape[0] - img0_shape[0] * gain) / 2  # wh padding
    else:
        gain = ratio_pad[0][0]
        pad = ratio_pad[1]

    coords[:, [0, 2]] -= pad[0]  # x padding
    coords[:, [1, 3]] -= pad[1]  # y padding
    coords[:, :4] /= gain
    clip_coords(coords, img0_shape)
    return coords


def clip_coords(boxes, shape):
    # Clip bounding xyxy bounding boxes to image shape (height, width)
    if isinstance(boxes, torch.Tensor):  # faster individually
        boxes[:, 0].clamp_(0, shape[1])  # x1
        boxes[:, 1].clamp_(0, shape[0])  # y1
        boxes[:, 2].clamp_(0, shape[1])  # x2
        boxes[:, 3].clamp_(0, shape[0])  # y2
    else:  # np.array (faster grouped)
        boxes[:, [0, 2]] = boxes[:, [0, 2]].clip(0, shape[1])  # x1, x2
        boxes[:, [1, 3]] = boxes[:, [1, 3]].clip(0, shape[0])  # y1, y2
相关推荐
一杯仙妖气10 分钟前
Grok 4.6 正式发布!性能直接飙升,xAI 这次真的开始冲击第一梯队! 可免费试用 2026年8月20日 admin AI xAI
人工智能
白露与泡影14 分钟前
解密 Pi 的 Harness 工程:Agent 会话如何实现持久化与恢复
java·人工智能·算法
DogDaoDao21 分钟前
Magma:微软如何用一个模型打通数字与物理世界的 AI Agent
人工智能·微软·机器人·大模型·机器人模型·智能体·magma
DS随心转插件30 分钟前
Grok生成的html怎么导出——AI导出鸭:大模型结构化输出的“最后一公里”工程化解构
前端·人工智能·ai·html·豆包·deepseek·ai导出鸭
世隆科技37 分钟前
武汉世隆科技有限公司获评2026湖北省科创“新物种“瞪羚企业
人工智能
yinmaisoft40 分钟前
当 AI“长”进低代码:从外挂点缀到原生融合,软件开发正在经历怎样的变革?
人工智能·低代码
2301_7867566043 分钟前
今日未放榜!国自然等待期,别被往年“周五经验”绑架
大数据·人工智能·科研·国自然·国家自然科学基金
进军的码农1 小时前
政府采购联想工作站:授权链合规验证+投标资质+代理商选择全指南
人工智能·技术支持·联想工作站·代理商推荐·cuda部署
东离与糖宝1 小时前
GLM‑5.3+ZCode原配登场!实测一下午重构完整导航站
人工智能
lailai04101 小时前
学校AI教学功能类型
人工智能