目标检测 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
相关推荐
m0_6501082421 分钟前
【论文精读】迈向更好的指标:从T2VScore看文本到视频生成的新评测范式
人工智能·论文精读·评估指标·文本到视频生成·t2vscore·tvge数据集·视频质量评估
算家计算37 分钟前
一张白纸,无限画布:SkyReels刚刚重新定义了AI视频创作
人工智能·aigc·资讯
Kandiy1802539818739 分钟前
PHY6252国产蓝牙低成本透传芯片BLE5.2智能灯控智能家居
人工智能·物联网·智能家居·射频工程
机器之心1 小时前
字节Seed团队发布循环语言模型Ouro,在预训练阶段直接「思考」,Bengio组参与
人工智能·openai
新智元1 小时前
AI 教父 Hinton 末日警告!你必须失业,AI 万亿泡沫豪赌才能「赢」
人工智能·openai
新智元1 小时前
CUDA 再见了!寒武纪亮出软件全家桶
人工智能·openai
oe10192 小时前
好文与笔记分享 A Survey of Context Engineering for Large Language Models(下)
人工智能·笔记·语言模型·agent
有为少年2 小时前
告别乱码:OpenCV 中文路径(Unicode)读写的解决方案
人工智能·opencv·计算机视觉
清风与日月2 小时前
halcon分类器使用标准流程
深度学习·目标检测·计算机视觉
FreeCode2 小时前
LangChain1.0智能体开发:模型使用
人工智能·langchain·agent