Python各类图像库的图片读写方式总结(推荐)


Posted in Python onFebruary 23, 2018

最近在研究深度学习视觉相关的东西,经常需要写python代码搭建深度学习模型。比如写CNN模型相关代码时,我们需要借助python图像库来读取图像并进行一系列的图像处理工作。我最常用的图像库当然是opencv,很强大很好用,但是opencv也有一些坑,不注意的话也会搞出大麻烦。近期我也在看一些别人写的代码,因为个人习惯不一样,他们在做深度学习时用于图片读取的图像库各不相同,从opencv到PIL再到skimage等等各种库都有,有些库读进来的图片存储方式也不太一样,如果不好好总结这些主流图像读写库特点的话,以后看代码写代码都会遇坑无数。这篇文章就总结了以下主流Python图像库的一些基本使用方法和需要注意的地方:

1.opencv
2.PIL(pillow)
3.matplotlib.image
4.scipy.misc
5.skimage

opencv: cv2.imread

opencv作为我最常用的图像处理库,当然第一个介绍,并且介绍得比较全面。毋庸置疑,opencv是今天介绍得所有图像库中最全面也最强大的库,如果我们只想掌握一个图像库,我觉得opencv库肯定是最适合不过了。

图片读取操作

import cv2
import numpy as np

#读入图片:默认彩色图,cv2.IMREAD_GRAYSCALE灰度图,cv2.IMREAD_UNCHANGED包含alpha通道
img = cv2.imread('1.jpg')
cv2.imshow('src',img)
print(img.shape) # (h,w,c)
print(img.size) # 像素总数目
print(img.dtype)
print(img)
cv2.waitKey()

Python各类图像库的图片读写方式总结(推荐)

Python各类图像库的图片读写方式总结(推荐)

值得注意的是,opencv读进来的图片已经是一个numpy矩阵了,彩色图片维度是(高度,宽度,通道数)。数据类型是uint8。

#gray = cv2.imread('1.jpg',cv2.IMREAD_GRAYSCALE) #灰度图
#cv2.imshow('gray',gray)
#也可以这么写,先读入彩色图,再转灰度图
src = cv2.imread('1.jpg')
gray = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)
cv2.imshow('gray',gray)
print(gray.shape)
print(gray.size)
print(gray)
cv2.waitKey()

Python各类图像库的图片读写方式总结(推荐)

Python各类图像库的图片读写方式总结(推荐)

上面提到了两种获取灰度图的方式,读进来的灰度图的矩阵格式是(高度,宽度)。

#注意,计算图片路径是错的,Opencv也不会提醒你,但print img时得到的结果是None
img2 = cv2.imread('2.jpg')
print(img2)

Python各类图像库的图片读写方式总结(推荐)

#如何解决“读到的图片不存在的问题”? #加入判断语句,如果为空,做异常处理
img2 = cv2.imread('2.jpg')
if img2 == None:
  print('fail to load image!')

Python各类图像库的图片读写方式总结(推荐)

图片矩阵变换

opencv读入图片的矩阵格式是:(height,width,channels)。而在深度学习中,因为要对不同通道应用卷积,所以会采取另一种方式:(channels,height,width)。为了应对该要求,我们可以这么做

#注意到,opencv读入的图片的彩色图是一个channel last的三维矩阵(h,w,c),即(高度,宽度,通道)
#有时候在深度学习中用到的的图片矩阵形式可能是channel first,那我们可以这样转一下
print(img.shape)
img = img.transpose(2,0,1)
print(img.shape)

Python各类图像库的图片读写方式总结(推荐)

在深度学习搭建CNN时,往往要做相应的图像数据处理,比如图像要扩展维度,比如扩展成(batch_size,channels,height,width)。

对于这种要求,我们可以这么做。

#有时候还要扩展维度,比如有时候我们需要预测单张图片,要在要加一列做图片的个数,可以这么做
img = np.expand_dims(img, axis=0)
print(img.shape)

Python各类图像库的图片读写方式总结(推荐)

上面提到的是预测阶段时预测单张图片的扩展维度的操作,如果是训练阶段,构建batch,即得到这种形式:(batch_size,channels,height,width)。我一般喜欢这么做

data_list = [] 
loop:
  im = cv2.imread('xxx.png')
  data_list.append(im)
data_arr = np.array(data_list)

这样子就能构造成我们想要的形式了。

图片归一化

#因为opencv读入的图片矩阵数值是0到255,有时我们需要对其进行归一化为0~1
img3 = cv2.imread('1.jpg')
img3 = img3.astype("float") / 255.0 #注意需要先转化数据类型为float
print(img3.dtype)
print(img3)

