计算机视觉——Opencv blobFromImage与torchvision实现数据标准化

1.blobFromImage

blobFromImage 是 OpenCV 的深度神经网络(DNN)模块中的一个函数,它用于将图像转换为深度学习模型所需的输入格式,主要是对传入的图像进行的转换包括图像尺寸调整、均值减法、缩放等预处理步骤,以便图像数据能够适配深度学习模型的输入要求。

以下是 blobFromImage 函数的一些关键点:

  • 图像尺寸调整:函数可以根据需要调整图像的尺寸,以匹配神经网络的输入尺寸。
  • 均值减法:可以指定一个均值(mean),该函数会从图像的每个通道中减去这个均值。这通常用于数据中心化,以提高模型的训练和推理性能。
  • 缩放:通过 scalefactor 参数,可以对图像数据进行缩放,通常用于数据归一化。
  • 通道交换:如果 swapRB 参数设置为 true,则会交换图像的红色(R)和蓝色(B)通道,因为 OpenCV 默认使用 BGR 格式,而某些神经网络框架使用 RGB 格式。
  • 裁剪:如果 crop 参数设置为 true,则在调整图像大小时进行中心裁剪,以确保输出尺寸与指定的尺寸精确匹配。
  • 数据类型:通过 ddepth 参数可以指定输出 blob 的深度,通常选择 CV_32F(32位浮点数)。
  • 批量处理:还有一个对应的函数 blobFromImages,用于将一系列图像转换为一个批量的 blob,这在处理图像批次时更为高效。
    这个函数是 OpenCV DNN 模块中进行图像预处理的关键步骤,它使得 OpenCV 能够与多种深度学习框架无缝集成,进行图像分类、目标检测、语义分割等任务。
    例如,在进行图像分类时,可以使用 blobFromImage 对输入图像进行预处理,然后通过神经网络模型进行推理,得到预测结果。在 OpenCV 的示例和相关博客文章中,提供了如何使用这个函数的详细说明和示例代码。

函数原型

Mat cv::dnn::blobFromImage	(	InputArray 	image,double 	scalefactor = 1.0,const Size & 	size = Size(),const Scalar & 	mean = Scalar(),bool 	swapRB = false,bool 	crop = false,int 	ddepth = CV_32F 
)

OpenCV中的DNN模块包含blobFromImage方法对输入神经网络的图像进行处理,blobFromImage函数执行的操作及顺序为:

  • 先相对于原图像中心resize,crop
  • 再减均值
  • 像素值缩放0-255 -> 0-1
  • 图像数据通道转换,RGB->BGR
  • 返回一个NCHW 数组

2.torchvision

torchvision库中,transforms模块提供了一系列用于数据增强和预处理的函数,这些函数可以在数据加载后、模型训练前对图像数据进行操作,以适配深度学习模型的输入要求。ToTensorNormalize是两个常用的转换方法,它们通常联合使用来实现图像数据的标准化。

ToTensor转换的作用是将图像数据转换为PyTorch模型可以接受的格式。具体来说,它执行以下操作:

  1. 转换数据类型:将输入图像的数据类型从uint8转换为浮点数(通常是float32)。
  2. 维度变换:将图像的维度从HWC(高度、宽度、通道数)变换为CHW(通道数、高度、宽度)。这是因为PyTorch模型通常期望输入数据遵循这种维度顺序。
  3. 缩放像素值:将像素值从范围0-255线性缩放到0-1。这是通过将每个像素值除以255来实现的。

Normalize

Normalize转换用于对图像数据进行标准化处理,通常在ToTensor之后使用。它主要执行以下操作:

  1. 减去均值:从图像的每个通道中减去指定的均值。均值通常是根据整个数据集的每个通道的像素值计算得到的。
  2. 除以标准差:将减去均值后的图像数据除以对应通道的标准差。这有助于进一步规范化数据,使其具有单位方差。

标准化公式是: x − mean std \frac{x - \text{mean}}{\text{std}} stdxmean,其中x是原始像素值,mean是像素值的均值,std是标准差。

这两个转换方法的联合使用可以有效地对输入图像进行预处理,使其格式和数值范围适应深度学习模型的需要。这样做不仅有助于模型的训练过程,还可以提高模型的泛化能力。在实际应用中,这些转换通常被组合在一起作为一个预处理管道,可以方便地应用于数据集中的每个图像。

3.示例

通过一段简单的程序介绍cv2.dnn.blobFromImage执行的操作与torchvision中的ToTensor+Normalize效果等同

