Python图像处理一:图像的读取、显示与存储

图像的读取、显示与存储

skimage提供了io模块,用来对图像进行输入输出操作。为了方便练习,也提供了一个data模块,里面有一些示例图像,我们可以直接使用。

导入skimage模块可用:

from skimage import io

一、从外部读取图像并显示

使用skimage.io.imread(fname)函数,带一个参数,表示需要读取的文件路径。显示图像使用skimage.io.imshow(arr)函数,带一个参数,表示需要显示的arr数组(读取的图像以numpy数组形式计算)。例:

from skimage import io
img=io.imread('D:/lena.bmp')
io.imshow(img)

二、程序自带图像

skimage程序自带了一些示例图像,如果我们不想从外部读取图像,就可以直接使用这些示例图像:

astronaut 宇航员图像
coffee 一杯咖啡图像
camera 拿相机的人图像
coins 硬币图像
moon 月亮图像
checkerboard 棋盘图像
horse 马图像
page 书页图像
chelsea 小猫图像
hubble_deep_field 星空图像
text 文字图像
clock 时钟图像

显示这些图像可用如下代码,不带任何参数

from skimage import io,data
img=data.coffee()
io.imshow(img)

图像名对应的就是函数名,如coffee图像对应的函数名为coffee(). 这些示例图像存放在skimage的安装目录下面,路径名称为data_dir,我们可以将这个路径打印出来看看:

from skimage import data_dir
print(data_dir)

显示:
Python图像处理一:图像的读取、显示与存储_第1张图片

也就是说,下面两行读取图像的代码效果是一样的:

from skimage import data_dir,data,io
img1=data.coffee() 
img2=io.imread(data_dir+'/coffee.png')  

三、保存图像

使用io模块的imsave(fname,arr)函数来实现。第一个参数表示保存的路径和名称,第二个参数表示需要保存的数组变量。例:

from skimage import io,data
img=data.chelsea()
io.imshow(img)
io.imsave('d:/cat.jpg',img)

保存图像的同时也起到了转换格式的作用。如果读取时图像格式为jpg图像,保存为png格式,则将图像从jpg图像转换为png图像并保存。

四、图像信息

如果想知道图像信息,可以直接打印输出,代码如下:
from skimage import io,data
img=data.chelsea()
io.imshow(img)
print(type(img))  #显示类型
print(img.shape)  #显示尺寸
print(img.shape[0])  #图像宽度
print(img.shape[1])  #图像高度
print(img.shape[2])  #图像通道数
print(img.size)   #显示总像素个数
print(img.max())  #最大像素值
print(img.min())  #最小像素值
print(img.mean()) #像素平均值

五、图像绘制

matplotlib是一个专业绘图的库,可以设置多个figure窗口,设置figure的标题,隐藏坐标尺,甚至可以使用subplot在一个figure中显示多张图像。一般我们可以这样导入matplotlib库:
import matplotlib.pyplot as plt
也就是说,我们绘图实际上用的是matplotlib包的pyplot模块。实际上前面我们就已经用到了图像的绘制,如:

io.imshow(img)  

这一行代码的实质是利用matplotlib包对图像进行绘制,绘制成功后,返回一个matplotlib类型的数据。因此,我们也可以这样写:

import matplotlib.pyplot as plt
plt.imshow(img)

imshow()函数格式为:
matplotlib.pyplot.imshow(X, cmap=None)
X: 要绘制的图像或数组。
cmap: 颜色图谱(colormap), 默认绘制为RGB(A)颜色空间。
其它可选的颜色图谱如下:

颜色图谱 描述
autumn 红-橙-黄
bone 黑-白,x线
cool 青-洋红
copper 黑-铜
flag 红-白-蓝-黑
gray 黑-白
hot 黑-红-黄-白
hsv hsv颜色空间, 红-黄-绿-青-蓝-洋红-红
inferno 黑-红-黄
jet 蓝-青-黄-红
magma 黑-红-白
pink 黑-粉-白
plasma 绿-红-黄
prism 红-黄-绿-蓝-紫-…-绿模式
spring 洋红-黄
summer 绿-黄
viridis 蓝-绿-黄
winter 蓝-绿

用的比较多的有gray,jet等,如:

plt.imshow(image,plt.cm.gray)
plt.imshow(img,cmap=plt.cm.jet)

在窗口上绘制完图片后,返回一个AxesImage对象。要在窗口上显示这个对象,我们可以调用show()函数来进行显示。

from skimage import io,data
img=data.astronaut()
dst=io.imshow(img)
print(type(dst))
io.show()

显示一张图像,我们也可以这样写:

import matplotlib.pyplot as plt
from skimage import io,data
img=data.astronaut()
plt.imshow(img)
plt.show()

创建窗口和划分子图的方法:

1、用figure函数和subplot函数分别创建主窗口与子图

例:分开并同时显示宇航员图像的三个通道

from skimage import data
import matplotlib.pyplot as plt
img=data.astronaut()
plt.figure(num='astronaut',figsize=(8,8))  #创建一个名为astronaut的窗口,并设置大小 
plt.subplot(4,1,1)     #将窗口分为两行两列四个子图,则可显示四幅图像
plt.title('origin image')   #第一幅图像标题
plt.imshow(img)      #绘制第一幅图像

