OpenCv on Android: detect key points in images from a file

I am new to OpenCv and StackOverflow, and almost new to Android programming, so please excuse me if my question is stupid.

I am trying to match the image received from the camera with some image files to see which image file looks more like the camera image. So I use DescriptorExtractor.compute to get the key points of the file image and the camera image using SURF (I also tried SIFT) to match them, but ... the method applied to the file image always returns an empty list of key points, whereas if I use it on the camera image, I always get a non-empty list (an average of one hundred points). What bothers me most is that even when using the image itself downloaded from the camera first and then from the file, I get this behavior.

Could you help me figure out what I'm doing wrong? Here are some test codes (only for part of the file, but I use the same getKp method to extract key points from the camera).

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

Many thanks.

Ale

+6
source share
1 answer

After several hours of research and a headache ;-) I found a problem. Images from the camera and file can be saved in raster objects, but their config (Bitmap.Config) is different: ARGB_8888 for images from the camera and RGB_565 for files. Changing the bitmap configuration in file images in ARGB_8888 using the Bitmap.copy method is a solution.

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

Hope this helps anyone who is facing the same problem. :-)

+12
source

Source: https://habr.com/ru/post/901207/


All Articles