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 相关文章推荐
python构造icmp echo请求和实现网络探测器功能代码分享
Jan 10 Python
Python引用(import)文件夹下的py文件的方法
Aug 26 Python
浅谈Python中的数据类型
May 05 Python
Python实现文件信息进行合并实例代码
Jan 17 Python
python指定写入文件时的编码格式方法
Jun 07 Python
pandas的唯一值、值计数以及成员资格的示例
Jul 25 Python
Python一个简单的通信程序(客户端 服务器)
Mar 06 Python
基于python实现高速视频传输程序
May 05 Python
TensorFlow命名空间和TensorBoard图节点实例
Jan 23 Python
python 项目目录结构设置
Feb 14 Python
Python实现的北京积分落户数据分析示例
Mar 27 Python
python index() 与 rindex() 方法的使用示例详解
Dec 24 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实现让页面只能被百度gogole蜘蛛访问的方法
2009/12/29 PHP
神盾加密解密教程(三)PHP 神盾解密工具
2014/06/08 PHP
PHP随机获取未被微信屏蔽的域名(微信域名检测)
2017/03/19 PHP
[Web]防止用户复制页面内容和另存页面的方法
2009/02/06 Javascript
百度 popup.js 完美修正版非常的不错 脚本之家推荐
2009/04/17 Javascript
JQuery for与each性能比较分析
2013/05/14 Javascript
jquery eval解析JSON中的注意点介绍
2013/08/23 Javascript
jquery显示隐藏input对象
2014/07/21 Javascript
jquery实现侧边弹出的垂直导航
2014/12/09 Javascript
js实现的下拉框二级联动效果
2016/04/30 Javascript
jQuery实现的placeholder效果完整实例
2016/08/02 Javascript
JS获取字符串实际长度(包含汉字)的简单方法
2016/08/11 Javascript
vue2笔记 — vue-router路由懒加载的实现
2017/03/03 Javascript
jquery dataTable 获取某行数据
2017/05/05 jQuery
easyui-datagrid开发实践(总结)
2017/08/02 Javascript
Node.js+jade抓取博客所有文章生成静态html文件的实例
2017/09/19 Javascript
JS动态插入脚本和插入引用外部链接脚本的方法
2018/05/21 Javascript
在Koa.js中实现文件上传的接口功能
2019/10/08 Javascript
[03:49]DOTA2英雄基础教程 光之守卫
2014/01/14 DOTA
[40:05]DOTA2上海特级锦标赛A组小组赛#1 EHOME VS MVP.Phx第一局
2016/02/25 DOTA
python3操作微信itchat实现发送图片
2018/02/24 Python
浅谈Python中重载isinstance继承关系的问题
2018/05/04 Python
详解python3中tkinter知识点
2018/06/21 Python
Python绘制KS曲线的实现方法
2018/08/13 Python
python json.loads兼容单引号数据的方法
2018/12/19 Python
Django models文件模型变更错误解决
2020/05/11 Python
Python操作dict时避免出现KeyError的几种解决方法
2020/09/20 Python
戛纳奢侈品商店:Jacques Loup法国
2019/11/04 全球购物
兼职学生的自我评价
2013/11/24 职场文书
简历中求职的个人自我评价
2013/12/03 职场文书
材料专业毕业生求职信
2014/02/26 职场文书
2014年公务员思想汇报范文:全心全意为人民服务
2014/03/06 职场文书
2014教师党员自我评议总结
2014/09/19 职场文书
信用卡工资证明范本
2015/06/19 职场文书
一文彻底理解js原生语法prototype,__proto__和constructor
2021/10/24 Javascript
Spring Security使用单点登录的权限功能
2022/04/03 Java/Android