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缩进区别分析
Feb 15 Python
python使用rabbitmq实现网络爬虫示例
Feb 20 Python
Python闭包的两个注意事项(推荐)
Mar 20 Python
django将图片上传数据库后在前端显式的方法
May 25 Python
python初学者,用python实现基本的学生管理系统(python3)代码实例
Apr 10 Python
Python实现图片批量加入水印代码实例
Nov 30 Python
python如何使用socketserver模块实现并发聊天
Dec 14 Python
django数据模型(Model)的字段类型解析
Dec 25 Python
Python第三方库的几种安装方式(小结)
Apr 03 Python
python利用tkinter实现图片格式转换的示例
Sep 28 Python
python+appium+yaml移动端自动化测试框架实现详解
Nov 24 Python
python中子类与父类的关系基础知识点
Feb 02 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
备份mysql数据库的php代码(一个表一个文件)
2010/05/28 PHP
php数组函数序列之array_splice() - 在数组任意位置插入元素
2011/11/07 PHP
PHP fopen中文文件名乱码问题解决方案
2020/10/28 PHP
jquery图片轮播插件仿支付宝2013版全屏图片幻灯片
2014/04/03 Javascript
jQuery实现ichat在线客服插件
2014/12/29 Javascript
jQuery+AJAX实现无刷新下拉加载更多
2015/07/03 Javascript
jQuery插件之Tocify动态节点目录菜单生成器附源码下载
2016/01/08 Javascript
设置点击文本框或图片弹出日历控件的实现代码
2016/05/12 Javascript
原生 JS Ajax,GET和POST 请求实例代码
2016/06/08 Javascript
基于VUE选择上传图片并页面显示(图片可删除)
2017/05/25 Javascript
Vue项目组件化工程开发实践方案
2018/01/09 Javascript
JavaScript递归函数解“汉诺塔”算法代码解析
2018/07/05 Javascript
jQuery实现checkbox全选功能完整实例
2018/07/12 jQuery
详解如何在微信小程序中愉快地使用sass
2018/07/30 Javascript
详解Vue依赖收集引发的问题
2019/04/22 Javascript
JavaScript JSON数据处理全集(小结)
2019/08/15 Javascript
javascript中innerHTML 获取或替换html内容的实现代码
2020/03/17 Javascript
Python中利用原始套接字进行网络编程的示例
2015/05/04 Python
浅谈Python的异常处理
2016/06/19 Python
Python Pandas数据中对时间的操作
2019/07/30 Python
Selenium 滚动页面至元素可见的方法
2020/03/18 Python
HTML5本地存储之Web Storage详解
2016/07/04 HTML / CSS
瑞典首都斯德哥尔摩的多元奢侈时尚品牌:Acne Studios
2017/07/09 全球购物
室内设计实习自我鉴定
2013/09/25 职场文书
化工工艺设计求职信
2014/06/25 职场文书
劳模先进事迹材料
2014/12/24 职场文书
优秀护士事迹材料
2014/12/25 职场文书
2015高考寄语集锦
2015/02/27 职场文书
法院个人总结
2015/03/03 职场文书
2015年幼儿园中班工作总结
2015/04/25 职场文书
2015年普法依法治理工作总结
2015/05/26 职场文书
银行中层干部培训心得体会
2016/01/11 职场文书
2019求职信:应届生求职信范文
2019/04/24 职场文书
MySQL利用UNION连接2个查询排序失效详解
2021/11/20 MySQL
详解jQuery的核心函数和事件处理
2022/02/18 jQuery
教你部署vue项目到docker
2022/04/05 Vue.js