Python各类图像库的图片读写方式总结(推荐)

存储图片

#存储图片
cv2.imwrite('test1.jpg',img3) #得到的是全黑的图片,因为我们把它归一化了
#所以要得到可视化的图,需要先*255还原
img3 = img3 * 255
cv2.imwrite('test2.jpg',img3) #这样就可以看到彩色原图了

opencv大坑之BGR

opencv对于读进来的图片的通道排列是BGR,而不是主流的RGB!谨记!

#opencv读入的矩阵是BGR,如果想转为RGB,可以这么转
img4 = cv2.imread('1.jpg')
img4 = cv2.cvtColor(img4,cv2.COLOR_BGR2RGB)

访问像素

#访问像素
print(img4[10,10]) #3channels
print(gray[10,10]) #1channel
img4[10,10] = [255,255,255]
gray[10,10] = 255
print(img4[10,10]) #3channels
print(gray[10,10]) #1channel

Python各类图像库的图片读写方式总结(推荐)

ROI操作

#roi操作
roi = img4[200:550,100:450,:]
cv2.imshow('roi',roi)
cv2.waitKey()

Python各类图像库的图片读写方式总结(推荐)

通道操作

#分离通道
img5 = cv2.imread('1.jpg')
b,g,r = cv2.split(img5)
#合并通道
img5 = cv2.merge((b,g,r))
#也可以不拆分
img5[:,:,2] = 0 #将红色通道值全部设0

PIL:PIL.Image.open

图片读取

from PIL import Image
import numpy as np

PIL即Python Imaging Library,也即为我们所称的Pillow,是一个很流行的图像库,它比opencv更为轻巧,正因如此,它深受大众的喜爱。

图像读写

PIL读进来的图像是一个对象,而不是我们所熟知的numpy 矩阵。

img = Image.open('1.jpg')
print(img.format) 
print(img.size) #注意,省略了通道 (w,h)
print(img.mode) #L为灰度图,RGB为真彩色,RGBA为加了透明通道
img.show() # 显示图片

Python各类图像库的图片读写方式总结(推荐)

Python各类图像库的图片读写方式总结(推荐)

灰度图的获取

gray = Image.open('1.jpg').convert('L')
gray.show()

Python各类图像库的图片读写方式总结(推荐)

#读取不到图片会抛出异常IOError,我们可以捕捉它,做异常处理
try:
  img2 = Image.open('2.jpg')
except IOError:
  print('fail to load image!')

Python各类图像库的图片读写方式总结(推荐)

#pillow读进来的图片不是矩阵,我们将图片转矩阵,channel last
arr = np.array(img3)
print(arr.shape)
print(arr.dtype)
print(arr)

Python各类图像库的图片读写方式总结(推荐)

灰度图的转化与彩图转化一样

arr_gray = np.array(gray)
print(arr_gray.shape)
print(arr_gray.dtype)
print(arr_gray)

Python各类图像库的图片读写方式总结(推荐)

存储图片

#矩阵再转为图像
new_im = Image.fromarray(arr)
new_im.save('3.png')

图像操作

#分离合并通道
r, g, b = img.split()
img = Image.merge("RGB", (b, g, r))
img = img.copy() #复制图像

ROI获取

img3 = Image.open('1.jpg')
roi = img3.crop((0,0,300,300)) #(左上x,左上y,右下x,右下y)坐标
roi.show()

matplotlib:matplotlib.image.imread

matplotlib是一个科学绘图神器,用的人非常多。

import matplotlib.pyplot as plt
import numpy as np
image = plt.imread('1.jpg')
plt.imshow(image)
plt.show()

Python各类图像库的图片读写方式总结(推荐)

#也可以关闭显示x,y轴上的数字
image = plt.imread('1.jpg')
plt.imshow(image)
plt.axis('off')
plt.show()

Python各类图像库的图片读写方式总结(推荐)

#plt.imread读入的就是一个矩阵,跟opencv一样,但彩图读进的是RGB,与opencv有区别
print(image.shape) # (h,w,c)
print(image.size)
print(image.dtype) 
print(image)

Python各类图像库的图片读写方式总结(推荐)

im_r = image[:,:,0] #红色通道
plt.imshow(im_r)
plt.show()
#此时会发现显示的是热量图,不是我们预想的灰度图,可以添加 cmap 参数解决
plt.imshow(im_r,cmap='Greys_r')
plt.show()

