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 .
Hồ 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. 1 if(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[]) 2 { System.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++) { 3 for (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]; 4 a1=data[0][0]-g.getValue(0); double 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); 5 2 )/(1 1 ba + inDSVecto(dulieu); vecto 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); } } 6 Kế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) 7 . Hồ 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. rieng"); inDSVecto(vectoRieng); vecto gtKL[]=KLtrans(vectoRieng,dulieu,b); System.out.println ("DS cac vecto da chuyen doi KL& quot;); inDSVecto(gtKL); } } 6 Kết quả chương trình với hệ vecto {1,2} {3,4}. 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];