Cơ sở lý thuyết của phép biến đổi KL Đây là phép biến đổi không gian chiều thành không gian chiều, với . Mỗi thành phần của vectơ miêu tả một đặc tính của đối tượng. Nếu ta biến đổi được từ không gian n chiều về không gian m chiều, như vậy ta sẽ làm giảm được thông tin dư thừa (theo thuật ngữ trong xử lý ảnh hay nhận dạng ảnh gọi là giảm thứ nguyên). Mục đích của biến đổi KL là chuyển từ không gian n chiều sang không gian trực giao m chiều sao cho sai số bình phương là nhỏ nhất. Gọi là tập các vector cơ sở trong không gian trực giao .
Trang 1Hồ Chí Sĩ
Lớp SP Tin K30
Bài kiểm tra giữa kì Môn: xử lí ảnh
-Đề bài: Cài đặt chương trình biến đổi K-L (Karhunen-Loeve) với số chiều là 2
class vecto
{
public double gt1;
public double gt2;
public vecto(double v1,double v2)
{
gt1=v1; gt2=v2;
}
public void hienthi()
{
System.out.println (" ("+gt1+","+gt2+") ");
}
public double getValue(double v)
{
if (v==0)
return gt1;
if (v==1)
return gt2;
return gt1+gt2; //vo cung }
}
class gtriRieng
{
public double gtRieng1;
public double gtRieng2;
public gtriRieng(double v1,double v2)
{
gtRieng1=v1;
gtRieng2=v2;
}
public void hienthi()
{ //giá trị riêng có thể là 1, 2 giá trị hoặc không tìm được.
Trang 2if(gtRieng1!=gtRieng2) {
System.out.println ("Gtri rieng 1= "+gtRieng1);
System.out.println ("Gtri rieng 2= "+gtRieng2);
} else
if(gtRieng1==gtRieng2)
System.out.println ("Gtri rieng = "+gtRieng1);
else
System.out.println (" Khong co gia tri rieng");
}
public double getValue(int v)
{
if(gtRieng1!=gtRieng2) {
if(v==0)
return gtRieng1;
if(v==1)
return gtRieng2;
} else
return gtRieng1;
return gtRieng1+gtRieng2; //Nếu không có giá trị riêng thì lấy “vô cùng”
}
}
class KLtrans
{ //Nhập dữ liệu vào mảng các vecto
public static void nhapDL(vecto data[])
{
for (int i = 0; i<data.length; i++){
System.out.println ("Nhap vecto "+i);
System.out.print ("Ptu 1: ");
int a=input.readInt();
System.out.print ("Ptu 2: ");
int b=input.readInt();
data[i]=new vecto(a,b);
} }
//Hiển thị danh sách các vecto đã nhập
public static void inDSVecto(vecto data[])
Trang 3System.out.println ();
for (int i = 0; i<data.length; i++)
data[i].hienthi();
}
// Tính vecto TB
public static vecto tinhgtriTB(vecto data[])
{
double tong1=0;
double tong2=0;
for (int i = 0; i<data.length; i++)
{
tong1=tong1+data[i].getValue(0);
tong2=tong2+data[i].getValue(1);
}
vecto kq=new vecto(tong1/data.length, tong2/data.length);
return kq;
}
//Tính ma trận hiệp biến
public static double[][] tinhmtHB(vecto vTB, vecto data[])
{
double kq[][]=new double [2][2];
for (int u = 0; u<2; u++)
{
double tg=0;
for (int v = 0; v<2; v++) {
tg=0;
for (int x = 0; x<data.length; x++)
tg=tg+(data[x].getValue(u)-vTB.getValue(u))*
(data[x].getValue(v) -vTB.getValue(v));
kq[u][v]=tg/data.length;
} }
return kq;
}
//Hiển thị ma trận hiệp biến
public static void inmtHB(double data[][])
{
System.out.println ("MA TRAN HIEP BIEN:");
for (int i = 0; i<2; i++)
{
Trang 4for (int j = 0; j<2; j++)
System.out.print(data[i][j]+" ");
System.out.println ();
}
}
// Tính giá trị riêng
public static gtriRieng tinhgtRieng(double mt[][])
{
gtriRieng kq;
double x1,x2;
double a=1;
double b=-(mt[0][0]+mt[1][1]);
double c=(mt[0][0]*mt[1][1])-(mt[1][0]*mt[0][1]);
double delta=b*b-4*a*c;
if(delta<0)
return null;
else
if(delta>0) {
x1=(-b+Math.sqrt(delta))/(2*a);
x2=(-b-Math.sqrt(delta))/(2*a);
} else {
x1=-b/(2*a);
x2=-b/(2*a);
} kq=new gtriRieng(x1,x2);
return kq;
}
// Tìm vecto riêng
public static vecto[] giaihptTT(double [][]data, gtriRieng g)
{
/* Hpt có dạng:
ax+by=0 (1) cx+ dy=0 (2) điều kiện: x 2 + y 2 =1 (3)
Vì D=ad-bc=0; Dx=Dy=0 => Vô số nghiệm
=> Kết hợp (1) với (3) để giải, dùng pp thế
*/
vecto kq[]=new vecto [2];
double a1=data[0][0];
Trang 5double b=data[0][1];
double tg1=Math.sqrt( 1/ ((a1/b)*(a1/b)+1)); //x=
double tg2=-a1*tg1/b; //y=-ax+b
kq[0]=new vecto(tg1,tg2);
double a2=data[0][0];
a2=data[0][0]-g.getValue(1);
double tg3=Math.sqrt( 1/ ((a2/b)*(a2/b)+1)); //x double tg4=-a2*tg3/b; //y=-ax/b
kq[1]=new vecto(tg3,tg4);
return kq;
}
// Tính các vecto biến đổi
public static vecto[] KLtrans(vecto T[], vecto dulieu[], gtriRieng G)
{
vecto kq[]=new vecto[dulieu.length];
double tg1=0,tg2=0;
for (int i = 0; i<dulieu.length; i++) {
for (int j = 0; j<T.length; j++) //Chạy trong mảng các veto riêng
{
tg1=T[j].getValue(0)*(dulieu[i].getValue(0)-G.getValue(0))+
T[j].getValue(0)*(dulieu[i].getValue(0)-G.getValue(0));
tg2=T[j].getValue(1)*(dulieu[i].getValue(1)-G.getValue(1))+
T[j].getValue(1)*(dulieu[i].getValue(1)-G.getValue(1));
} kq[i]=new vecto(tg1,tg2 );
} return kq;
}
// Chương trình chính
public static void main (String[] args) {
System.out.println ("Nhap so luong vecto: ");
int n=input.readInt();
vecto dulieu[]=new vecto[n];
double mtHiepBien[][]=new double[2][2];
nhapDL(dulieu);
2
) / ( 1
1
b a
+
Trang 6vecto a=tinhgtriTB(dulieu);
a.hienthi();
double matranHB[][]=tinhmtHB(a,dulieu);
inmtHB(matranHB);
gtriRieng b=tinhgtRieng(matranHB);
b.hienthi();
vecto vectoRieng[]=giaihptTT(matranHB,b);
System.out.println ("DS cac vecto rieng");
inDSVecto(vectoRieng);
vecto gtKL[]=KLtrans(vectoRieng,dulieu,b);
System.out.println ("DS cac vecto da chuyen doi KL");
inDSVecto(gtKL);
}
}
Trang 7Kết quả chương trình với hệ vecto {1,2} {3,4} {4,5} {3,2} {3,5} {4,2} {0,1} {2,1}
Ma trận hiệp biến:
1.75 1.25 1.25 2.44
Giá trị riêng 1= 3.39
Giá trị riêng 2= 0.80
Vecto riêng 1= (0.61,0.80)
Vecto riêng 2= (0.80,-0.61)
Các vecto đã chuyển đổi theo thuật toán KL:
g1= (-3.80 , -1.46 )
g2=(-0.62 , -3.88 )
g3= (0.97 , -5.09 )
g4= (-0.62 , -1.46)
g5= (-0.62 , -5.09)
g6= (0.97 , -1.46)
g7= (-5.39 , -0.24)
g8= (-2.21 , -0.24)