前言
K-L变换(Karhunen-Loeve Transform)是建立在统计特性基础上的一种变换,有的文献也称为霍特林变换,因他在1933年最先给出将离散信号变换成一串不相关系数的方法。K-L变换的突出优点是去相关性好,是均方误差意义下的最佳变换,它在数据压缩技术中占有重要地位。
图像K-L变换
- 步骤1:读取图片,将图片信息以8*8图像方块合成一个向量,将整张图片分割成一个n*64的矩阵A。
- 步骤2:计算向量数据矩阵A的协方差矩阵(64*64)。
- 步骤3:对协方差矩阵进行特征分解,并按特征值大小排列特征向量D。
- 步骤4:计算A*D,得到kl变换矩阵K。
- 步骤5:将矩阵K的后m列置为0。
- 步骤6:通过K*D^T得新矩阵A,并将其重新还原图像。
程序源码(python实现)
import cv2
import numpy as np
import matplotlib.pyplot as plt
def img2vec(image, blocksize):
image_w, image_h = img.shape
# 图像方块数据转换为向量
img_block_vec = np.zeros((int(image_w*image_h/blocksize/blocksize), blocksize*blocksize))
i = 0
for r in range(0,image.shape[0], blocksize):
for c in range(0,image.shape[1], blocksize):
block = image[r:r+blocksize,c:c+blocksize]
block = np.resize(block, (1, blocksize*blocksize))
img_block_vec[i] = block
i += 1
return img_block_vec
def vec2img(vectors, blocksize):
# 向量数据转换为图像
img_kl = np.zeros((new_w, new_h))
i = 0
for r in range(0,img_kl.shape[0], blocksize):
for c in range(0,img_kl.shape[1], blocksize):
block = vectors[i]
block = np.resize(block, (blocksize, blocksize))
i += 1
img_kl[r:r+blocksize,c:c+blocksize] = block
return img_kl.astype(int)
def kl_transform(vectors, principal_n):
# 计算协方差矩阵和特征
cov_matrix = np.cov(vectors.T)
_, fvec = np.linalg.eig(cov_matrix) # 输出的特征值默认降序排列
img_kl_block_vec = np.dot(vectors, fvec)
# 压缩,将非前N个主成分置为0
img_kl_block_vec[:,principal_n:] = 0
return np.dot(img_kl_block_vec, fvec.T)
if __name__ == "__main__":
filename = '3.png'
blocksize = 8 # 像素块
principal_n1 = 16 # 贡献度高的前N个特征值个数
# 读取图片
img = cv2.imread(filename)
img = np.array(cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)) #灰度化处理
# 图像大小设置为blocksize倍数
image_w, image_h = img.shape
new_w, new_h = image_w//blocksize*blocksize, image_h//blocksize*blocksize
img = cv2.resize(img, (new_h, new_w))
vec = img2vec(img, blocksize)
kl1 = vec2img(kl_transform(vec, principal_n1), blocksize)
plt.subplot(1, 2, 1)
plt.imshow(img, 'gray')
plt.subplot(1, 2, 2)
plt.imshow(kl1, 'gray')
小结
数字图像处理的实验报告,并没有在网上找到很好的例子,所以将自己写的例子发出来,如发现有错误,欢迎评论指正。