【AI基础】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<1,新图像比原图像亮

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各有千秋。各种框架中进行进行混用,所以我们都必须要掌握,而且要注意区分他们之间微小的差异。

(0)

相关推荐

  • Python进阶——OpenCV之Core Operations

    文章目录 图像基本操作 访问并修改像素值 访问图像的属性 设置图像区域 图像分割与合并 画图像边框 图像的数学操作 图像叠加 图像融合 图像位操作 Python OpenCV代码检测与速度优化 时隔一 ...

  • OpenCV探索之路(五):图片缩放和图像金字塔

    对图像进行缩放的最简单方法当然是调用resize函数啦! resize函数可以将源图像精确地转化为指定尺寸的目标图像. 要缩小图像,一般推荐使用CV_INETR_AREA来插值:若要放大图像,推荐使用 ...

  • 基于OpenCV的条形码区域分割

    重磅干货,第一时间送达 本期,我们将一起学习如何从图像中提取出含有条形码的区域.下面的代码,我们将在Anaconda中采用Python 2.7 完成,当然OpenCV中的图像处理库也是必不可少的. 分 ...

  • 使用OpenCV进行图像编辑--绘画和素描

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 OpenCV是功能强大的计算机视觉库,具有强大的图像处理工具包.在 ...

  • 【从零学习OpenCV 4】中值滤波

    重磅干货,第一时间送达 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍<OpenCV 4开发详解>.为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社沟通 ...

  • OpenCV基础知识入门

    本文旨在让你快速入门opencv. OpenCV OpenCV是计算机视觉中最受欢迎的库,最初由intel使用C和C ++进行开发的,现在也可以在python中使用.该库是一个跨平台的开源库,是免费使 ...

  • python+opencv图像处理(七)

    图像相减 图像可以做加法,当然也可以做减法,还可以做乘除法呢,这叫图像的四则运算. 本篇介绍两幅图像相减,以及使用加减法进行图像亮度增强. 图像相减的用处也比较多,比如视频中,要知道上一时刻和下一时刻 ...

  • (11条消息) Opencv 读取灰度图像会识别为3通道问题

    最近初接触图像cv,一切都是从零开始因此遇到了许多问题,故在此记录遇到的问题方便提醒自己也方便后来人不再困惑. 场景: 我们都知道灰度图或者红外图都是单通道图片,而彩色图片是三通道图片.但是当我们用i ...

  • Python+opencv 图像处理(五)

        灰度反转 "你说的黑是什么黑......"有一首歌的歌词是这样的. 在图像中,黑是什么? 很简单,就是0嘛. 因为在数字图像里,用0表示黑. 那么,"你说的白是什 ...

  • 基于Opencv的图像单应性转换实战

    重磅干货,第一时间送达 同形转换 我们所常见的都是以这样的方式来处理图像:检测斑点,分割感兴趣的对象等.我们如何将它们从一种形式转换为另一种形式来处理这些图像呢?通过单应矩阵快速转换图像可以实现这个需 ...

  • 常见的图像处理技术

    重磅干货,第一时间送达 本期文章中,让我们一起来学习以下内容. 通过PIL和OpenCV来使用一些常见的图像处理技术,例如将RGB图像转换为灰度图像.旋转图像.对图像进行消噪.检测图像中的边缘以及裁剪 ...

  • python+opencv图像处理(六)

    图像相加 两幅图像是可以加在一起的. 图像相加是通过对两幅大小相同的图像对应位置像素的相加运算,以产生一幅新的含有两幅图像信息的图像的方法.有时也称为图像合成. 1.(+)法 数学运算中的+可以用于图 ...

  • OpenCV-Python学习教程.2

    如果你用Linux得设备,可能会用到这里来看有没有设备被安全挂载.因为没有一个图形化的页面来方便的查看. 子Linux不是太好使 # 获取视频帧的宽w = fcap.get(cv2.CAP_PROP_ ...

  • 快速指南:使用OpenCV预处理神经网络中的面部图像的

    重磅干货,第一时间送达 本期将介绍脸部检测.眼睛检测:图像拉直.裁剪.调整大小.归一化等内容 目前,涉及面部分类的计算机视觉问题,通常都需要使用深度学习.因此在将图像输入神经网络之前,需要经过一个预处 ...