OpenCV,PIL,Skimage你pick谁

汤兴旺

就读于吉林大学汽车工程学院,计算机视觉爱好者,言有三弟子

作者 | 汤兴旺

编辑 | 汤兴旺/言有三

如何对图像进行处理是深度学习图像处理的基础,我们常常需要对图像进行读取、保存、缩放、裁剪、旋转、颜色转换等基本操作。

本文将讲解如何利用opencv、PIL、 scikit-image等进行图像处理,并比较它们之间微小的差异。

01

三大包的基础操作

本节讲解如何利用opencv、PIL、 scikit-image等工具进行图像读取、图像保存、图像缩放、裁剪、旋转、颜色转换等基本操作。

下面将基于下面这张图片演示如何对图形进行基本的处理

1.1 利用PIL处理图像

我们首先从读取图片开始,很多图像处理库(如opencv、skimage)都以imread()读取图片,但是PIL用open方法。

如果我们想要使用PIL来处理图像,必须先导入Image模块,这是进行一切操作的前提。导入方法如下:

from PIL import Image

读取一幅图像

#我的图片是保存在d盘picture文件夹下

img = Image.open('d:/picture/cat.jpg')

执行上述代码返回的结果如下:

怎样才能可视化这个图像呢?

我们需要调用matplotlib这个库,如果没有matplotlib.pyplot中的show()方法,图像只会在内存中,我们当然看不见了。话不多说,代码如下

from PIL import Image

import matplotlib.pyplot as plt

img = Image.open('d:/picture/cat.jpg')

plt.imshow(img)

plt.show()

结果如下:

查看图片信息

哈哈!图片我们已经看到了,这是万里长征的第一步。如果我们想要了解图片格式,大小应该怎么办呢?方法如下:

print(img.format)#查看图片格式

print(img.size)#查看图片大小

print(img.mode)#查看图片模式

我只列举了常用的三个其实还有很多,可以自行搜索

更改图像形式

使用PIL中的crop()方法可以从一幅图像中裁剪指定区域,该区域使用四元组来指定,四元组的的坐标依次是(b1,a1,b2,a2),通常一张图片的左上角为0。示意图如下:

如何对图像进行裁剪,具体代码如下:

裁剪后的图片

调整图片尺寸和旋转

我们可以使用resize()来调整图片尺寸,该方法的参数是一个元组,用来指定图像的大小,代码如下:

#把图片的尺寸改为400x400,tuple里面是图像的weight和height

Img2 = img1.resize((400,400))

调整大小后的图片

要旋转一幅图像,可以使用逆时针方法表示角度,调用rotate()方法,代码如下:

img2 = img1.rotate((45))

旋转后的图片

对图像旋转(旋转90度的整数倍)和翻转也可以用transpose,方法如下:

#左右对换。

img2=img1.transpose(Image.FLIP_LEFT_RIGHT)

#上下对换。

img2=img1.transpose(Image.FLIP_TOP_BOTTOM)

#旋转 90 度角。注意只能旋转90度的整数倍

img2=img1.transpose(Image.ROTATE_90)

左右翻转

上下翻转

图像颜色变化

PIL中可以使用convet()方法来实现图像一些颜色的变化,convert()函数会根据传入参数的不同将图片变成不同的模式。在PIL中有9种模式,如下表所示:

下面我们以灰度图像为例,将目标图像转换成灰度图像,方法如下:

img1 = img.convert('F')#将图片转化为32位浮点灰色图像,结果如下图:

下面再使用skimage和opencv对图像进行基本操作,只附上具体实现代码和注释,效果和上面的其实没什么差别。

1.2 使用skimage对图像处理

#导入io模块

from skimage import io

#以彩色模式读取图片

img=io.imread('d:/picture/cat.jpg')

#以灰色图像模式读取图片

img=io.imread('d:/picture/cat.jpg',as_grey=True)

#将图片保存在c盘,picture文件夹下

io.imsave('c:/picture/cat.jpg')

#将图片的大小变为500x500

img1 = transform.resize(img, (500,500))

#缩小为原来图片大小的0.1

img2 = transform.rescale(img, 0.1)

#缩小为原来图片行数一半,列数四分之一

img3 = transform.rescale(img, [0.5,0.25])

#放大为原来图片大小的2倍

img4 =transform.rescale(img, 2)

#旋转60度,不改变大小

img5 =transform.rotate(img, 60)

