bock transform 和KL 变换

概述

无论是在图像处理领域还是数据领域,KL变换或者称PCA都是一种很重要的手段,通过这种方法,我们能把降低数据的维度,保留最重要的信息,从而达到压缩或者减轻数据处理的复杂度。这篇文章主要从图像的角度来解释一下什么是KL变换。首先需要了解一下KL变换的背景知识,block transform 

Block Transform

何为Block transform? 首先需要说明,block transform是一种线性变换,( T(v1+v2) = T(v1)+T(v2) \T(alpha v) = alpha T(v) ) 通过block transfom,图像的能量可以集中在最初的几个参数上,这样我们可以把后面的参数置零,从而达到压缩的目的。因为在反变换时用到逆矩阵,而逆矩阵的运算会带来很多麻烦,所以一般block transform的变换矩阵都是酉矩阵。 *T表示共轭转置。 如果A实矩阵那么它的转置即为逆。

 酉矩阵有很多好的特点:

 (y = Ax spacespace x=A^{-1}y=A^Hy)

(|mathbf{y}|^{2}=mathbf{y}^{H} mathbf{y}=(mathbf{A} mathbf{x})^{H} mathbf{A} mathbf{x}=mathbf{x}^{H} mathbf{A}^{H} mathbf{A} mathbf{x}=mathbf{x}^{H} mathbf{x}=|mathbf{x}|^{2})

对于酉矩阵变换

平均值为

(oldsymbol{mu}_{y}=E[mathbf{y}]=E[mathbf{A} mathbf{x}]=mathbf{A} E[mathbf{x}]=mathbf{A} oldsymbol{mu}_{x})

协方差为

(mathbf{R}_{y y}=Eleft[left(mathbf{y}-oldsymbol{mu}_{y} ight) cdotleft(mathbf{y}-oldsymbol{mu}_{y} ight)^{H} ight]=mathbf{A} mathbf{R}_{x x} mathbf{A}^{H})

通过酉矩阵变换,能量会集中在最前面的几个参数,而能量通过协方差观察到。这里一个例子

 当 p = 0.95时,91.1%的能量都集中在第一个参数上。

因为有这种良好的性质,在图像处理中,往往将图像分为很多正方形,对每一个正方形进行block transform,将大部分信息都放在最初的几个参数上,达到图像压缩的目的。

在图像处理中,经常用到的Harr, DCT 变换就运用这种方式,通常有很好的效果。而所有变换都不能完全将能量集中在最开始的几个参数,并且每个维度之间uncorrelate 协方差成为一个对角线矩阵。如果想达到这种目的,只有通过KL变化

KL 变换

KL 变换是最优变化, 通过KL变换,图像成为 Best decoorelation and energy concentration. 那KL变换如何做到呢。

对于一个协方差矩阵来说, 可以将协方差矩阵分解为包含特征值和特征向量的矩阵。 (C_{xx} = UVU^T) 其中(U) 每一列为一个特征向量。(V)是一个对角线矩阵,对角线上对应特征值。得到(U) (V), 对特征值从大到小排序,并且调整特征向量,将(U^T)作为变换矩阵。 (Y=U^TX)。

为什么这样就可以得到最优的(C_yy)呢。 

( C_{yy} = A^TC_{xx}A\ Rightarrow C_{yy} = UC_{xx}U^T\ Rightarrow C_{yy} =UUVU^TU = V )

(C_{yy}) 就是特征值矩阵,也就是对角矩阵

对于协方差有一点说明

虽然协方差(C = E[((X-mu)^T(X-mu)]) 由于数据不同,公式也可以变。

如果

每一个小方块对应4个像素 一共有6个方块 每一列相当于一个维度。协方差为(C = E[((X-mu)^T(X-mu)])

1 block 1 2 3 4
2 block 1 2 3 4
3 block 1 2 3 4
4 block 1 2 3 4
5 block 1 2 3 4
6 block 1 2 3 4

如果每一行是一个维度 协方差为(C = E[(X-mu)(X-mu)^T])

1 block 2 block 3 block 4 block 5 block 6 block
1 1 1 1 1 1
2 2 2 2 2 2
3 3 3 3 3 3
4 4 4 4 4 4

代码 matlab

function [blocks , C_im , klt_base ] = compute_klt_basis (im)
N=8;
% 1. Allocate memory for blocks
sz = size (im);
x_arr = 1:N:( sz (2) - N+1);
y_arr = 1:N:( sz (1) - N+1);
blocks = zeros ( length ( x_arr ) * length ( y_arr ), N*N);
%2. Regroup the input image into blocks
for iy = 1: length ( y_arr )
    for ix = 1: length ( x_arr )
        x_start = x_arr (ix); y_start = y_arr (iy); 
        block_in = im( y_start : y_start +N -1, x_start : x_start +N -1);
        blocks ((iy -1)* length ( x_arr ) + ix , :) = block_in (:);
    end
end 
%3. Compute autocorrelation over all blocks
C_im = blocks '* blocks / size (blocks ,1);
[ klt_base_v ,ew] = eig( C_im );
[ew , ew_idx ] = sort ( diag (ew), 'descend ');
klt_base_v = klt_base_v (:, ew_idx );
klt_base = zeros (N^2);
for x = 0:N -1
    for y = 0:N -1
        idx = x*N+y+1;
        klt_base (y*N +1:( y+1)*N, x*N +1:( x+1)*N) = ...
        reshape ( klt_base_v (:, idx ), N, N);
    end
end
end

  

原文地址:https://www.cnblogs.com/deuchen/p/12834122.html