plt.subplot(4,1,2)     #第二个子图
plt.title('R channel')   #第二幅图像标题
plt.imshow(img[:,:,0],plt.cm.gray)      #绘制第二幅图像,且为灰度图
plt.axis('off')     #不显示坐标尺寸

plt.subplot(4,1,3)     #第三个子图
plt.title('G channel')   #第三幅图像标题
plt.imshow(img[:,:,1],plt.cm.gray)      #绘制第三幅图像,且为灰度图
plt.axis('off')     #不显示坐标尺寸

plt.subplot(4,1,4)     #第四个子图
plt.title('B channel')   #第四幅图像标题
plt.imshow(img[:,:,2],plt.cm.gray)      #绘制第四幅图像,且为灰度图
plt.axis('on')     #显示坐标尺寸

plt.show()   #显示窗口

在图像绘制过程中,我们用matplotlib.pyplot模块下的figure()函数来创建显示窗口,该函数的格式为:

matplotlib.pyplot.figure(num=None, figsize=None, dpi=None, facecolor=None, edgecolor=None)

所有参数都是可选的,都有默认值,因此调用该函数时可以不带任何参数,其中:
num: 整型或字符型都可以。如果设置为整型,则该整型数字表示窗口的序号。如果设置为字符型,则该字符串表示窗口的名称。用该参数来命名窗口,如果两个窗口序号或名相同,则后一个窗口会覆盖前一个窗口。

figsize: 设置窗口大小。是一个tuple型的整数,如figsize=(8,8)
dpi: 整形数字,表示窗口的分辨率。
facecolor: 窗口的背景颜色。
edgecolor: 窗口的边框颜色。
用figure()函数创建的窗口,只能显示一幅图像,如果想要显示多幅图像,则需要将这个窗口再划分为几个子图,在每个子图中显示不同的图像。我们可以使用subplot()函数来划分子图,函数格式为:
matplotlib.pyplot.subplot(nrows, ncols, plot_number)
nrows: 子图的行数。
ncols: 子图的列数。
plot_number: 当前子图的编号。
如:

plt.subplot(2,2,1)#则表示将figure窗口划分成了2行2列共4个子图,当前为第1个子图。我们有时也可以用这种写法:
plt.subplot(221)#两种写法效果是一样的。
#每个子图的标题可用title()函数来设置,是否使用坐标尺可用axis()函数来设置,如:
plt.subplot(221)
plt.title("first subwindow")
plt.axis('off')   

2、用subplots来创建显示窗口与划分子图

还有另外一种编写方法也可以划分子图,例:

import matplotlib.pyplot as plt
from skimage import data,color

img = data.coffee()

fig, axes = plt.subplots(2, 2, figsize=(7, 6))
ax0, ax1, ax2, ax3 = axes.ravel()

ax0.imshow(img)
ax0.set_title('Origin image')

ax1.imshow(img[:, :, 0], cmap=plt.cm.gray)
ax1.set_title('R channel')

ax2.imshow(img[:, :, 1], cmap=plt.cm.gray)
ax2.set_title('G channel')

ax3.imshow(img[:, :, 2], cmap=plt.cm.gray)
ax3.set_title('B channel')

for ax in axes.ravel():
    ax.axis('off')

fig.tight_layout()  #自动调整subplot间的参数

直接用subplots()函数来创建并划分窗口。注意,比前面的subplot()函数多了一个s,该函数格式为:

matplotlib.pyplot.subplots(nrows=1, ncols=1)
nrows: 所有子图行数,默认为1。
ncols: 所有子图列数,默认为1。

返回一个窗口figure, 和一个tuple型的ax对象,该对象包含所有的子图,可结合ravel()函数列出所有子图,如:

fig, axes = plt.subplots(2, 2, figsize=(7, 6))
ax0, ax1, ax2, ax3 = axes.ravel()
# 创建了2行2列4个子图,分别取名为ax0,ax1,ax2和ax3, 每个子图的标题用set_title()函数来设置,如:
ax0.imshow(img)
ax0.set_title("Original image")
# 如果有多个子图,我们还可以使用tight_layout()函数来调整显示的布局,该函数格式为:
matplotlib.pyplot.tight_layout(pad=1.08, h_pad=None, w_pad=None, rect=None)
# 所有的参数都是可选的,调用该函数时可省略所有的参数。
pad: 主窗口边缘和子图边缘间的间距,默认为1.08
h_pad, w_pad: 子图边缘之间的间距,默认为 pad
rect: 一个矩形区域,如果设置这个值,则将所有的子图调整到这个矩形区域内。
# 一般调用为:
plt.tight_layout()  #自动调整subplot间的参数

总结一下,绘制和显示图像常用到的函数有:

函数名 功能 调用格式
figure 创建一个显示窗口 plt.figure(num=1,figsize=(8,8)
imshow 绘制图像 plt.imshow(image)
show 显示窗口 plt.show()
subplot 划分子图 plt.subplot(2,2,1)
title 设置子图标题(与subplot结合使用) plt.title(‘origin image’)
axis 是否显示坐标尺 plt.axis(‘off’)
subplots 创建带有多个子图的窗口 fig,axes=plt.subplots(2,2,figsize=(8,8))
ravel 为每个子图设置变量 ax0,ax1,ax2,ax3=axes.ravel()
set_title 设置子图标题(与axes结合使用) ax0.set_title(‘first window’)
tight_layout 自动调整子图显示布局 plt.tight_layout()

你可能感兴趣的:(skimage,计算机视觉,1024程序员节)