Python各类图像库的图片读写方式总结(推荐)

#与opencv结合使用
import cv2
im2 = cv2.imread('1.jpg')
plt.imshow(im2)
plt.axis('off')
plt.show()
#发现图像颜色怪怪的,原因当然是我们前面提到的RGB顺序不同的原因啦,转一下就好
im2 = cv2.cvtColor(im2,cv2.COLOR_BGR2RGB)
plt.imshow(im2)
plt.axis('off')
plt.show()
#所以无论用什么库读进图片,只要把图片改为矩阵,那么matplotlib就可以处理了

Python各类图像库的图片读写方式总结(推荐)

#再试一试pillow和matplotlib结合
from PIL import Image
im3 = Image.open('1.jpg')
im3 = np.array(im3)
plt.figure(1)
plt.imshow(im3)
plt.axis('off')
#存储图像,注意,必须在show之前savefig,否则存储的图片一片空白
plt.savefig('timo.jpg')
plt.show()

Python各类图像库的图片读写方式总结(推荐)

#最后以一个综合例子总结matplotlib最基本的图片显示技巧吧
im_lol1 = plt.imread('lol.jpg')
im_lol2 = plt.imread('1.jpg')
figure = plt.figure(figsize=(20,10)) # 调整显示图片的大小
'''
figsize参数:指定绘图对象的宽度和高度,单位为英寸;dpi参数指定绘图对象的分辨率,
即每英寸多少个像素,缺省值为80。因此本例中所创建的图表窗口的宽度为8*80 = 640像素
'''
plt.axis("off")#不显示刻度 
ax = figure.add_subplot(121) # 图片以1行2列的形式显示
plt.axis('off')
ax.imshow(im_lol1) #第一张图
ax.set_title('lol image 1')#给图片加titile 
ax = figure.add_subplot(122) 
plt.axis('off')
ax.imshow(im_lol2) 
ax.set_title('lol image 2')#给图片加titile 

plt.savefig('twp.jpg')
plt.show()

Python各类图像库的图片读写方式总结(推荐)

scipy.misc:scipy.misc.imread

from scipy import misc
import matplotlib.pyplot as plt
im = misc.imread('1.jpg')
print(im.dtype)
print(im.size)
print(im.shape)
misc.imsave('misc1.png',im)
plt.imshow(im)
plt.show()
print(im)

Python各类图像库的图片读写方式总结(推荐)

Python各类图像库的图片读写方式总结(推荐)

可以看到,有warining,提示我们imread和imsave在后来的版本将会被弃用,叫我们使用imageio.imread和imageio.imwrite。

我们根据她的提示,使用imageio模块进行图片读写,warning也就没有了。

import imageio
im2 = imageio.imread('1.jpg')
print(im2.dtype)
print(im2.size)
print(im2.shape)
plt.imshow(im)
plt.show()
print(im2)
imageio.imsave('imageio.png',im2)

Python各类图像库的图片读写方式总结(推荐)

skimage:skimage.io.imread

from skimage import io

im = io.imread('1.jpg')
print(im.shape) # numpy矩阵,(h,w,c)
print(im.dtype)
print(im.size)
io.imshow(im)
io.imsave('sk.png',im)
print(im)

Python各类图像库的图片读写方式总结(推荐)

图像也是以numpy array形式读入。

灰度图的获取方式:

im2 = io.imread('1.jpg',as_grey=True) #读入灰度图
print(im2.dtype)
print(im2.size)
print(im2.shape)
io.imshow(im2)
io.imsave('sk_gray.png',im2)
io.show()
print(im2)

Python各类图像库的图片读写方式总结(推荐)

可以看到,灰度图像的矩阵的值被归一化了,注意注意!

也可以以这种方式获得灰度图:

from skimage import color
im3 = io.imread('1.jpg')
im3 = color.rgb2grey(im3)
print(im3.dtype)
print(im3.size)
print(im3.shape)
io.imshow(im3)
io.show()

'''
skimage.color.rgb2grey(rgb)
skimage.color.rgb2hsv(rgb)
skimage.color.rgb2lab(rgb)
skimage.color.gray2rgb(image)
skimage.color.hsv2rgb(hsv)
skimage.color.lab2rgb(lab)

'''

Python各类图像库的图片读写方式总结(推荐)

