opencv,numpy,tensor格式转换

这篇具有很好参考价值的文章主要介绍了opencv,numpy,tensor格式转换。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

深度学习中,涉及的图片格式有诸多转换方式,写此篇用于区别记录。

目前接触到的读取图片的方式主要是两种,一是使用opencv的cv2模块,二是PIL.Image模块,两者的使用有不同。

一、cv2的读取方式,格式转换

最先一个问题是读取格式。

1. cv2读取的图片格式直接是numpy的ndarry格式,图片是形状为HxWxC的BGR图片。

jm = cv2.imread(path)  # cv读取的是BGR格式图片
print(type(jm))
print(jm.shape)
# 输出
<class 'numpy.ndarray'>
(240, 300, 3)

直接打印是BGR格式

plt.imshow(jm)
plt.show()

numpy转cv2,opencv,numpy,python
经过格式转换之后得到正常的RGB格式图片

jm = cv2.cvtColor(jm, cv2.COLOR_BGR2RGB)

numpy转cv2,opencv,numpy,python

2. 在pytorch中,输入网络时将图片转化为tensor格式,并对数据做归一化处理,数值缩放到0-1之间。如:

jm = cv2.imread(path)  # cv读取的是BGR格式图片
# jm = cv2.cvtColor(jm, cv2.COLOR_BGR2RGB)
img_tensor = torchvision.transforms.ToTensor()(jm)  # 转换成tensor格式
print(img_tensor)
print(type(img_tensor))
print(img_tensor.shape)
# 输出
tensor([[[0.1647, 0.1608, 0.1608,  ..., 0.2431, 0.2431, 0.2431],
         [0.1647, 0.1608, 0.1608,  ..., 0.2431, 0.2431, 0.2431],
         [0.1647, 0.1608, 0.1647,  ..., 0.2431, 0.2431, 0.2431],
         ...,
         [0.2902, 0.2902, 0.2902,  ..., 0.1412, 0.1451, 0.1490],
         [0.2863, 0.2863, 0.2863,  ..., 0.1412, 0.1451, 0.1490],
         [0.2863, 0.2863, 0.2863,  ..., 0.1412, 0.1451, 0.1490]],

        [[0.1216, 0.1176, 0.1176,  ..., 0.2784, 0.2784, 0.2784],
         [0.1216, 0.1176, 0.1176,  ..., 0.2784, 0.2784, 0.2784],
         [0.1216, 0.1176, 0.1216,  ..., 0.2784, 0.2784, 0.2784],
         ...,
         [0.2745, 0.2745, 0.2745,  ..., 0.1176, 0.1216, 0.1255],
         [0.2706, 0.2706, 0.2706,  ..., 0.1176, 0.1176, 0.1216],
         [0.2706, 0.2706, 0.2706,  ..., 0.1176, 0.1176, 0.1216]],

        [[0.3412, 0.3373, 0.3373,  ..., 0.3843, 0.3843, 0.3843],
         [0.3412, 0.3373, 0.3373,  ..., 0.3843, 0.3843, 0.3843],
         [0.3412, 0.3373, 0.3412,  ..., 0.3843, 0.3843, 0.3843],
         ...,
         [0.2706, 0.2706, 0.2706,  ..., 0.1843, 0.1961, 0.2000],
         [0.2667, 0.2667, 0.2667,  ..., 0.1922, 0.2000, 0.2039],
         [0.2667, 0.2667, 0.2667,  ..., 0.1922, 0.2000, 0.2039]]])
<class 'torch.Tensor'>
torch.Size([3, 240, 300])

3. tensor类型的数据转换到图片的类型
假设数据未经过normalization处理到[-1,1],还是在0-1之间。
步骤:

# 1. 首先tensor转化到numpy形式
img_np = img_tensor.numpy()
print(img_np)
print(type(img_np))
print(img_np.shape)
# 输出
[[[0.16470589 0.16078432 0.16078432 ... 0.24313726 0.24313726 0.24313726]
  [0.16470589 0.16078432 0.16078432 ... 0.24313726 0.24313726 0.24313726]
  [0.16470589 0.16078432 0.16470589 ... 0.24313726 0.24313726 0.24313726]
  ...
  [0.2901961  0.2901961  0.2901961  ... 0.14117648 0.14509805 0.14901961]
  [0.28627452 0.28627452 0.28627452 ... 0.14117648 0.14509805 0.14901961]
  [0.28627452 0.28627452 0.28627452 ... 0.14117648 0.14509805 0.14901961]]

 [[0.12156863 0.11764706 0.11764706 ... 0.2784314  0.2784314  0.2784314 ]
  [0.12156863 0.11764706 0.11764706 ... 0.2784314  0.2784314  0.2784314 ]
  [0.12156863 0.11764706 0.12156863 ... 0.2784314  0.2784314  0.2784314 ]
  ...
  [0.27450982 0.27450982 0.27450982 ... 0.11764706 0.12156863 0.1254902 ]
  [0.27058825 0.27058825 0.27058825 ... 0.11764706 0.11764706 0.12156863]
  [0.27058825 0.27058825 0.27058825 ... 0.11764706 0.11764706 0.12156863]]

 [[0.34117648 0.3372549  0.3372549  ... 0.38431373 0.38431373 0.38431373]
  [0.34117648 0.3372549  0.3372549  ... 0.38431373 0.38431373 0.38431373]
  [0.34117648 0.3372549  0.34117648 ... 0.38431373 0.38431373 0.38431373]
  ...
  [0.27058825 0.27058825 0.27058825 ... 0.18431373 0.19607843 0.2       ]
  [0.26666668 0.26666668 0.26666668 ... 0.19215687 0.2        0.20392157]
  [0.26666668 0.26666668 0.26666668 ... 0.19215687 0.2        0.20392157]]]
