Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> Android上使用ASIFT實現對視角變化更魯棒的特征匹配

Android上使用ASIFT實現對視角變化更魯棒的特征匹配

編輯:Android開發實例

    上次講解了在Android上通過NDK把彩圖轉換為灰度圖,現在可以把WindowsMobile版的ASIFT 例子移植到Android上了.......在這裡還是要再次感謝Jean-Michel Morel和Guoshen Yu兩位大牛的無私奉獻,尊重知識尊重開源精神。

先來看看本文程序運行截圖:

 

左圖是設定識別率為最低的結果,右圖是設定識別率為較低的結果。

本文的代碼可以到這裡下載:http://www.pudn.com/downloads314/sourcecode/comm/android/detail1391871.html

這裡ASIFT的NDK代碼(C++)跟WM篇的DLL代碼大體一樣,不過也存在一些不同:

1、JNI不支持引用傳遞,所以有些值必須通過函數返回,例如:

 

  1. /**  
  2.  * 取得放大/縮小之後的圖像大小  
  3.  */ 
  4. JNIEXPORT jintArray JNICALL Java_com_testASIFT_LibASIFT_GetZoomSize(  
  5.         JNIEnv* env, jobject obj) {  
  6.     jint arrint[2];  
  7.     arrint[0] = IM_X;  
  8.     arrint[1] = IM_Y;  
  9.     jintArray result = env->NewIntArray(2);  
  10.     env->SetIntArrayRegion(result, 0, 2, arrint);  
  11.     return result;  
  12. }  
  13. /**  
  14.  * 返回匹配後圖像的大小 jintArray[0]為width, jintArray[1]為height  
  15.  */ 
  16. JNIEXPORT jintArray JNICALL Java_com_testASIFT_LibASIFT_GetMatchedImageSize(  
  17.         JNIEnv* env, jobject obj) {  
  18.     jint arrint[2];  
  19.     arrint[0] = wo;  
  20.     arrint[1] = ho;  
  21.     jintArray result = env->NewIntArray(2);  
  22.     env->SetIntArrayRegion(result, 0, 2, arrint);  
  23.     return result;  

2、ASIFT接受的是8bit的灰度圖,使用前要轉換為8bit的灰度圖:

  1. void PixelToVector(jint *cbuf, int w, int h, std::vector<float> *ipixels) {  
  2.     for (int i = 0; i < h; i++) {  
  3.         for (int j = 0; j < w; j++) {  
  4.             // 獲得像素的顏色  
  5.             int color = cbuf[w * i + j];  
  6.             int red = ((color & 0x00FF0000) >> 16);  
  7.             int green = ((color & 0x0000FF00) >> 8);  
  8.             int blue = color & 0x000000FF;  
  9.             color = (red + green + blue) / 3;  
  10.             ipixels->push_back(color);//保存灰度值  
  11.         }  
  12.     }  
  13. }  

 

使用後要把8bit灰度圖轉為RGB565:

  1. jintArray result = env->NewIntArray(wo * ho);  
  2. jint *cResult;  
  3. cResult = env->GetIntArrayElements(result, false);  
  4. int alpha = 0xFF << 24;  
  5. for (int i = 0; i < ho; i++) {  
  6.     for (int j = 0; j < wo; j++) {  
  7.         // 獲得像素的顏色  
  8.         int color = (int) opixelsASIFT[wo * i + j];  
  9.         color = alpha | (color << 16) | (color << 8) | color;  
  10.         cResult[wo * i + j] = color;  
  11.     }  
  12. }  
  13. env->ReleaseIntArrayElements(result, cResult, 0); 

 

主類testASIFT.java的邏輯代碼如下:

 

  1. public class testASIFT extends Activity {  
  2.     /** Called when the activity is first created. */ 
  3.     ImageView imgView;  
  4.     @Override 
  5.     public void onCreate(Bundle savedInstanceState) {  
  6.         super.onCreate(savedInstanceState);  
  7.         setContentView(R.layout.main);  
  8.         this.setTitle("Android上使用ASIFT---hellogv");  
  9.         imgView=(ImageView)this.findViewById(R.id.ImageView01);  
  10.           
  11.         LibASIFT.initZoomSize(320, 480);//縮放目標的大小  
  12.         int []size=LibASIFT.GetZoomSize();//判斷是否設置成功  
  13.         Log.e(String.valueOf(size[0]),String.valueOf(size[1]));  
  14.           
  15.         Bitmap img1=((BitmapDrawable) getResources().getDrawable(R.drawable.adam1)).getBitmap();  
  16.         int w1=img1.getWidth(),h1=img1.getHeight();  
  17.         int[] pix1 = new int[w1 * h1];  
  18.         img1.getPixels(pix1, 0, w1, 0, 0, w1, h1);  
  19.         //提取第一張圖片的特征點  
  20.         LibASIFT.initImage1(pix1, w1, h1, 2);  
  21.         Bitmap img2=((BitmapDrawable) getResources().getDrawable(R.drawable.adam2)).getBitmap();  
  22.         int w2=img2.getWidth(),h2=img2.getHeight();  
  23.         int[] pix2 = new int[w2 * h2];  
  24.         img2.getPixels(pix2, 0, w2, 0, 0, w2, h2);  
  25.         int[] imgPixels=LibASIFT.Match2ImageForImg(pix2, w2, h2, 2);//兩圖匹配  
  26.         int[] imgSize=LibASIFT.GetMatchedImageSize();//匹配結果圖的大小  
  27.         Bitmap imgResult=Bitmap.createBitmap(imgSize[0], imgSize[1], Config.RGB_565);  
  28.         imgResult.setPixels(imgPixels, 0, imgResult.getWidth(), 0, 0, imgResult.getWidth(), imgResult.getHeight());  
  29.         imgView.setImageBitmap(imgResult);//顯示結果  
  30.           
  31.     }  

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved