Numpy
NumPy(http://www.scipy.org/NumPy/)是非常有名的 Python 科学计算工具包,其中 包含了大量有用的思想,比如数组对象(用来表示向量、矩阵、图像等)以及线性代数函数。
1、图像数组表示
from PIL import Image
from pylab import *
im = array(Image.open('7.jpg'))
im2=array(Image.open('7.jpg').convert('L'))
im3=array(Image.open('7.jpg').convert('L'),'f')
print(im.shape,im.dtype)
print(im2.shape,im2.dtype)
print(im3.shape,im3.dtype)
1、每行的第一个元组表示图像数组的大小(行、列、颜色通道),紧接着的字符串表示数组元素的数据类型。图像通常被编码成无符号八位整数(uint8)。
2、在第一种情况下,载入图像并将其转换到数组中,数组的数据类型为“uint8”。
3、在第二种情况下,对图像进行灰度化处理,无颜色通道。
4、在创建数组时使用额外的参数“f”,该参数将数据类型转换为浮点型。
位于坐标 i、j,以及颜色通道 k 的像素值可以像 下面这样访问: value = im[i,j,k]
如对于RGB图像来说:im[i,j,0]获取(i,j)点像素的红色分量值。
2、灰度转换
灰度变换是一种改变图像灰度级别分布的操作,可以通过调整像素的亮度和对比度来改变图像的外观。可以用于图像增强、图像分析、图像压缩和特征提取等应用中。
from PIL import Image
from pylab import *
im = array(Image.open('7.jpg').convert('L'))
im2 = 255 - im # 对图像进行反相处理
im3 = (100.0/255) * im + 100 # 将图像像素值变换到 100...200 区间
im4 = 255.0 * (im/255.0)**2 #对图像像素值求平方后得到的图像
print(int(im.min()), int(im.max()))
print(int(im2.min()), int(im2.max()))
print(int(im3.min()), int(im3.max()))
print(int(im4.min()), int(im4.max()))
#将array类型变为jpg类型
img=Image.fromarray(unit8(im))#如果你并不十分确定输入数据的类型,安全起见,应该先转换成unit8
img2=Image.fromarray(unit8(im2))
figure()
subplot(1,2,1)
imshow(img)
subplot(1,2,2)
imshow(img2)
show()
3、直方图均值化
直方图均衡化是指将一幅图像的灰度直方图变平,使变换后的图像中每个灰度值的分布概率都相同。在对图像做进一步处理之前,直方图均衡化通常是对图像灰度值进行归一化的一个非常好的方法,并且可以增强图像的对比度。
直方图均衡化的变换函数是图像中像素值的累积分布函数(cumulative distribution function,简写为 cdf,将像素值的范围映射到目标范围的归一化操作)
from PIL import Image
from pylab import *
#对一幅图像实现直方图均值化
def histep(im,nbr_bins=256):#nbr_bins是使用小区间的数目
imhist,bins=histogram(im.flatten(),nbr_bins,normed=True)
cdf=imhist.cumsum()
cdf=255*cdf/cdf[-1]#归一化
# 使用累积分布函数的线性插值,计算新的像素值
im2=interp(im.flatten(),bins[:-1],cdf)
return im2.reshape(im.shape),cdf
im = array(Image.open('before.jpg').convert('L'))
im2,cdf=histep(im)
figure()
subplot(1,2,1)
imshow(im)
subplot(1,2,2)
imshow(im2)
show()
代码解析
imhist,bins=histogram(im.flatten(),nbr_bins,normed=True)
1、使用histogram
函数计算直方图。该函数接受两个参数,第一个参数是一维的输入数据,即展平后的图像数组;第二个参数nbr_bins
是指定直方图的分bin数目;normed=True
表示将直方图进行归一化处理,即使得各个bin的和为1。
2、imhist是数组,数组中的每个元素表示对应灰度级别的像素数量或频率;bins是直方图的分bin边界值,也是一个一维数组。它定义了每个bin的范围,用于将像素灰度级别映射到相应的bin中。
cdf=imhist.cumsum()
1、cumsum()函数可以将灰度级别从低到高按照对应的像素数量或频率排序,并计算累积的像素数量或频率。
4、图像平均
图像平均操作是减少图像噪声的一种简单方式,通常用于艺术特效。
#计算图像列表的平均图像
def compute_average(imlist):
#打开第一幅图像,将其存储在浮点型数组中
averageim = array(Image.open(imlist[0]), 'f')
for imname in imlist[1:]:
try:
averageim += array(Image.open(imname))
except:
print(imname + '...skipped')
averageim /= len(imlist)
# 返回 uint8 类型的平均图像
return array(averageim, 'uint8')
该函数包括一些基本的异常处理技巧,可以自动跳过不能打开的图像。
5、图像的主成分分析(PCA)
个人并没有太看懂,可以稍微看一下。主成分分析数模也会用到:(
在看代码之前可以先去详细了解一下PCA的原理
图像的主成分分析(Principal Component Analysis,简称PCA)是一种常用的降维和特征提取技术,通过线性变换将原始图像数据转换为一组新的特征向量,这些特征向量被称为主成分。主要用于数据降维、特征提取、数据可视化和图像压缩等领域。
步骤分析:
1、将变平的图像堆积起来,我们可以得到一个矩阵,矩阵的一行表示一幅图像。
2、对数据进行中心化。
3、我们通常使用 SVD(Singular Value Decomposition,奇异值分解)方法来计算主成分;但当矩阵的维数很大时,SVD 的计算非常慢,所以此时通常不使用 SVD 分解。
from PIL import Image
from numpy import *
#主成分分析
def pca(X):
#获取样本数、维数
num_data,dim = X.shape
#数据中心化
mean_X = X.mean(axis=0)#axis=0是沿着列方向
X = X - mean_X
if dim>num_data:#维度>样本数
M = dot(X,X.T) #获取协方差矩阵
e,EV = linalg.eigh(M) #获取特征值和特征向量
tmp = dot(X.T,EV).T #获取投影矩阵
V = tmp[::-1] #由于最后的特征向量是我们所需要的,所以需要将其逆转
S = sqrt(e)[::-1] # 由于特征值是按照递增顺序排列的,所以需要将其逆转
for i in range(V.shape[1]):#标准化
V[:,i] /= S
else:#使用 SVD方法
U,S,V = linalg.svd(X)
V= V[:num_data] # 仅仅返回前 nun_data 维的数据才合理
#返回投影矩阵、方差和均值
return V,S,mean_X
具体实现:
from PIL import Image
from numpy import *
from pylab import *
import pca #原来的pca代码保存到了另一个脚本,导入pca到此脚本
im = array(Image.open(imlist[0])) # 打开一幅图像,获取其大小
m,n = im.shape[0:2] # 获取图像的大小
imnbr = len(imlist) # 获取图像的数目
# 创建矩阵,保存所有压平后的图像数据
immatrix = array([array(Image.open(im)).flatten() for im in imlist],'f')
# 执行 PCA 操作
V,S,immean = pca.pca(immatrix)
# 显示一些图像(均值图像和前 7 个模式)
figure()
gray()
subplot(2,4,1)
#将图像从一维转成二维图像
imshow(immean.reshape(m,n))
for i in range(7):
subplot(2,4,i+2)
imshow(V[i].reshape(m,n))
show()
6、使用pickle模块
如果想要保存一些结果或者数据以方便后续使用,Python 中的 pickle 模块非常有用。
pickle 模块可以接受几乎所有的 Python 对象,并且将其转换成字符串表示,该 过程叫做封装(pickling)。
从字符串表示中重构该对象,称为拆封(unpickling)。
保存上一节图像的平均图像和主成分
# 保存均值和主成分数据
f = open('font_pca_modes.pkl', 'wb')
pickle.dump(immean,f)
pickle.dump(V,f)
f.close()
在 其他 Python 会话中载入数据,只需要如下使用 load() 方法:
# 载入均值和主成分数据
f = open('font_pca_modes.pkl', 'rb')
immean = pickle.load(f)
V = pickle.load(f)
f.close()
也可以用with()来实现保存和载入操作
# 打开文件并保存
with open('font_pca_modes.pkl', 'wb') as f:
pickle.dump(immean,f)
pickle.dump(V,f)
# 打开文件并载入
with open('font_pca_modes.pkl', 'rb') as f:
immean = pickle.load(f)
V = pickle.load(f)