import cv2
import torch
import torchvision
from torchvision import transforms
import numpy as np
from PIL import Image# 生成一个随机颜色的4x4图像,形状为 (高度, 宽度, 通道数)
dd = np.random.randint(0, 255, (5, 5, 3), dtype=np.uint8)
print(f"原始图像 dd: {dd}")print("===>>> 使用 PyTorch 的 torchvision 进行预处理")# 将 NumPy 数组转换为 PyTorch 张量
tt = torch.tensor(dd)
print(f"转换后的张量 tt: {tt}")# 将 NumPy 数组转换为 PIL 图像
tp = Image.fromarray(dd)# 使用 torchvision 的 Compose 来串联多个转换操作
trans = transforms.Compose([transforms.ToTensor(),  # 将 PIL 图像转换为张量,执行 HWC 到 CHW 的维度变换,并将像素值从 0-255 转换为 0-1transforms.Normalize((.5, .5, .5), (1., 1., 1.))  # 标准化张量,减去均值 (.5, .5, .5) 并除以标准差 (1., 1., 1.)
])# 应用转换操作
trans_tt = trans(tp)
print(trans_tt)
print(f"转换后的张量形状 trans_tt.shape: {trans_tt.shape}")print("===>>> 使用 OpenCV 的 cv2.dnn.blobFromImage 进行预处理")# 使用 OpenCV 的 blobFromImage 函数进行预处理
# 参数说明:
# dd: 输入图像
# 1/255: 缩放比例,将像素值从 0-255 转换为 0-1
# (4, 4): 目标图像尺寸,由于输入图像已经是 4x4,所以这里不执行尺寸变换
# (127.5, 127.5, 127.5): 用于减去的均值
# False, False: 分别表示不交换 R 和 B 通道,不进行裁剪
blob = cv2.dnn.blobFromImage(dd, 1/255, (5, 5), (127.5, 127.5, 127.5), False, False)
print(f"OpenCV blobFromImage 输出的 blob: {blob}")
print(f"blob 的形状 blog.shape: {blob.shape}")

上述代码的输出为:

原始图像 dd: [[[ 24  53  15][  4 172 202][133  72  98][128  19 201][174 141  57]][[ 71 176 174][242 166 134][139 157 153][160 104 222][208  71 191]][[ 21 104 241][173 199 116][222  97  19][ 76 222 237][220  41  78]][[175 254  71][106  44  23][  1 142 205][157 236 211][214 235 128]][[246 104 169][186 112 187][176 181 251][108 232 173][203  25  55]]]
===>>> 使用 PyTorch 的 torchvision 进行预处理
转换后的张量 tt: tensor([[[ 24,  53,  15],[  4, 172, 202],[133,  72,  98],[128,  19, 201],[174, 141,  57]],[[ 71, 176, 174],[242, 166, 134],[139, 157, 153],[160, 104, 222],[208,  71, 191]],[[ 21, 104, 241],[173, 199, 116],[222,  97,  19],[ 76, 222, 237],[220,  41,  78]],[[175, 254,  71],[106,  44,  23],[  1, 142, 205],[157, 236, 211],[214, 235, 128]],[[246, 104, 169],[186, 112, 187],[176, 181, 251],[108, 232, 173],[203,  25,  55]]], dtype=torch.uint8)
tensor([[[-0.4059, -0.4843,  0.0216,  0.0020,  0.1824],[-0.2216,  0.4490,  0.0451,  0.1275,  0.3157],[-0.4176,  0.1784,  0.3706, -0.2020,  0.3627],[ 0.1863, -0.0843, -0.4961,  0.1157,  0.3392],[ 0.4647,  0.2294,  0.1902, -0.0765,  0.2961]],[[-0.2922,  0.1745, -0.2176, -0.4255,  0.0529],[ 0.1902,  0.1510,  0.1157, -0.0922, -0.2216],[-0.0922,  0.2804, -0.1196,  0.3706, -0.3392],[ 0.4961, -0.3275,  0.0569,  0.4255,  0.4216],[-0.0922, -0.0608,  0.2098,  0.4098, -0.4020]],[[-0.4412,  0.2922, -0.1157,  0.2882, -0.2765],[ 0.1824,  0.0255,  0.1000,  0.3706,  0.2490],[ 0.4451, -0.0451, -0.4255,  0.4294, -0.1941],[-0.2216, -0.4098,  0.3039,  0.3275,  0.0020],[ 0.1627,  0.2333,  0.4843,  0.1784, -0.2843]]])
转换后的张量形状 trans_tt.shape: torch.Size([3, 5, 5])
===>>> 使用 OpenCV 的 cv2.dnn.blobFromImage 进行预处理
OpenCV blobFromImage 输出的 blob: [[[[-0.40588236 -0.48431373  0.02156863  0.00196078  0.18235295][-0.22156863  0.4490196   0.04509804  0.12745099  0.3156863 ][-0.41764706  0.17843138  0.37058824 -0.20196079  0.3627451 ][ 0.18627451 -0.08431373 -0.49607843  0.11568628  0.3392157 ][ 0.46470588  0.22941177  0.19019608 -0.07647059  0.29607844]][[-0.29215688  0.17450981 -0.21764706 -0.4254902   0.05294118][ 0.19019608  0.1509804   0.11568628 -0.09215686 -0.22156863][-0.09215686  0.28039217 -0.11960784  0.37058824 -0.3392157 ][ 0.49607843 -0.327451    0.05686275  0.4254902   0.42156863][-0.09215686 -0.06078431  0.20980392  0.40980393 -0.4019608 ]][[-0.44117647  0.29215688 -0.11568628  0.2882353  -0.2764706 ][ 0.18235295  0.0254902   0.1         0.37058824  0.24901961][ 0.44509804 -0.04509804 -0.4254902   0.42941177 -0.19411765][-0.22156863 -0.40980393  0.30392158  0.327451    0.00196078][ 0.1627451   0.23333333  0.48431373  0.17843138 -0.28431374]]]]
blob 的形状 blog.shape: (1, 3, 5, 5)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/11177.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

