2011-11-10 10 views
6

私はOpenCvとStackOverflowの両方が新しく、Androidプログラミングには新しくなっています。AndroidのOpenCv:ファイルからの画像のキーポイント検出

私は、カメラから取得した画像といくつかの画像ファイルを照合して、どの画像ファイルがカメラ画像に似ているかを確認しようとしています。だからDescriptorExtractor.computeを使ってファイルイメージのキーポイントとSURF(私もSIFTを試してみました)を使ってカメライメージを取得しますが、ファイルイメージに適用されるメソッドは常に空のキーポイントリストを返します。私がカメラの画像でそれを使うと、私は常に空ではないリスト(平均して100点)を得ます。私が最も困惑しているのは、カメラから最初にロードされた同じイメージを使用していても、ファイルから取得したとしても、私はこの動作を取得するということです。

私が間違っていることを理解してもらえますか?ここにいくつかのテストコードがあります(ファイル部分のみですが、同じメソッドgetKpを使用してカメラからキーポイントを抽出します)。

public class HelloOpenCvActivity extends Activity { 
    private static final int FILE_REQUEST = 400; 
    /** Called when the activity is first created. */ 

    ImageView img; 
    TextView txt; 
    Bitmap logo; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     img = (ImageView) findViewById(R.id.image); 
     txt = (TextView) findViewById(R.id.kp); 

     img.setOnClickListener(new OnClickListener() { 

      public void onClick(View v) { 
       chooseFile();    
      } 
     }); 
    } 

    private void chooseFile(){ 
     Intent fileIntent = new Intent(Intent.ACTION_GET_CONTENT); 
     fileIntent.addCategory(Intent.CATEGORY_OPENABLE); 
     fileIntent.setType("image/*"); 
     startActivityForResult(Intent.createChooser(fileIntent,"prova"), FILE_REQUEST); 
    } 

    /*Quando ho il risultato della chiamata al file explorer, viene invocata questa callback */ 
    @Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
     if (requestCode == FILE_REQUEST) { 
      // obtain the filename 
      Uri uri = data.getData(); 
      String filePath = null; 
      if (uri != null) { 
       if (uri.toString().startsWith("file:")) { 
        filePath = uri.getPath(); 
       } else { // uri.startsWith("content:") 
        Cursor c = getContentResolver().query(uri, null, null, null, null); 
        if (c != null && c.moveToFirst()) { 
         int id = c.getColumnIndex(Images.Media.DATA); 
         if (id != -1) { 
          filePath = c.getString(id); 
         } 
        } 
       } 
      } 
      if (filePath != null) { 
       logo = BitmapFactory.decodeFile(filePath); 
       img.setImageBitmap(logo); 
       txt.setText(""+getKp(logo).size()); 
      } 
     } 
    } 

    private List<KeyPoint> getKp(Bitmap bm){ 
     Mat image = Utils.bitmapToMat(bm); 

     List<KeyPoint> kp = new ArrayList<KeyPoint>(); 
     FeatureDetector fd = FeatureDetector.create(FeatureDetector.SURF); 
     fd.detect(image, kp); 


     return kp; 
    } 

} 

ありがとうございました。

エール

答えて

12

私はこの問題を発見しました。カメラとファイルの画像はどちらもビットマップオブジェクトに保存できますが、その設定(Bitmap.Config)は異なります。カメラ画像はARGB_8888、ファイルはRGB_565です。 Bitmap.copyメソッドを使用して、ファイルイメージのビットマップ構成をARGB_8888に変更することがソリューションです。

private List<KeyPoint> getKp(Bitmap bm){ 
    //scale bitmap (otherwise the program crashes due to memory lack) 
    int MAX_DIM = 300; 
    int w, h;  
    if (bm.getWidth() >= bm.getHeight()){ 
     w = MAX_DIM; 
     h = bm.getHeight()*MAX_DIM/bm.getWidth(); 
    } 
    else{ 
     h = MAX_DIM; 
     w = bm.getWidth()*MAX_DIM/bm.getHeight(); 
    } 
    bm = Bitmap.createScaledBitmap(bm, w, h, false); 

    //change bitmap config <- THAT'S THE POINT! 
    Bitmap img = bm.copy(Bitmap.Config.ARGB_8888, false);   

    Mat image = Utils.bitmapToMat(img); 

    List<KeyPoint> kp = new ArrayList<KeyPoint>(); 
    FeatureDetector fd = FeatureDetector.create(FeatureDetector.SURF); 
    fd.detect(image, kp); 

    return kp; 
} 

これは、同じ問題に遭遇している人に役立ちます。 :-)

+0

魅力のように機能します。 –

関連する問題