gpt4 book ai didi

cv2,pil.image,plt.image读图的差异

转载 作者:撒哈拉 更新时间:2024-12-15 14:49:42 57 4
gpt4 key购买 nike

人是习惯性动物,当我们第一次用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来实现的.

  。

另外还有一个做可视化时,大家常常用到的matplotlib.pyplot,这个库也可以读图 。

import matplotlib.pyplot as plt 。

import numpy as np 。

plt_img=plt.imread('./demo.jpg') 。

print(type(plt_img) ) 。

print(plt_img.shape) # h,w,c c上是RGB通道 。

print(plt_img[0,0,:]) # print左上角位置的像素值,一定要看清楚三个通道的值 。

#保存图 。

plt.imsave('./plt_img.jpg', plt_img) 。

  。

但是通常深度学习模型,进模型时,通常是b,c,h,w这样的顺序,因此,以上几种方式都需要在维度上对数据进行转换。转换的时候,可以使用transpose(),也可以使用permute(),这两个函数的具体使用方式这里也简单介绍一下.

其中,transpose这个函数,在numpy中,是可以进行超过2个维度的转置的。比如我们对opencv的图进行转置.

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.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 。

  。

此时最后一行打印出来是c,h,w这样的顺序。numpy的transpose很强大,根据官方的介绍,参数传递时,可以这样的,也就是可以对各个维度进行交换.

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()基本上完全一样.

  。

PS.题外话:

1. 无论用哪种方式来读图,请确保训练和测试是一定要保持一致.

2. 三种方式在对同一张图读取时,读进来的像素值可能会有差异的。保存时更不用说了,肯定不一样,因为不同的方法保存时,压缩比例不保证一致,所以保存下来的图再读肯定不一样.

3. 无论哪种方式,通常都会归一化,这个地方一定要确保是一致的.

  。

最后此篇关于cv2,pil.image,plt.image读图的差异的文章就讲到这里了,如果你想了解更多关于cv2,pil.image,plt.image读图的差异的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

57 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com