2011-11-10 32 views
6

Tôi mới dùng cả OpenCv và StackOverflow, và gần như mới với lập trình Android vì vậy xin vui lòng giải thích cho tôi nếu câu hỏi của tôi là ngu ngốc.OpenCv trong Android: phát hiện điểm chính trong hình ảnh từ tập tin

Tôi đang cố gắng khớp một hình ảnh được lấy từ máy ảnh với một số tệp hình ảnh, để xem tệp hình ảnh nào giống với hình ảnh camera hơn. Vì vậy, tôi sử dụng DescriptorExtractor.compute để lấy các điểm chính của hình ảnh tệp và hình ảnh máy ảnh với SURF (Tôi cũng đã thử SIFT) để khớp với chúng nhưng ... phương pháp được áp dụng cho hình ảnh tệp luôn trả về danh sách điểm trống trong khi nếu tôi sử dụng nó trên hình ảnh camera, tôi luôn nhận được một danh sách không trống (trung bình một trăm điểm). Những gì câu đố tôi nhất là ngay cả khi sử dụng cùng một hình ảnh, nạp từ máy ảnh đầu tiên, và sau đó từ tập tin, tôi nhận được hành vi này.

Bạn có thể giúp tôi tìm ra những gì tôi đang làm không? Đây là một số mã thử nghiệm (chỉ dành cho phần tệp, nhưng tôi cũng sử dụng cùng phương thức getKp để trích xuất các điểm chính từ máy ảnh).

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; 
    } 

} 

Cảm ơn bạn rất nhiều.

Ale

Trả lời

12

Sau nhiều giờ nghiên cứu và nhức đầu ;-) Tôi đã tìm thấy sự cố. Hình ảnh từ máy ảnh và tệp có thể được lưu trữ trong cả hai đối tượng bitmap, nhưng cấu hình của chúng (Bitmap.Config) là khác nhau: ARGB_8888 cho hình ảnh camera và RGB_565 cho các tệp. Thay đổi cấu hình bitmap trong hình ảnh tệp thành ARGB_8888 bằng phương pháp Bitmap.copy là giải pháp.

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; 
} 

Hy vọng điều này có thể giúp bất kỳ ai gặp phải vấn đề tương tự. :-)

+0

Hoạt động như một sự quyến rũ, bạn hãy lên đi !! –

Các vấn đề liên quan