目标检测 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
相关推荐
donoot20 分钟前
PaddleOCR + PyMuPDF 生成【全兼容双层 PDF】完整实操指南
人工智能·算法·pymupdf·paddleocr·双层pdf
lpfasd1236 小时前
2026年第30周科技社区趋势周报:开放权重之争与AI Agent的破局
人工智能·科技
佛光芳林8 小时前
AI 情报局:用 PowerMem + SeekDB 做一个多 Agent 记忆小游戏
人工智能
通问AI8 小时前
2026年AI短剧技术现状:全链路AIGC生产已达95%,但用户完播率不足15%
人工智能·aigc
_Jimmy_8 小时前
Agent引用数据库知识过时的增量同步方案
人工智能·python·langchain
qq_454245038 小时前
Systemprompt 体系全览:形式化公理驱动的分层系统设计
人工智能
大龄码农有梦想8 小时前
传统的 BPMN 工作流审批和 AI 工作流有什么区别?
人工智能·流程引擎·工作流·ai agent·ai工作流·审批流·智能体平台
DO_Community8 小时前
Claude Opus 5 现已上线 DigitalOcean AI 推理云
人工智能·llm·agent·claude
幸福指北8 小时前
🚀 开源了,一个人 + AI 肝出一个 AI 终端 | AShell 技术分享
运维·人工智能·ai·终端
可以飞的话8 小时前
一、机器学习概述
人工智能·机器学习