总结

  1. 除了opencv读入的彩色图片以BGR顺序存储外,其他所有图像库读入彩色图片都以RGB存储。
  2. 除了PIL读入的图片是img类之外,其他库读进来的图片都是以numpy 矩阵。
  3. 各大图像库的性能,老大哥当属opencv,无论是速度还是图片操作的全面性,都属于碾压的存在,毕竟他是一个巨大的cv专用库。下面那张图就是我从知乎盗来的一张关于各个主流图像库的一些性能比较图,从测试结果看来,opencv确实胜出太多了。

Python各类图像库的图片读写方式总结(推荐)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Linux下使用python调用top命令获得CPU利用率
Mar 10 Python
Python中字典的基础知识归纳小结
Aug 19 Python
Python数组遍历的简单实现方法小结
Apr 27 Python
浅析Python3爬虫登录模拟
Feb 07 Python
django将图片上传数据库后在前端显式的方法
May 25 Python
python爬取酷狗音乐排行榜
Feb 20 Python
Python3 pandas 操作列表实例详解
Sep 23 Python
Pytorch中实现只导入部分模型参数的方式
Jan 02 Python
Python实现列表中非负数保留,负数转化为指定的数值方式
Jun 04 Python
浅谈python处理json和redis hash的坑
Jul 16 Python
pandas apply使用多列计算生成新的列实现示例
Feb 24 Python
Python+Matplotlib图像上指定坐标的位置添加文本标签与注释
Apr 11 Python
python自动发邮件库yagmail的示例代码
Feb 23 #Python
Python KMeans聚类问题分析
Feb 23 #Python
浅谈python爬虫使用Selenium模拟浏览器行为
Feb 23 #Python
python kmeans聚类简单介绍和实现代码
Feb 23 #Python
python MysqlDb模块安装及其使用详解
Feb 23 #Python
Python实现k-means算法
Feb 23 #Python
python语言中with as的用法使用详解
Feb 23 #Python
You might like
PHP中对于浮点型的数据需要用不同的方法解决
2014/03/11 PHP
ThinkPHP多语言支持与多模板支持概述
2014/08/22 PHP
JavaScript的document对象和window对象详解
2010/12/30 Javascript
javascript之Partial Application学习
2013/01/10 Javascript
jQuery jcrop插件截图使用方法
2013/11/20 Javascript
jquery easyui中treegrid用法的简单实例
2014/02/18 Javascript
jQuery实现简单的日期输入格式化控件
2015/03/12 Javascript
JavaScript使表单中的内容显示在屏幕上的方法
2015/06/29 Javascript
js clearInterval()方法的定义和用法
2015/11/11 Javascript
JavaScript截取指定长度字符串点击可以展开全部代码
2015/12/04 Javascript
jquery及js实现动态加载js文件的方法
2016/01/21 Javascript
JavaScript中 ES6 generator数据类型详解
2016/08/11 Javascript
node.js实现快速截图
2016/08/27 Javascript
将html页面保存成图片,图片写入pdf的实现方法(推荐)
2016/09/17 Javascript
js仿手机页面文件下拉刷新效果
2016/10/14 Javascript
基于js 字符串indexof与search方法的区别(详解)
2017/12/04 Javascript
element ui table(表格)实现点击一行展开功能
2018/12/04 Javascript
微信小程序wx.navigateTo中events属性实现页面间通信传值,数据同步
2019/07/13 Javascript
[03:03]2014DOTA2西雅图国际邀请赛 Alliance战队巡礼
2014/07/07 DOTA
[01:08:24]DOTA2-DPC中国联赛 正赛 RNG vs Phoenix BO3 第一场 2月5日
2021/03/11 DOTA
Python魔术方法详解
2015/02/14 Python
使用Python的Scrapy框架编写web爬虫的简单示例
2015/04/17 Python
Django框架下在视图中使用模版的方法
2015/07/16 Python
利用Python命令行传递实例化对象的方法
2016/11/02 Python
Python序列操作之进阶篇
2016/12/08 Python
python中使用psutil查看内存占用的情况
2018/06/11 Python
python按比例随机切分数据的实现
2019/07/11 Python
Python3的socket使用方法详解
2020/02/18 Python
基于python实现数组格式参数加密计算
2020/04/21 Python
Python爬取股票信息,并可视化数据的示例
2020/09/26 Python
详解win10下pytorch-gpu安装以及CUDA详细安装过程
2021/01/28 Python
YOINS官网:时尚女装网上购物
2017/03/17 全球购物
学校党支部承诺书
2015/04/30 职场文书
2015年办公室人员工作总结
2015/05/15 职场文书
springboot+VUE实现登录注册
2021/05/27 Vue.js
把77A收信机改造成收音机
2022/04/05 无线电