cv2, pil.image, plt.image 读图的差异
人是习惯性动物,当我们第一次用opencv时,肯定会觉得opencv的imread()方式很奇怪,做图像出来天天说图像是RGB图RGB图,可opencv读出来的图,却是BGR的顺序。是不是很奇怪,还不止这一点,opencv读进来的图,你在使用shape函数时,返回的是h,w,c,也就是height是第一个维度,然后是宽度,最后是通道数,就是彩色图是RGB三通道。但是我们在使用的时候,第一个维度又是width的,第二个维度是height。然后利用opencv进行保存和show的时候,也一定要保证是BGR通道的顺序,否则保存和显示出来的图是不对的。
可以跑一下以下代码试试。
import cv2
cv2_img=cv2.imread('./demo.jpg')
print(type(cv2_img) )
print(cv2_img.shape)
# h,w,c
print(cv2_img[0,0,:])
# print左上角位置的像素值,一定要看清楚三个通道的值
cv2.imwrite('./test_cv2.jpg', cv2_img)
cv2_img_ch = cv2_img[:, :, ::-1] # 更改为RGB通道
print(cv2_img_ch[0,0,:])
cv2.imwrite('./test_cv2_ch.jpg', cv2_img_ch)
# 看一下保存的图像是不是和原图一样?
正是因为这些原因,深度学习的处理图像时会存在是使用BGR还是使用RGB的图这个问题。还有一个另外的原因,那就是早起的深度学习平台caffe是基于opencv来读图的,读图顺序是BGR。
当然有人不喜欢opencv这种读图模式,那就换一种方式,比如最近发现在AGI领域,大家更倾向于用PIL库,用这个库来读图,更符合大家平常习惯的RGB模式,但是这个库也有问题,你如果想像opencv读进来的图像那样用,还要借助numpy进行转一下,因为本身这个函数读进来的并不是一个图向量,可以理解为一个索引。
from PIL import Image
import numpy as np
pil_img=Image.open('./demo.jpg').convert('RGB')
#关于此处convert('RGB')的使用, 如果不使用.convert('RGB')进行转换,读出来的图像是RGBA四通道的,A通道为透明,通过convert('RGB')转成只有RGB三通道的数据。可以不加convert('RGB')打印出来看看。
print(type(pil_img) )
print(pil_img.size)
# w,h 没有c
print(np.array(pil_img).shape)
# h,w,c 但是c是RGB通道的,这里通过np.array转成可以读写的数据结构,原来读进来的是无法直接print打开的
print(pil_img[0,0,:])
# print左上角位置的像素值,一定要看清楚三个通道的值
#保存图
pil_img.save('./pil_img.jpg')
目前在diffusers的库中,有个load_image,也就是基于PIL.Image来实现的。
Parameters:
a array_like
Input array.
axes tuple or list of ints, optional
If specified, it must be a tuple or list which contains a permutation of [0, 1, …, N-1] where N is the number of axes of a. Negative indices can also be used to specify axes. The i-th axis of the returned array will correspond to the axis numbered axes[i]
of the input. If not specified, defaults to range(a.ndim)[::-1]
, which reverses the order of the axes.
但是我们在做深度学习,通常是基于torch工作时,常常会碰到transpose和permute()这两个函数,这两个和numpy中的tranpose用途是基本一致的。但是torch.transpose只能对两个维度进行交换,而permute可以对多个维度进行交换。比如上面的实验,我们可以这么做。
import cv2
import torch
cv2_img=cv2.imread('./demo.jpg')
print(type(cv2_img) )
print(cv2_img.shape)
# h,w,c
print(cv2_img[0,0,:])
# print左上角位置的像素值,一定要看清楚三个通道的值
cv2.imwrite('./test.jpg', cv2_img)
cv2_img_ch = cv2_img[:, :, ::-1] # 更改为RGB通道
print(cv2_img_ch[0,0,:])
cv2.imwrite('./test_ch.jpg', cv2_img_ch)
# 看一下保存的图像是不是和原图一样?
t_cv2_img=cv2_img.transpose(2,0,1)
print(cv2_img.shape)
# c,h,w
tt_cv2_img=torch.from_numpy(cv2_img).permute(2,0,1)
print(tt_cv2_img.shape)
# c,h,w
tt_cv2_img=torch.from_numpy(cv2_img).transpose(2,0,1)
# 此处会提示出错,torch的transpose只能交换两个维度
也就是说,如果是numpy的维度交换,可以随意用transpose()实现。但是如果你操作的对象是torch.tensor这种数据结构,尽量用permute()函数,用法其实和numpy的transpose()基本上完全一样。
cv2, pil.image, plt.image 读图的差异的更多相关文章
- pickel加速caffe读图
64*64*3小图(12KB),batchSize=128,训练样本100万, 全部load进来内存受不了,load一次需要大半天 训练时读入一个batch,ali云服务器上每个batch读入时间1. ...
- matlab读图函数
最基本的读图函数:imread imread函数的语法并不难,I=imread('D:\fyc-00_1-005.png');其中括号内写图片所在的完整路径(注意路径要用单引号括起来).I代表这个图片 ...
- LM_ReadImgMode.js PC单页轮播读图模式组件,零依赖!
LM_ReadImgMode.js PC单页轮播读图模式组件,零依赖! github:http://dtdxrk.github.io/LM-ReadImgMode/ TXT 1.全新的2.0版本,脱离 ...
- 扩增子图表解读5火山图:差异OTU的数量及变化规律
火山图 Volcano plot 在统计学上,火山图是一种类型的散点图,被用于在大数据中快速鉴定变化.由于它的形成像火山喷发的样子,所以被称为火山图.和上文讲的曼哈顿图类似. 火山图基本元素 火山 ...
- 机器学习进阶-图像基本处理-视频的读取与处理 1.cv2.VideoCapture(视频的载入) 2.vc.isOpened(载入的视频是否可以打开) 3.vc.read(视频中一张图片的读取) 4.cv2.cvtColor(将图片转换为灰度图)
1.vc = cv2.VideoCapture('test.mp4') #进行视频的载入 2.vc.isOpened() # 判断载入的视频是否可以打开 3.ret, frame = vc.read( ...
- 【Python开发】python PIL读取图像转换为灰度图及另存为其它格式(也可批量改格式)
例如有一幅图,文件名为"a.jpg'. 读取: from PIL import Image #或直接import Image im = Image.open('a.jpg') 将图片转换成 ...
- cv2 & PIL(pillow)显示图像
= OpenCV和PIL中显示图像方式不一样,且支持的格式也不同 = cv在显示图像时是自定义的显示窗口,而PIL中显示是调用操作系统中的默认打开程序 如: import cv2 im = cv2.i ...
- plt.figure()的使用,plt.plot(),plt.subplot(),plt.subplots()和图中图
参考:https://blog.csdn.net/m0_37362454/article/details/81511427 matplotlib官方文档:https://matplotlib.org/ ...
- 4.3Python数据处理篇之Matplotlib系列(三)---plt.plot()折线图
目录 前言 (一)plt.plot()函数的本质 ==1.说明== ==2.源代码== ==3.展示效果== (二)plt.plot()函数缺省x时 ==1.说明== ==2.源代码== ==3.展示 ...
- PIL 一秒切九图 朋友圈发图神器
注意图片像素返回值是(宽度,高度),pil填像素点坐标原点左上角. 判断像素点是否在圆方程中. import numpy as np from PIL import Image file = inpu ...
随机推荐
- 为什么我觉得需要熟悉vim使用,难道仅仅是为了耍酷?
实例说话: 使用vscode保存,有报提示信息,可以以超级用户身份重试,于是我授权root给vscode软件,却还提示失败! 而实际上,我使用cat命令发现已经写入成功了 终端内使用cat这条shel ...
- `std::future`--异步的优势
std::future 相比于直接使用线程在 C++ 中有几个重要的优势,主要体现在同步结果获取.简化代码管理.以及更安全的异步任务管理等方面.以下是 std::future 的一些主要优势: 1. ...
- Python:条件分支 if 语句全讲解
Python:条件分支 if 语句全讲解 如果我拿出下面的代码,阁下该做何应对? if not reset_excuted and (terminated or truncated): ... els ...
- C#查漏补缺----值类型与引用类型,值类型一定分配在栈上吗?
前言 环境:.NET 8.0 系统:Windows11 参考资料:<CLR via C#>, <.Net Core底层入门>,<.NET 内存管理宝典> 栈空间与堆 ...
- C#使用 MailKit 收发邮件
目录 获取QQ邮箱授权码 安装 MailKit 配置邮件服务器信息 实现邮件收发方法 测试邮件收发 参考文章 获取QQ邮箱授权码 打开QQ邮箱,进入 设置->账号 页面: 在 POP3/IMAP ...
- 没想到,Python 还可以制作 Web 可视化页面!
一谈到Web页面,可能大家首先想到就是HTML,CSS或JavaScript. 本次小F就给大家介绍一下如何用Python制作一个数据可视化网页,使用到的是Streamlit库. 轻松的将一个Exce ...
- 狂神说-Docker基础-学习笔记-07 容器数据卷
狂神说-Docker基础-学习笔记-07 容器数据卷 视频地址:https://www.bilibili.com/video/BV1og4y1q7M4?p=21 什么是容器数据卷 运行时数据都在容器中 ...
- JS Parser Combinator (解析器组合子)
前言 前些天偶然看到以前写的一份代码,注意有一段尘封的代码,被我遗忘了.这段代码是一个简单的解析器,当时是为了解析日志而做的.最初解析日志时,我只是简单的正则加上分割,写着写着,我想,能不能用一个简单 ...
- leetcode 740 删除并获得点数
740 删除并获得点数 题意 给你一个整数数组 nums ,你可以对它进行一些操作. 每次操作中,选择任意一个 nums[i] ,删除它并获得 nums[i] 的点数.之后,你必须删除 所有 等于 n ...
- java通过SSE实现消息推送
一.什么是SSE 严格地说,HTTP 协议无法做到服务器主动推送信息.但是,有一种变通方法,就是服务器向客户端声明,接下来要发送的是流信息(streaming). 也就是说,发送的不是一次性的数据包, ...