【深度学习实战(10)】图像推理之预处理

ops/2024/10/20 17:19:19/

一、预处理流程

在把一张图像送入模型进行推理时,需要先进行预处理,预处理流程包括:
(1)读取图像
(2)尺寸调整,letter_box(不失真)
(3)通道调整:HWC->CHW
(4)格式调整: array -> tensor
(5)维度调整:CHW -> BCHW
(6)设备调整:to device

二、代码

import torch
import cv2
import numpy as np
from torchvision import transforms# -------------------------------------------------------------------#
#   letterbox:图片缩放,居中对齐,左右或者上下填充,通过仿射变换实现
# -------------------------------------------------------------------#
def letter_box(image, input_w=640, input_h=640):scale = min(input_h / image.shape[0], input_w / image.shape[1])ox = (-scale * image.shape[1] + input_w + scale  - 1) * 0.5oy = (-scale * image.shape[0] + input_h + scale  - 1) * 0.5M = np.array([[scale, 0, ox],[0, scale, oy]], dtype=np.float32)IM = cv2.invertAffineTransform(M)image_prep = cv2.warpAffine(image, M, (input_w, input_h), flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT, borderValue=(114, 114, 114))return image_prep, M, IM#------------------#
#   preprocess
#------------------#
def preprocess(image, input_size, device):# ------------------##   HWC->CHW#   array -> tensor#   CHW -> BCHW#   to device# ------------------#return torch.unsqueeze(transforms.ToTensor()(image), 0).to(device)if __name__ == "__main__":device = 'cpu'model_input_size = [320, 320]# -----------------##   read image# -----------------#image=cv2.imread('demo.png')cv2.imshow('orginal', image)# -----------------##   letter_box# -----------------#M = NoneIM = Noneltbox = (image.shape[0] != model_input_size[0] or image.shape[1] != model_input_size[1])if ltbox:image, M, IM=letter_box(image, 320, 320)cv2.imshow('ltbox', image)cv2.waitKey(0)# -----------------##   preprocess# -----------------#image_in = preprocess(image, model_input_size, device)

二、代码逐行debug调试

运行letter_box后
在这里插入图片描述
运行preprocess后
在这里插入图片描述
我们看看ToTensor对图像做了什么?
ToTensor之前:
在这里插入图片描述
类型:ndarray
通道:HWC
数值:[114,114,114] 未归一化
ToTensor之后:
在这里插入图片描述

类型:Tensor
通道:CHW
数值:[0.4471,0.4471,0.4471] 归一化 0.4471=114/256

通过debug,我们可以发现transforms.ToTensor()一共对图片做了三件事,分别是类型转换通道调整归一化

查阅资料,确认一下
在这里插入图片描述


http://www.ppmy.cn/ops/4847.html

相关文章

gazebo中vins-fusion在仿真小车上的部署

软件要求:Ubuntu 20.04 ros的noetic版本,我是在虚拟机vitrualbox上运行的 这几天在学ROS,跟着赵虚左老师过了一遍之后,感觉还是有很多不懂的地方,xtdrone上仿真跟着文档走了一遍,好像没学到什么东西&#…

MySQL 8 那些新来的参数,给那些快被淘汰的MYSQL DBA

开头还是介绍一下群,如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, Oceanbase, Sql Server等有问题,有需求都可以加群群内有各大数据库行业大咖,CTO,可以解决你的问题。加群请联系 liuaustin3 ,(…

Linux下的GDB调试器:深入使用指南

在Linux软件开发过程中,调试是不可避免的一环,而GDB(GNU Debugger)是最强大的调试工具之一,用于发现运行程序中的疏漏并修复它们。这篇博客将通过详尽的介绍和实用的示例,帮助您熟练掌握GDB的使用方法 list…

Spark-Scala语言实战(16)

在之前的文章中,我们学习了三道任务,运用之前学到的方法。想了解的朋友可以查看这篇文章。同时,希望我的文章能帮助到你,如果觉得我的文章写的不错,请留下你宝贵的点赞,谢谢。 Spark-Scala语言实战&#x…

美业连锁门店收银系统源码-如何查看收款门店对应的加盟商?

美业管理系统源码 博弈美业SaaS系统 连锁多门店美业收银系统源码 多门店管理 / 会员管理 / 预约管理 / 排班管理 / 商品管理 / 促销活动 PC管理后台、手机APP、iPad APP、微信小程序 第一步: 登录pc管理后端 第二步: 进入企业组织管理-门店管理&a…

docker+awk=无敌?!

欢迎来到我的博客,代码的世界里,每一行都是一个故事 dockerawk无敌?! 前言需求分析容器间通过容器名称访问脚本实现一键部署命令解释 前言 当今软件开发的世界充满了数据,而 Docker 则是许多开发者首选的容器化解决方…

nodejs模块机制

模块机制 CommonJs规范 模块引用 上下文提供require()方法来引人外部模块var math require(math) 模块定义 exports 对象用于到处当前模块中的方法和变量module代表模块自身 exports.add function() {...}在另一个模块中使用require()方法进行导入。就可以使用 区别和联系 …

Reka团队打造前沿多模态语言模型,展现卓越性能

eka,一家新兴的人工智能公司,近期推出了一系列强大的多模态语言模型 - Reka Core、Reka Flash和Reka Edge。这些模型不仅能处理和推理文本,还能够灵活应对图像、视频和音频等多种输入,在各项测试中表现出色,在某些指标…