#旋转60度,同时改变大小

img6=transform.rotate(img, 60,resize=True)

#将图片调暗,。如果gamma大于1,新图像比原图像暗,如果gamma

img7= exposure.adjust_gamma(img, 4)

#将图片调亮

img8= exposure.adjust_gamma(img, 0.3)

1.3使用opencv对图像进行处理

#导入opencv

import cv2

#读取图片返回的是numpy.array格式

#cv2.imread共两个参数,第一个参数为要读入的图片文件名,第二个参数为如何读取图片,包括cv2.IMREAD_COLOR:读入一副彩色图片;cv2.IMREAD_GRAYSCALE:以灰度模式读入图片;cv2.IMREAD_UNCHANGED:读入一幅图片,并包括其alpha通道。

img = cv2.imread('d:/picture/cat.jpg')

#获取图片属性

print(img.shape)#返回图片的长,宽和通道数

#保存图片,共两个参数,第一个为保存文件名,第二个为读入图片

cv2.imwrite('c:/picture/cat4.jpg',img)

#创建一个窗口显示图片,共两个参数,第一个参数表示窗口名字,可以创建多个窗口中,但是每个窗口不能重名;第二个参数是读入的图片。

cv2.imshow()

#键盘绑定函数,共一个参数,表示等待毫秒数,将等待特定的几毫秒,看键盘是否有输入,返回值为ASCII值。如果其参数为0,则表示无限期的等待键盘输入

cv2.waitKey()

#删除建立的全部窗口

cv2.destroyAllWindows()

删除指定的窗口

cv2.destroyWindows()

#opencv中图像彩色空间变换函数cv2.cvtColor

cv2.cvtColor(input_image,fiag)

参数一: input_image表示将要变换色彩的图像ndarray对象

参数二: 表示图像色彩空间变换的类型,以下介绍常用的两种:

· cv2.COLOR_BGR2GRAY: 表示将图像从BGR空间转化成灰度图,最常用

· cv2.COLOR_BGR2HSV: 表示将图像从RGB空间转换到HSV空间

如果想查看参数flag的全部类型,请执行以下程序便可查阅,总共有274种空间转换类型:

import cv2

flags = [i for i in dir(cv2) if i.startswith('COLOR_')]

print(flags)

02

比较细节差异

2.1读取方式上的不同

我们首先从读取图片开始,PIL用open方法来读取图片,但opencv、skimage都以imread()读取图片。

2.2读进来内容的差异

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

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

opencV存储的格式:BGR

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

PIL储存的格式

针对PIL读进来的图像是一个对象,那么如何才能将读进来的图片转为矩阵呢,方法如下:

from PIL import Image

import numpy as np

img1 = Image.open('d:/picture/cat.jpg')

arr = np.array(img1)

转换后的格式

skimage读取一张图像时也是以numpy array形式读入skimage的存储格式是RGB。如下图所示:

skimage的存储格式RGB

skimage有一个巨大的不同是读取灰度图时其图像的矩阵的值被归一化了,注意注意!

我们skimage先看读取灰度图的方式,代码如下:

from skimage import io

img=io.imread('d:/picture/cat.jpg',as_grey=True)

读取的结果如下图所示,明显看到被归一化了!

我们再看opencv和PIL读取灰度图时会不会被归一化呢?代码和对比如下:

opencv读取灰度图

import cv2

img=cv2.imread('d:/picture/cat.jpg',cv2.IMREAD_GRAYSCALE)

opencv读取灰度图格式

PIL读取灰度图

from PIL import Image

import numpy as np

img1 = Image.open('d:/picture/cat.jpg').convert('L')

arr = np.array(img1)

PIL读取灰度图格式

从上面的对比可以看出skimage读取灰度图时的巨大不同就是其图像的矩阵的值被归一化了!!!

03

总结

总的来说OpenCV、Skimage、PIL各有千秋。各种框架中进行进行混用,所以我们都必须要掌握,而且要注意区分他们之间微小的差异。

如果想了解更多,欢迎关注知乎。

十月开始,我们有三AI学院开启了“稷”划和“济”划,帮助想入行以及想取得更多实战经验的同学。内容覆盖从自动驾驶到美颜直播等领域的实战项目,从图像基础到深度学习理论的系统知识,欢迎关注。

如果想加入我们,后台留言吧

转载后台联系,侵权必究

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181213G19XLT00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券