架构设计之学新而知故

缘由 因为一些特殊的机缘,接触到洋葱架构等一些新架构设计概念。 尝试理解了一段时间,就想简单梳理下对它们的理解,以达到学新而知故 😃 信息增益 以前计算机专业并不设置通信领域的信息论的专业课程,但是&#xf…

输出指定日期区间内的所有天、周、月

hutool获取指定时间周几 Slf4j public class DateWeekUtil {public static List<String> getDateWeek(String startDateString, String endDateString, List<Integer> codeList) {List<String> dateInfoList new ArrayList<>();List<Integer> v…

工作随机:linux 挂载LVM管理模式的磁盘

文章目录 前言一、创建一个分区二、创建PV三、创建VG四、创建LV五、格式化并挂载目录 前言 在数据库管理中&#xff0c;常有比较头疼的问题&#xff0c;就是一段时间发展后我的磁盘空间不够了&#xff0c;想要扩容原有的目录很是头疼&#xff0c;那么LVM管理的优势就体现出来了…

JAVA学习-练习试用Java实现改写字符串

问题&#xff1a; 键盘录入一个字符串&#xff0c;将字符串中的大写改成小写&#xff0c;小写改成大写&#xff0c;数字改成。例如heLLO123,输出后为HEllo** 解答思路&#xff1a; import java.util.Scanner;public class StringConversion {public static void main(String…

单元测试之JUnit5知识点总结及代码示例

单元测试是软件开发过程中的一种验证手段&#xff0c;它针对最小的可测试部分&#xff08;通常是函数或方法&#xff09;进行检查和验证。其实单元测试还是挺重要的&#xff0c;不过国内很多公司的项目其实并没有做好单元测试&#xff0c;或者根本就没做单元测试&#xff0c;原…

英语复习之英语形近词总结(四)

英语形近词总结复习第四部分&#xff1a; 单词 释义例句 genuine 英 /ˈdʒenjuɪn/ 美 /ˈdʒenjuɪn/ adj.真实的&#xff0c;真正的&#xff1b;诚恳的 1.Only genuine refugees can apply for asylum. 只有真正的难民才能申请政治避难。 《牛津词典》 2.This isnt a genui…

C++笔试强训day19

目录 1.小易的升级之路 2.礼物的最大价值 3.对称之美 1.小易的升级之路 链接 模拟就行&#xff0c;唯一可能是难点得就是gcd&#xff08;最大公约数&#xff09; #include <iostream> using namespace std; #define int long long const int N 1e5 10; int arr[N];…

儿童悬吊训练系统如何进行制动肌的动力训练

儿童悬吊训练系统进行制动肌的动力训练&#xff0c;可以按照以下步骤进行&#xff1a; 评估&#xff1a;首先&#xff0c;治疗师需要对儿童的制动肌进行评估&#xff0c;确定其稳定性和力量水平&#xff0c;从而制定合适的训练计划。 选择训练方式&#xff1a;根据评估结果&am…

利用IP地址查询解决被“薅羊毛”的方法

在互联网时代&#xff0c;随着各种网络诈骗手段的不断更新和演变&#xff0c;“薅羊毛”成为了一种常见的网络犯罪行为。其中&#xff0c;利用查询IP地址进行欺诈活动已经成为一种普遍的手段。当个人或组织的IP地址被不法分子查询后&#xff0c;可能会面临虚假注册、盗取个人信…

Python中的绝对路径与相对路径详解

对路径与相对路径 Python中的绝对路径与相对路径详解什么是路径&#xff1f;绝对路径优点&#xff1a;缺点&#xff1a;示例&#xff1a; 相对路径优点&#xff1a;缺点&#xff1a;示例&#xff1a; Python中如何使用**重点内容**&#xff1a;**在Python中&#xff0c;建议使用…

AVL Cruise与Simulink联合仿真(通过MATLAB DLL方式)

最近毕业设计需要用到AVL Cruise与Simulink进行联合仿真&#xff0c;分析汽车模型的经济性。下面介绍一下我所知的AVL Cruise与Simulink联合仿真的几种方式&#xff0c;它们各自的优缺点&#xff0c;以及DLL方式联合仿真的具体配置过程。我这里用的MATLAB软件版本是2021a&#…

有边数限制的最短路

文章目录 题目 有边数限制的最短路算法分析1、问题&#xff1a;为什么Dijkstra不能使用在含负权的图中&#xff1f;dijkstra详细步骤2、什么是bellman - ford算法&#xff1f;3、bellman - ford算法的具体步骤4、在下面代码中&#xff0c;是否能到达n号点的判断中需要进行if(di…

水准网间接平差

目录 一、原理概述二、案例分析三、代码实现 一、原理概述 间接平差的函数模型和随机模型为&#xff1a; L ^ B X ^ d D σ 0 2 Q σ 0 2 P − 1 \hat{L}B\hat{X}d\\ D\sigma_0^2Q\sigma_0^2P^{-1} L^BX^dDσ02​Qσ02​P−1 误差方程为&#xff1a; V B x ^ − l VB\ha…

信息系统项目管理师0104:详细可行性研究(7项目立项管理—7.2项目可行性研究—7.2.3详细可行性研究)

点击查看专栏目录 文章目录 7.2.3详细可行性研究1.详细可行性研究的依据2.详细可行性研究的原则3.详细可行性研究的方法4.详细可行性研究的内容5.详细可行性研究报告记忆要点总结7.2.3详细可行性研究 详细可行性研究是在项目决策前对与项目有关的技术、经济、

智慧公厕:打造智能、安全、舒适的公共厕所新时代

随着智慧城市建设的不断推进&#xff0c;公共设施的智能化也已成为一种必然趋势。在这一背景下&#xff0c;智慧公厕作为城市管理的一个重要方面&#xff0c;正逐渐走进人们的视野。通过对所在辖区内所有公共厕所的全域感知、全网协同、全业务融合以及全场景智慧的赋能&#xf…

如何训练一个大模型:LoRA篇

目录 写在前面 一、LoRA算法原理 1.设计思想 2.具体实现 二、peft库 三、完整的训练代码 四、总结 写在前面 现在有很多开源的大模型&#xff0c;他们一般都是通用的&#xff0c;这就意味着这些开源大模型在特定任务上可能力不从心。为了适应我们的下游任务&#xff0c;…

使用Python构建一个简单的图书管理系统

Python是一种强大而灵活的编程语言&#xff0c;它可以用于构建各种类型的应用程序&#xff0c;包括图书管理系统。在这篇文章中&#xff0c;我们将学习如何使用Python和一些常见的库来创建一个简单的图书管理系统。 1. 设计数据库模型 首先&#xff0c;我们需要设计数据库模型…

【退役之重学 Java】初步认识 AQS

一、AQS 是什么 Abstract Queued Synchronizer &#xff0c;翻译过来就是“抽象的排好队的同步器”。 AQS 是一个用来构建锁和同步器的框架。是用来构建锁或者其他同步器组件的重量级基础框架及整个JUC体系的基石&#xff0c;通过内置的FIFO队列来完成线程获取资源的排队工作&…

centos7时间同步教程

针对问题&#xff1a;在我们使用虚拟机配置好centos7后&#xff0c;发现服务器时间和当前时间对不上 通过命令查看时间不同步 date 或者 date -R修改/etc/sysconfig/clock文件如下内容&#xff0c;保存 vi /etc/sysconfig/clockZONE“Asia/Shanghai” UTCtrue ARCfalse重写/e…

251 基于matlab的动态粒子群算法

基于matlab的动态粒子群算法。普通粒子群算法无法感知外界环境的变化&#xff0c;在外界环境发生改变时无法实时进行响应&#xff0c;因而缺乏动态环境寻优能力。在普通粒子群算法基本上通过增加敏感粒子得到一种动态粒子群算法&#xff0c;该算法通过实时计算敏感粒子的适应度…