当前位置:   article > 正文

【pytorch】自己实现精简版YOLOV3【三】,YOLOV3输入图片预处理:输入图片缩放及将生成预测框还原至原图_yolo输入图像不是416怎么办

yolo输入图像不是416怎么办

接上篇博文
Yolov3网络的输入默认为416x416,然后待检测的图片不总是416x416,这就产生了如何将待检测图片,在不破坏特征的情况下缩放至416x416,并对应在网络产生预测框后,如何将416x416图中的预测框还原至原图的问题。
对此,Yolov3的方法如下图所示,分为3步:
1.求取缩放比例,将目标416x416,除以输入图像尺寸(width,height),取其中较小的一个比例,将长宽同时按此比例进行缩放。由于是长宽等比缩放,所以图片的特征并不失真。
2.制作rgb为(128,128,128),大小为416*416的底色图片。
3.将两张图片的中心对其,将缩放后的图片粘贴到底色图上。
在这里插入图片描述
![在这里插入图片描述](https://img-blog.csdnimg.cn/11ad5cb346b24e568e773a1d2aae869b.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6aKi5biI5YKF,size_20,color_FFFFFF,t_70,g_se,x_16
其实现的pytorch代码如下:

import os.path
from typing import Iterator
import numpy as np
import torch
import cv2
import matplotlib.pyplot as plt
from PIL import Image
from torch.utils.data import Dataset, DataLoader, Subset, random_split
import re
from functools import reduce
from torch.utils.tensorboard import SummaryWriter as Writer
from torchvision import transforms, datasets
import torchvision as tv
from torch import nn
import torch.nn.functional as F
import time
import math
def letterbox_image(image, size):
    '''
    保持比例的图像缩放用:代替了传统的resize方式
    对图片加以灰色背景,补全较目标比例相差的边缘部分。
    该函数只能处理单张图片
    :param image: 原始图片
    :param size: 目标图像宽高的元组
    :return: 缩放到size后的目标图像
    '''
    iw, ih = image.size
    w, h = size
    scale = min(w / iw, h / ih)
    nw = int(iw * scale)
    nh = int(ih * scale)
    #此时为按比例缩放,为torch提供的函数
    image = image.resize((nw, nh), Image.BICUBIC)
    #构建新的RGB背景图片
    new_image = Image.new('RGB', size, (128, 128, 128))
    #缩放后的图片粘贴至背景图片上
    '''参数可选4元组及2元组,如果选择2元组,则为新图片相当于背景图片的左上角坐标'''
    new_image.paste(image, ((w - nw) // 2, (h - nh) // 2))
    return new_image
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

将此416x416图片输入网络,即可在该416x416图片上预测出目标框;同时,在输出预测结果时,应将输出的目标框,还原至未处理图像上,由此,对应的pytorch代码为:

import os.path
from typing import Iterator
import numpy as np
import torch
import cv2
import matplotlib.pyplot as plt
from PIL import Image
from torch.utils.data import Dataset, DataLoader, Subset, random_split
import re
from functools import reduce
from torch.utils.tensorboard import SummaryWriter as Writer
from torchvision import transforms, datasets
import torchvision as tv
from torch import nn
import torch.nn.functional as F
import time
import math
def returnBoxOnOriginImage(OriginimageShape,boxesOnletterbox_image,imageShape):
    '''
    经过letterbox_image函数缩放过的图片,在其上得到box框坐标后,用此函数返回图片在经letterbox_image函数缩放
    前,box在原图上的位置。
    :param OriginimageShape:原始图片大小,[[w,h],...] size (n,2)
    :param boxesOnletterbox_image: 在最终补齐的图片上的盒大小位置参数:
    [[x,y,w,h],...] size (n,4)其值为边长的比例值。注意,其中x,y为网格中心点的坐标
    :param imageShape:最终补齐的图片大小,[416,416]
    :return:[[x1,y1,x2,y2],...] size (n,4) 比例值,为box左上角及右下角的坐标。
    '''
    #xy从网格中心点坐标转换为网格左上角的坐标:
    boxesOnletterbox_image[:,0:2]=boxesOnletterbox_image[:,0:2]-boxesOnletterbox_image[:,2:4]/2
    #imageShape/OriginimageShape,size为(n,2),输出(n,1)最大值数组
    # 经过长宽缩放但未补全大小的图片大小
    resizedImageShape=OriginimageShape*torch.min(imageShape/OriginimageShape,1,keepdim=True)[0]
    #目前box是画在最终图片上,要将box回归到补全前只经过缩放处理的原始图片
    #以最终图片为基准的缩放比例:
    scales=resizedImageShape/imageShape
    #以最终图片为基准的偏移率:
    offset=(imageShape-resizedImageShape)/2/imageShape
    boxesOnOriginimage=torch.torch.FloatTensor(boxesOnletterbox_image.shape)
    '''将以最终图片为基准的值转为以待补全图像为基准的比例值,由于待补全图片和
    原图是长宽以相同比例放大转换关系,故结果可视为box在原图上的比例值:
    '''
    boxesOnOriginimage[:,0:2]=(boxesOnletterbox_image[:,0:2]-offset)/scales
    boxesOnOriginimage[:,2:4]=boxesOnletterbox_image[:,2:4]/scales
    #从x1,y1,w,h到x1,y1,x2,y2
    boxesOnOriginimage[:, 2:4] = boxesOnletterbox_image[:, 0:2] +boxesOnletterbox_image[:, 2:4]
    return boxesOnOriginimage
#简单测试
OriginimageShape=torch.FloatTensor([[300,400]])
boxesOnletterbox_image=torch.FloatTensor([[100,200,200,200]])
imageShape=torch.FloatTensor([800,800])
print(returnBoxOnOriginImage(OriginimageShape,boxesOnletterbox_image,imageShape).shape)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

测试代码输出结果为:

torch.Size([1, 4])
  • 1

输出结果为[[x1,y1,x2,y2]],该函数输出值为比例形式。
设原图宽为w,高为h,则目标框左上角实际坐标为(x1w,y1h),目标框右下角实际坐标为(x2w,y2h)。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/373515
推荐阅读
相关标签
  

闽ICP备14008679号