1.图像数组表示
1.1 运行代码
from PIL import Image
from numpy import array
img = array(Image.open("C:\\Users\\cgs\\Desktop\\pictures\\1 (3).jpg"))
print("img.shape:", img.shape)
print("img_dtype:", img.dtype)
1.2 显示结果
2. 灰度变换
2.1 运行代码
from PIL import Image
from numpy import *
from pylab import *
img = array(Image.open("C:\\Users\\cgs\\Desktop\\pictures\\1 (3).jpg").convert('L'))
img2 = 255 - img # 对图像进行反向处理
img3 = (100.0/255) * img + 100 # 将图像像素值变换到100-200区间
img4 = 255.0 * (img/255.0)**2 # 对图像像素值求平方后得到的图像
# 将Numpy 数组转换为PIL的图像对象
img4_pil= Image.fromarray(np.uint8(img4))
# 显示处理后的图像
print (int(img.min()), int(img.max()))
print (int(img2.min()), int(img2.max()))
print (int(img3.min()), int(img3.max()))
print (int(img4.min()), int(img4.max()))
2.2 三次不同处理后的图像
0 255
0 255
100 200
0 255
3. 图像缩放
3.1 运行对象
from PIL import Image
import numpy as np
from matplotlib import pyplot as plt
def imresize(im, sz):
"""使用PIL对象重新定义图像数组的大小"""
# 将 NumPy 数组转换为 PIL 图像对象
pil_img = Image.fromarray(np.uint8(im))
# 调整图像大小
resized_pil_img = pil_img.resize(sz)
# 将调整大小后的 PIL 图像转换回 NumPy 数组
return np.array(resized_pil_img)
if __name__ == "__main__":
# 读取图像并转换为 NumPy 数组
img = np.array(Image.open(r"C:\Users\cgs\Desktop\pictures\1 (5).jpg"))
# 调整图像大小
new_size = (100, 100) # 目标大小 (宽, 高)
resized_img = imresize(img, new_size)
# 显示调整大小后的图像
plt.imshow(resized_img)
plt.show()
3.2 显示图像
4. 直方图均衡化
def histeq(im, nbr_bins=256):
"""对一副灰度图像进行直方图均衡化"""
# 计算图像的直方图
imhist, bins = histogram(im.flatten(), nbr_bins, normed = True)
cdf = imhist.cumsum() # 累计分布函数
cdf = 255 * cdf / cdf[-1] # 归一化
# 使用累计分布函数的线性插值,计算新的像素值
img = interp(img.flatten(), bins[:-1], cdf)
return img.reshape(img.shape), cdf
5. 图像平均
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')
6. 图像的主成分分析(PCA)
6.1定义PCA函数
def pca(X):
"""主成分分析:
输入:矩阵X, 其中该矩阵中存储训练数据, 每一行为一条训练数据
返回:投影矩阵(按照维度的重要性排序)、方差和均值"""
# 获取维度
num_data, dim = X.shape
# 数据中心化
mean_X = X.mean(axis=0)
X = X - mean_X
if dim>num_data:
#PCA-使用紧致技巧
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:
# PCA使用SVD方法
U,S,V = linalg.svd(X)
V = V[:num_data]
# 返回投影矩阵、方差和均值
return V, S, mean_X
6.2 调用PCA函数
6.2.1 运行代码
import numpy as np
from scipy import linalg
from PIL import Image
import matplotlib.pyplot as plt
import os
def pca(X):
"""主成分分析:
输入: 矩阵X, 其中该矩阵中存储训练数据,每一行为一条训练数据
返回:投影矩阵(按照维度的重要性排序)、方差和均值"""
# 获取维度
num_data, dim = X.shape
# 数据中心化
mean_X = X.mean(axis=0)
X = X - mean_X
if dim > num_data:
# PCA-使用紧致技巧
M = np.dot(X, X.T) # 协方差矩阵
e, EV = linalg.eigh(M) # 特征值和特征向量
tmp = np.dot(X.T, EV).T
V = tmp[::-1] # 逆转最后的特征向量
S = np.sqrt(e)[::-1] # 由于特征值是按照递增顺序排列,将它逆转
for i in range(V.shape[1]):
V[:,i] /= S
else:
# PCA使用SVD方法
U, S, V = linalg.svd(X)
V = V[:num_data]
# 返回投影矩阵、方差和均值
return V, S, mean_X
# 定义图像文件夹路径
image_folder = "C:\\Users\\cgs\\Desktop\\pictures"
# 获取图像文件夹所有文件
imglist = [os.path.join(image_folder, filename) for filename in os.listdir(image_folder) if filename.endswith(('jpg', 'jpeg', 'png'))]
# 设定统一的图像尺寸
target_size = (128, 128) # 目标尺寸,可以根据需要调整
# 读取并调整图像尺寸
imglist_resized = []
for img_path in imglist:
img = Image.open(img_path).convert('L') # 转换为灰度图像
img = img.resize(target_size, Image.ANTIALIAS) # 调整图像尺寸
imglist_resized.append(np.array(img))
# 将图像数据转换为矩阵
imgmatrix = np.array([img.flatten() for img in imglist_resized], dtype='f')
# 执行PCA操作
V, S, imgmean = pca(imgmatrix)
# 显示一些图像(均值图像和前七个模式)
plt.figure()
plt.gray()
plt.subplot(2, 4, 1) # 2行4列第一个图像开始绘图
plt.imshow(imgmean.reshape(target_size))
for i in range(7):
plt.subplot(2, 4, i + 2)
plt.imshow(V[i].reshape(target_size))
plt.show()
6.2.2 运行结果
7. 使用pickle模块
# 使用pickle模块
# 载入均值和主成分数据,打开文件并保存
with open("font_pca_modes.pkl", 'wb') as f: # 写入二进制文件
pickle.dump(imgmean, f)
pickle.dump(V, f)
f.close()
# 读取均值和主成分数据, 打开文件并载入
with open("font_pca_modes.pkl", 'rb') as f: # 读取二进制文件
imgmean = pickle.load(f)
V = pickle.load(f)
模块文档页:pickle — Python object serialization — Python 3.12.5 documentation