OpenCv в Android: обнаружение ключевых точек в изображениях из файла


Я новичок как в OpenCv, так и в StackOverflow,и почти новичок в программировании на Android, поэтому, пожалуйста, извините меня, если мой вопрос глуп.

Я пытаюсь сопоставить изображение, полученное с камеры, с некоторыми файлами изображений, чтобы увидеть, какой файл изображения больше похож на изображение камеры. Поэтому я использую Дескрипторекстрактор.вычислите, чтобы получить ключевые точки изображения файла и изображения камеры с SURF (я также пытался просеять), чтобы сопоставить их, но... метод, применяемый к файлу image, всегда возвращает пустой список ключевых точек, в то время как если я использую его на изображении камеры, я всегда получаю непустой список (в среднем сто точек). Что меня больше всего озадачивает, так это то, что даже при использовании одного и того же изображения, загруженного сначала с камеры, а затем из файла, я получаю такое поведение.

Не могли бы вы помочь мне понять, что я делаю не так? Вот некоторый тестовый код (только для файловой части, но я использую тот же метод 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;
    }

}

Большое спасибо много.

Эль

1 6

1 ответ:

После нескольких часов исследований и головной боли ; -) я нашел проблему. Изображения с камеры и файла могут храниться как в растровых объектах, так и в их конфигурации (Bitmap.Config) отличается: ARGB_8888 для изображений камеры и RGB_565 для файлов. Изменение конфигурации растрового изображения в файле images На 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;
}

Надеюсь, что это может помочь любому, кто сталкивается с той же проблемой. :- )