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 相关文章推荐
tornado框架blog模块分析与使用
Nov 21 Python
Python对数据库操作
Mar 28 Python
python实现批量修改文件名代码
Sep 10 Python
Python网络编程之TCP与UDP协议套接字用法示例
Feb 02 Python
pandas的object对象转时间对象的方法
Apr 11 Python
pycharm设置注释颜色的方法
May 23 Python
利用selenium爬虫抓取数据的基础教程
Jun 10 Python
Python音频操作工具PyAudio上手教程详解
Jun 26 Python
python 实现在一张图中绘制一个小的子图方法
Jul 07 Python
Python实现图片批量加入水印代码实例
Nov 30 Python
python GUI模拟实现计算器
Jun 22 Python
Python 抓取数据存储到Redis中的操作
Jul 16 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实例
2013/12/24 PHP
php利用cookie实现自动登录的方法
2014/12/10 PHP
PHP中应该避免使用同名变量(拆分临时变量)
2015/04/03 PHP
PHP加密解密函数详解
2015/10/28 PHP
Jquery上传插件 uploadify v3.1使用说明
2012/06/18 Javascript
js中Math之random,round,ceil,floor的用法总结
2013/12/26 Javascript
查询json的数据结构的8种方式简介
2014/03/10 Javascript
解决jQuery动态获取手机屏幕高和宽的问题
2014/05/07 Javascript
基于jQuery实现搜索关键字自动匹配功能
2020/03/26 Javascript
详解Bootstrap glyphicons字体图标
2016/01/04 Javascript
浅谈Javascript数组(推荐)
2016/05/17 Javascript
解决vue-cli + webpack 新建项目出错的问题
2018/03/20 Javascript
Vue.js实现数据响应的方法
2018/08/13 Javascript
vue2.0 下拉框默认标题设置方法
2018/08/22 Javascript
JS合并两个数组的3种方法详解
2019/10/24 Javascript
JS函数基本定义与用法示例
2020/01/15 Javascript
vue2.x 对象劫持的原理实现
2020/04/19 Javascript
[00:31]2016完美“圣”典风云人物:国士无双宣传片
2016/12/04 DOTA
Python使用代理抓取网站图片(多线程)
2014/03/14 Python
利用Python绘制MySQL数据图实现数据可视化
2015/03/30 Python
Python中使用bidict模块双向字典结构的奇技淫巧
2016/07/12 Python
Python数据结构之图的应用示例
2018/05/11 Python
python散点图实例之随机漫步
2018/08/27 Python
使用python3实现操作串口详解
2019/01/01 Python
pycharm 2018 激活码及破解补丁激活方式
2020/09/21 Python
如何理解python中数字列表
2020/05/29 Python
python调用私有属性的方法总结
2020/07/24 Python
Python pip install之SSL异常处理操作
2020/09/03 Python
html5使用canvas压缩图片的示例代码
2018/09/11 HTML / CSS
爱国主义演讲稿
2014/05/07 职场文书
对照检查剖析材料
2014/09/30 职场文书
党的群众路线整改落实情况汇报
2014/10/28 职场文书
中考学习决心书
2015/02/04 职场文书
交流会主持词
2015/07/02 职场文书
2015年重阳节主持词
2015/07/04 职场文书
win10拖拽文件时崩溃怎么解决?win10文件不能拖拽问题解决方法
2022/08/14 数码科技