Search code examples
javaandroidandroid-cameraaugmented-realityarcore

how to increase preview camera quality in ARCore


I'm using ARCore in my android project. It has one activity, MainActivity.java and one CustomArFragment.java.

The problem is that the camera quality is very low. how can I increase the camera preview resolution. In future , I need the recognize the text using camera and having such low quality, its difficult to recognize. I am not able to find the solution on google. Tried many things but got no success. Anyone please tell how to increase camera quality. I'm totally new in AR and android field.

Thanks :)

MainActivity.java :

public class MainActivity extends AppCompatActivity {

private CustomArFragment arFragment;
private TextView textView;
private AugmentedImageDatabase aid;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

arFragment = (CustomArFragment) getSupportFragmentManager().findFragmentById(R.id.arFragment);
textView = findViewById(R.id.textView);

arFragment.getArSceneView().getScene().addOnUpdateListener(this::onUpdate);

findViewById(R.id.registeredBtn).setOnClickListener(v -> {
    if(ActivityCompat.checkSelfPermission(this,
            Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
        return;
    }
    registeredImage();
});


}


private void registeredImage() {
File file = new File(getExternalFilesDir(null) + "/db.imgdb");
try {

    FileOutputStream outputStream = new FileOutputStream(file);
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.earth);
    aid.addImage("earth",bitmap);
    aid.serialize(outputStream);
    outputStream.close();
    Toast.makeText(this, "image Registered", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
    e.printStackTrace();
 }
}

private void onUpdate(FrameTime frameTime) {
frame = arFragment.getArSceneView().getArFrame();
Collection<AugmentedImage> images = frame.getUpdatedTrackables(AugmentedImage.class);
for(AugmentedImage image : images){
    if(image.getTrackingMethod() == AugmentedImage.TrackingMethod.FULL_TRACKING){
        if(image.getName().equals("lion")){
            textView.setText("LION is visible");
        }
        else if(image.getName().equals("download")){
            textView.setText("download is visible");
        }
        else{
            textView.setText("Nothing is visible till now");
        }
        Log.d("Value of textView : "," " + textView.getText());
    }
    Log.d("Value of textView1 : "," " + textView.getText());
  }
 }

 public void loadDB(Session session, Config config){
//InputStream dbStream = getResources().openRawResource(R.raw.imagedb);
try {
    File file = new File(getExternalFilesDir(null) + "/db.imgdb");
    FileInputStream dbStream = new FileInputStream(file);
    aid = AugmentedImageDatabase.deserialize(session, dbStream);
    config.setAugmentedImageDatabase(aid);
    session.configure(config);
    Log.d("TotalImages"," :  " + aid.getNumImages());

}catch (IOException e){
    e.printStackTrace();
}
}

CustomArFragment.java

public class CustomArFragment extends ArFragment {
@Override
protected Config getSessionConfiguration(Session session){
    getPlaneDiscoveryController().setInstructionView(null);
    Config config = new Config(session);
    config.setUpdateMode(Config.UpdateMode.LATEST_CAMERA_IMAGE);
    MainActivity activity = (MainActivity) getActivity();
    activity.loadDB(session,config);
    this.getArSceneView().setupSession(session);
    return config;
}
}

Solution

  • I added some info regarding a similar topic in this other question. But answering yours, check what CameraConfig is used by default (use getCameraConfig() on the Session). Then you can get the one that is of your interest (high GPU texture size) through getSupportedCameraConfigs() and configure the Session with it through setCameraConfig.

    Reading your question again, if you need in the future to recognize some text on the image, you might want to get a higher CPU image instead of GPU texture size. You can still use CameraConfig to check that and choose your favorite, but keep in mind that higher CPU images decreases the performance quite a bit. You might want to check my answer in the question I mentioned earlier.

    EDIT: Use this code snippet to check the CameraConfig being used and adapt it to your needs:

    Session session = new Session(requireActivity());
    
    // ...
    
    Size selectedSize = new Size(0, 0);
    CameraConfig selectedCameraConfig = null;
    
    CameraConfigFilter filter = new CameraConfigFilter(session);
    List<CameraConfig> cameraConfigsList = session.getSupportedCameraConfigs(filter);
    for (CameraConfig currentCameraConfig : cameraConfigsList) {
        Size cpuImageSize = currentCameraConfig.getImageSize();
        Size gpuTextureSize = currentCameraConfig.getTextureSize();
        Log.d("TAG", "CurrentCameraConfig CPU image size:" + cpuImageSize + " GPU texture size:" + gpuTextureSize);
    
        // Adapt this check to your needs
        if (gpuTextureSize.getWidth() > selectedSize.getWidth()) {
            selectedSize = gpuTextureSize;
            selectedCameraConfig = currentCameraConfig;
        }
    }
    
    Log.d("TAG", "Selected CameraConfig CPU image size:" + selectedCameraConfig.getImageSize() + " GPU texture size:" + selectedCameraConfig.getTextureSize());
    session.setCameraConfig(selectedCameraConfig);
    
    // ...
    
    // Don't forget to configure the session afterwards
    session.configure(config);