首页 > 其他分享 >cv2, pil.image, plt.image 读图的差异

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

时间:2024-12-15 12:58:21浏览次数:5  
标签:plt img image cv2 读图 jpg RGB ch print

人是习惯性动物,当我们第一次用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()基本上完全一样。

 

 

 

 

 

 

 

 

 

标签:plt,img,image,cv2,读图,jpg,RGB,ch,print
From: https://www.cnblogs.com/jianyingzhou/p/18607863

相关文章

  • image
    ......
  • Vue3+ElementPlus 中 el-image 预览大图属性 previewSrcList 和 translateY(-5px) 的
    【前言】Vue3使用ElementPlus,Vue2使用Element-ui。【问题描述】在Vue3+ElementPlus中,使用el-image和预览大图功能,点击el-image后预览的图片局限在原有图片(小图)内,遮罩也没有充满屏幕。【注】使用  transform:translateY(-5px); 的原因是本来外面有一层div,想用hover ......
  • QT: QImage::bits()访问图像出现数据错位
    问题:    在解析bmp图片时,使用QImage::bits()拿到第一个像素点的数据,依次访问像素点数据时,发现图像数据错位现象。原因:    经查询应该为QImage读取bmp图像时,每行的像素点所占内存需为4字节的倍数,所以按照图像的长和宽以及深度,按字节依次读取会出现错位现象。......
  • 微信小程序中使用echarts 自定义图片时报错: Image is not defined
    最近需要在小程序中完成一个图表,其中需要导入一些自定义的图片来显示。使用echarts-for-weixin项目之后,发现报了如下错误:ReferenceError:Imageisnotdefined经查看源码发现,Echarts.Js文件中是使用NewImage来创建图片的,而小程序中应该使用Canvas.Createimage()因此需要修......
  • halcon gamma_image算子详解
    算子用于对图像进行伽马校正,这是一种非线性变换,常用于调整图像的亮度和对比度,尤其是在处理传感器数据时,因为它们可能会有非线性的响应特性。gamma_image(Image,GammaImage,0.416667,0.055,0.0031308,255,'true')参数详解gamma:=0.416667//通常0.8<=Gamma<=2.2,这里......
  • Windows Image Acquisition (WIA) 服务是 Windows 操作系统中的一个关键服务,主要用于
    WindowsImageAcquisition(WIA)服务是Windows操作系统中的一个关键服务,主要用于扫描仪、数码相机等设备的图像采集和管理。它为这些设备提供必要的软件接口,使得用户可以通过标准应用程序(如Windows照片查看器、扫描仪应用等)来获取图像数据。1. WIA服务概述服务名称: St......
  • uni-app在image上绘制点位并回显
    在Uni-app中绘制多边形可以通过使用CanvasAPI来实现。Uni-app是一个使用Vue.js开发所有前端应用的框架,同时支持编译为H5、小程序等多个平台。由于Canvas是H5和小程序中都支持的API,所以通过Canvas绘制多边形是一个比较通用的方法。1.创建一个新的Uni-app项......
  • github代码修改指南|乳腺超声肿块分割代码项目|Global Guidance Network for Breast L
    目录此项目相关信息显而易见的错误文件缺失很容易失误的地方此项目相关信息github链接:https://github.com/xorangecheng/GlobalGuidance-Net论文链接(2021MIA论文):https://www.sciencedirect.com/science/article/pii/S1361841521000359github提供的代码质量真的感人,我改了一下......
  • 当css中background或background-image的值为url()或url(#)时,会发生什么情况?为什么?如何
    当CSS中background或background-image的值为url()或url(#)时,会尝试加载指定的资源或引用。具体情况和解决方法如下:1.url(path/to/image.jpg)或url("path/to/image.jpg"):情况:浏览器会尝试加载指定路径的图片资源。如果路径正确且图片存在,则图片会作为背景显示。......
  • PNG Images Compression method
    Version1.00Assignment–PNGImagesVersion1.00SubmissionGuidelinesDeadline:9:00AMonFriday13DecemberSubmissionprocedure:Submitonlyonefilelabelledpng.pythroughblackboard(viaTurnItIn)Versionrequirement:YourcodemustrunusingPython......