<class 'numpy.ndarray'>
(3, 240, 300)

# 2. 改变矩阵形状,因为cv2的图片格式是HxWxC,使用转置transpose
img_np = img_np.transpose(1, 2, 0)  # 形状变为HxWxC
(240, 300, 3)

# 3. 改变数值,矩阵乘以255
img_np = img_np * 255
[[[42. 31. 87.]
  [41. 30. 86.]
  [41. 30. 86.]
  ...
  [62. 71. 98.]
  [62. 71. 98.]
  [62. 71. 98.]]
  .......
  .......
# 4.  图片格式是uint8,无符号8位整型,使用numpy的astype方法
img = img_np.astype(np.uint8)
print(img)
[[[42 31 87]
  [41 30 86]
  [41 30 86]
  ...
  [62 71 98]
  [62 71 98]
  [62 71 98]]
  ......
plt.imshow(img)
plt.show()

numpy转cv2,opencv,numpy,python
:这里是BGR格式,如果图片在tensor化之前经过BGR到RGB的处理,那么这里是输出RGB正常图。

二、Image的读取方式,格式转换

用PIL.Image的open方法得到的是一个特定图片类型的PIL对象,需要用numpy的array方法或者asarray方法转化成numpy的ndarray形式,不同于cv2,Image读取的图片是RGB的。

img = Image.open(path)
print(img)
# 输出
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=300x240 at 0x18943488>

这里可以用convert转化成RGB格式。其他博客说不加convert就会得到一个四通道的图,包含一个透明通道,但是上面没有显示。

img = Image.open(path).convert('RGB')
print(img)
# 输出
<PIL.Image.Image image mode=RGB size=300x240 at 0x1899CE88>
# 还是加一个convert('RGB')吧,看着专业一点

这里拓展一个array和asarray方法的区别。
array方法和asarray方法的区别为是否在内存中创建新的副本。
当数据源是非ndarray类型时,两者没有区别,都是创建新的副本。而当数据源是ndarray时,前者array创建副本,asarray直接在原内存修改。

a = [[1, 2], [3, 4]]  # 数据源不是ndarray
b = np.array(a)
c = np.asarray(a)
a[1] = 0
print(a)
print(b)
print(c)
print(id(a), id(b), id(c), sep='\n')
# 输出
[[1, 2], 0]
[[1 2]
 [3 4]]
[[1 2]
 [3 4]]
385734024
395981328
355290640

上面代码里,当数据源不是ndarray格式,np.array和np.asarray都创建副本,原数据改变不影响新建对象。

a = np.array([[1, 2], [3, 4]])  # 数据源先转换成ndarray形式
b = np.array(a)
c = np.asarray(a)
a[1] = 0
print(a)
print(b)
print(c)
print(id(a), id(b), id(c), sep='\n')
# 输出
[[1 2]
 [0 0]]
[[1 2]
 [3 4]]
[[1 2]
 [0 0]]
414413712
397155760
414413712

可以看出,上面代码,当输入数据格式是ndarray,asarray方法会使用原数据内存,array是创建副本。
剩余的步骤和cv2一致了。

# 到了下面这一步,可以使用Image.fromarray方法返回一个Image图片对象。
img = img_np.astype(np.uint8)  # img是uint8的ndarray
img = Image.fromarray(img)  
print(img)
#  输出
<PIL.Image.Image image mode=RGB size=300x240 at 0x180CF448>

cv2和Image保存图片也不一样

  • cv2保存方式:
img = img_np.astype(np.uint8)
cv2.imwrite('路径', img)

cv2保存的是uint8格式的ndarray数组。

  • PIL.Image保存方式
img = Image.fromarray(img)  # 转成PIL对象
img.save('路径')

PIL.Image保存的是PIL图片对象。

三、概括

cv2:
cv2读取和保存都是ndarray数组,形状为HxWxC。
cv2读取的图片通道顺序是BGR,如果要使用正常的图片,先使用通道转换方法转化成RGB通道。
保存时数据形式是uint8的ndarray数组。
变成tensor数据后,形状变为CxHxW,数值0-1之间。
PIL.Image:
Image读取和保存都是PIL图片对象,形状为HxWxC,使用前先用np.array或者np.asarray方法转换成ndarray数组类型。
通道顺序是RGB,和cv2不同。
保存时保存PIL对象,所以使用Image.fromarray方法将uint8格式转成PIL图片对象,使用img.save()保存。文章来源地址https://www.toymoban.com/news/detail-599431.html

到了这里,关于opencv,numpy,tensor格式转换的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • NumPy图像格式相互转换:使用OpenCV

    在图像处理和计算机视觉领域,NumPy和OpenCV是两个非常常用的Python库。NumPy提供了强大的多维数组操作功能,而OpenCV则提供了图像处理和计算机视觉算法的实现。在许多情况下,我们需要在这两个库之间进行图像格式的相互转换。本文将介绍如何使用OpenCV在NumPy数组和OpenCV图像

    2024年02月03日
    浏览(38)
  • opencv-python库 cv2 图形绘制 cv2.line()cv2.rectangle()cv2.circle()cv2.ellipse()cv2.polylines()cv2.putText

    cv2.line() 是 OpenCV 中的一个函数,用于在图像上绘制直线。这个函数需要指定图像、线的起点和终点坐标、线的颜色、线的宽度以及线的类型。 下面是 cv2.line() 函数的详细参数说明: 参数解释: 下面是一个使用 cv2.line() 绘制直线的简单示例: 在这个例子中,我们创建了一个

    2024年04月23日
    浏览(51)
  • python使用cv2库、下载opencv库

    cv2库在opencv库内,因此需要下载opencv-python和opencv-contrib-python 1、打开windows命令行: win+R cmd 2、更新pip版本(不一定要): python -m pip install --upgrade pip 3、使用pip下载opencv: 下载opencv库前最好要下载numpy库。 这里使用中科大的镜像源:https://pypi.mirrors.ustc.edu.cn/simple/ pip install

    2024年02月01日
    浏览(44)
  • 解决python3安装完OpenCV后没有cv2.imshow、cv2.imread等函数的问题

    发现cv2中没有函数可用,此时打开cv2所在的文件夹, 找到 cv2.pyd 文件,复制到所用python环境中的site-packages文件夹中 关闭项目工程文件重新打开,就可以调用cv2中的函数了。

    2024年02月03日
    浏览(83)
  • Python cv2 opencv-python opencv-contrib-python 安装

    老规矩,话不多说,上代码! pip install opencv-python(如果只用主模块,则使用这个命令安装【推荐】) pip install opencv-contrib-python(如果需要用到 contrib 模块,则使用这个命令【本次因自己没有使用 contrib 模块,所以没有尝试】) 首先,讲一下 cv2 这个模块是 opencv 的,所以安

    2024年02月11日
    浏览(49)
  • Python OpenCV 图像缩放:使用 cv2.resize() 方法

    图像缩放是计算机视觉和图像处理中常用的操作之一。OpenCV 是一个强大的计算机视觉库,提供了许多图像处理功能。在 Python 中使用 OpenCV 进行图像缩放非常简单,可以使用 cv2.resize() 方法来实现。 cv2.resize() 方法可以根据指定的尺寸调整图像的大小。它可以缩小图像,也可以

    2024年02月02日
    浏览(63)
  • opencv-python[cv2]读取中文路径图像

    随着AI人工智能的不断发展,图像处理这门技术也越来越重要,很多学校本科都开启了图像处理这门课程,学习图像处理开发,自然就绕不开opencv-python[ cv2 ]这个由intel主导的开源库。 cv2 是指OpenCV的Python接口库。 OpenCV (Open Source Computer Vision Library)是一个开源的计算机视觉库

    2024年02月06日
    浏览(74)
  • Python-OpenCv中的cv2.VideoCapture()类

    cv2.VideoCapture()具有两个功能,一是可以完成摄像头的初始化,打开摄像头;二是可以完成视频文件的初始化。 参数说明:         capture :要打开的摄像头         index :摄像头的设备索引,对于笔记本电脑来说,为0时,一般打开的是电脑的内置摄像头,为1时,打开的为外

    2024年01月25日
    浏览(39)
  • 【Python】进阶学习:OpenCV--一文详解cv2.namedWindow()

    【Python】进阶学习:OpenCV–一文详解cv2.namedWindow() 🌈 个人主页:高斯小哥 🔥 高质量专栏:Matplotlib之旅:零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程👈 希望得到您的订阅和支持~ 💡 创作高质量博文(平均质量分92+),分享更多关于深度学习、

    2024年03月20日
    浏览(130)
  • 使用opencv-python(cv2)库进行相机标定

    2023年09月11日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包