%函数LBG.m: LBG训练法%
function [I_codebook,O_distortion]=LBG(t_image,nc,nd,th)
%I_codebook:最后所得的码本%
%O_distortion:向量到最后所得码本之间的平均误差%
%t_image:训练数据%
%Rearrangement of the training image%
[row,col]=size(t_image);
nt=row*col/nd;
R_image=[];
sqrt_nd=sqrt(nd);
x_count=fix(col/sqrt_nd);
y_count=fix(row/sqrt_nd);
for i=1:1:y_count
for j=1:1:x_count
r_image=t_image((i-1)*sqrt_nd+1:i*sqrt_nd,(j-1)*sqrt_nd+1:j*sqrt_nd);
R_image=[R_image;r_image(1:nd)];
end
end
%Read training data and group the data into training vectors%
ratio=fix(y_count*x_count/nt);
T_image=[];
for i=1:ratio:ratio*nt
T_image=[T_image;R_image(i,1:nd)];
end
%制造初始码本%
ratio=fix(y_count*x_count/nc);
I_codebook=[];
for i=1:ratio:ratio*nc
I_codebook=[I_codebook;R_image(i,1:nd)];
end
%LBG Algorithm%
disp('Begin LBG algorithm,and wait........');
Dt=[];
converge=1;
I_count=1;
Dt(1)=inf;
while(converge)
%步骤1: 将码本内容当作重心,将所有的向量分类至这些区间%
T_dis=0;
for i=1:1:nt
P_dis=inf;
P_index=0;
%将每一个向量均归类到与其距离最短的重心那一类%
for j=1:1:nc
dis=((T_image(i,:)-I_codebook(j,:))*(T_image(i,:)-I_codebook(j,:))');
if dis P_dis=dis;
P_index=j; %归类
end
end
T_dis=T_dis+P_dis/nd;
id(i)=P_index;
end
Dt=[Dt,T_dis/nt];
%步骤2: 重新计算每一个分类区间的重心并取代先前的码本内容%
for i=1:1:nc
count=0;
U_codebook=zeros(1,nd);
for j=1:1:nt
if id(j)==i
U_codebook=U_codebook+T_image(j,:);
count=count+1;
end
end
if count>0
I_codebook(i,1:nd)=U_codebook/count;
end
end
%步骤3: 计算并判断向量到其分类重心之间的平均误差是否小于收敛值th%
disp('Distortion of current iteration =');
disp(T_dis/nt);
I_count=I_count+1;
%判断前一次和这一次平均误差的修正值是否小于th%
if abs((Dt(I_count-1)-Dt(I_count))/Dt(I_count-1)) converge=0;
end
end
O_distortion= T_dis/nt; %最后的平均误差
disp('End of the LBG algorithm');