处理是计算机技术及其相关学科的重要内容,但是数字图像处理的实践却往往因软件平台的限制而难以展开,本文采用简单易学,应用广泛的python语言,演示了数字图像处理的一般方法。
本文主要论述图片的存储结构、读取、保存、分割、拼接、合成,进一步的内容将在以后推送。
1.准备工作
本文使用python的numpy和matplotlib库演示数字图像的处理。在进行操作之前,需要先配置好运行环境。本文采用的运行环境为python3.9.0加VS Code。
在程序开头要声明所使用的库:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
同时还要准备实验材料,即一张jpg格式的图片:
2.图像的读取、显示和保存
2.1图像的读取和保存
使用matplotlib.image
中的函数可以轻松实现图片的读取和保存。
img=mpimg.imread('kite.jpg')#打开文件
mpimg.imsave('kite2.jpg',img)#保存文件
2.2图像数据查看
使用print()
方法,可以看到图片以三位数组的形式记录图像数据。使用.shape
方法可以获取三维数组的行数、列数和深度。对于BIP类型的图像文件,数组的最外层元素数量代表图像的高度,第二层数组元素数量代表图像的宽度,最里层数组元素数量代表波段数。
输入如下:
print(img)
height,width,bands=img.shape
print('图像高度为',height,'\n宽度为',width,'\n波段数为',bands)
输出如下:
[[[[253 253 253]
[253 253 253]
[253 253 253]
...
[253 253 253]
[253 253 253]
[253 253 253]]
...
[[253 253 253]
[253 253 253]
[253 253 253]
...
[253 253 253]
[253 253 253]
[253 253 253]]]
图像高度为 225
宽度为 211
波段数为 3
2.3图像的显示
图像的显示使用如下方法即可:
plt.imshow(img)
plt.show()
3.图像分割与波段分离
3.1数组索引和切片
经过前面的实验发现,栅格图像数据是以类似多维数组的方式存储的,因此可以采用数组操作的方法对图片进行处理。这里先学习一下数组的切片方法:
一维数组的索引和切片
例程如下:
a=[0,1,2,3,4,5,6]
print(a[2])#显示第2位的元素(序号从0开始)
print(a[2:4])#显示第2位到第4位的元素(不包含第4位)
print(a[2:])#显示第2位以后的元素
print(a[:2])#显示第2位以前的元素(不包含第2位)
print(a[:])#显示全部元素
输出如下:
2
[2, 3]
[2, 3, 4, 5, 6]
[0, 1]
[0, 1, 2, 3, 4, 5, 6]
二维数组的索引和切片
二维数组可以以如下方式进行创建和使用:
a=[[1,2,3],
[4,5,6],
[7,8,9]]
print(a[1][1])
print(a[:][1])
print(a[1][:])
输出结果如下:
5
[4, 5, 6]
[4, 5, 6]
这时发现对二维数组只能进行取“行”操作,而不能进行取“列”操作,因此需要引入numpy
库中的array
对象:
b=np.array(a)
#创建np.array对象b,取代数组a
print(b[1][1])
print(b[:,1])
#取所有行中的第1位元素,即取单列
print(b[1,:])
#取第1行,并取该行所有元素
输出结果如下
5
[2 5 8]
[4 5 6]
3.2图像分割
有了对多维数组的分割方法,即可像处理一般数组一样对图像进行处理:
如截取左上角100×100像素的图片:
img=mpimg.imread('kite.jpg')
new_img=img[:100,:100,:]
#取第100行以前、第100列以前,并保留所有波段
mpimg.imsave('cuted_kite.jpg',new_img)
输出结果:
3.3波段分离
波段的分离同样采用多维数组切片的方法进行:
img=mpimg.imread('kite.jpg')
red_img=img[:,:,0]
#第三维度的索引0,1,2分别代表Red、Green、Blues三个通道的灰度值
mpimg.imsave('red_kite.jpg',red_img)
matplotlib
会自动对灰度图像进行伪彩色变换,输出结果如下:
4.图像合并和多波段叠加
numpy
中提供了三个数组合并的方法:
- hstack:水平拼接,沿着行的方向,对列进行拼接;
- vstack:垂直拼接,沿着列的方向,对行进行拼接;
- dstack:沿着第三个轴(深度方向)进行拼接。
这三个方法也可以用于图像的处理。
4.1图像拼接
图像拼接前需要保证图像的宽度或高度一致,并且波段数一致。
img=mpimg.imread('kite.jpg')
img1=img[:100,:,:] #取第100行以前
img2=img[150:,:,:] #取第150行以后
new_img=np.vstack((img1,img2))
#垂直拼接,注意括号有两层
mpimg.imsave('new_img.jpg',new_img)
效果如下:
4.2多波段合成
下面演示了多波段假彩色合成方法:
img=mpimg.imread('kite.jpg')
red_img=img[:,:,0]#提取红光波段
green_img=img[:,:,1]#提取绿光波段
blue_img=img[:,:,2]#提取蓝光波段
new_img=np.dstack((red_img,blue_img,green_img))
#交换Blue波段和Green波段,进行合成
mpimg.imsave('new_img2.jpg',new_img)
效果如下: