Search code examples
androidcameraandroid-camera2

Camera2API on manual mode takes super low quality pictures


I've been for several days struggling with Camera2 API and apparently I'm stuck. I have an android app which uses Camera2 API to take pictures. It must run on a Samsung galaxy Tab A SM-T510 with Android 11. The app uses a call to camera2 API which after taking the picture, sends it in base64 format to the webview frontend.

Till here, everything is ok.

Now, for some reason, the picture using CaptureRequest.CONTROL_MODE on CameraMetadata.CONTROL_MODE_AUTO takes a picture with acceptable quality, but setting CaptureRequest.CONTROL_AE_MODE to CameraMetadata.CONTROL_AE_MODE_OFF and using similar settings takes a completely different picture. As you can see on the following images: Automatic settings / Manual settings

If I take a look to the settings that are being used, I can see that they are almost the same. See following two pictures comparing CaptureRequest settings and Capture result settings (automatic settings on the left and manual settings on the right): CaptureRequest comparison / CaptureResult comparison

As you will see the only differences on CaptureRequest are:

  • CONTROL_AE_MODE: Expected difference since it shows whether we are using automatic settings or not
  • CONTROL_AE_REGIONS: There is no difference indeed, but VS Code shows a difference on variable identifier
  • CONTROL_AF_REGIONS: There is no difference indeed, but VS Code shows a difference on variable identifier
  • CONTROL_AWB_REGIONS: There is no difference indeed, but VS Code shows a difference on variable identifier
  • LENS_APERTURE: I am trying to set it to 4 on manual settings, but apparently this value won't be changed on this tablet, so it will always stay at 1.9 (See CaptureResult value)
  • SENSOR_EXPOSURE_TIME: Set to 0 on automatic mode (This value changes on CaptureResult)
  • SENSOR_FRAME_DURATION: Very similar values
  • SENSOR_SENSITIVITY: Set to 0 on automatic mode (This value changes on CaptureResult)

Then the differences on CaptureResult are:

  • COLOR_CORRECTION_GAINS: Close enough values
  • COLOR_CORRECTION_TRANSFORM: Close enough values
  • CONTROL_AE_MODE: Expected difference since it shows whether we are using automatic settings or not
  • CONTROL_AE_REGIONS: There is no difference indeed, but VS Code shows a difference on variable identifier
  • CONTROL_AF_REGIONS: There is no difference indeed, but VS Code shows a difference on variable identifier
  • CONTROL_AWB_REGIONS: There is no difference indeed, but VS Code shows a difference on variable identifier
  • LENS_FOCUS_DISTANCE: Here is the main difference, but it does not explain why the picture is so white and noisy on manual mode
  • SENSOR_EXPOSURE_TIME: Close enough (Even so I tried hardcoding the same value and nothing changed)
  • SENSOR_FRAME_DURATION: Close enough (Even so I tried hardcoding the same value and nothing changed)
  • SENSOR_SENSITIVITY: Close enough (Even so I tried hardcoding the same value and nothing changed)

It seems to me that ISO (SENSOR_SENSITIVITY) uses kind of different values on automatic and manual mode, and I am beginning to think that there is some kind of post processing that is being performed on automatic mode and not on manual mode.

I've been struggling with this hours and hours and I don't see where I'm failing.

Could someone help me?

Here are the CaptureRequest and CaptureResult settings for both auto and manual settings:

CaptureRequest Auto:

COLOR_CORRECTION_ABERRATION_MODE: 0
COLOR_CORRECTION_GAINS: null
COLOR_CORRECTION_MODE: 2
COLOR_CORRECTION_TRANSFORM: null
CONTROL_AE_ANTIBANDING_MODE: 3
CONTROL_AE_EXPOSURE_COMPENSATION: 0
CONTROL_AE_LOCK: false
CONTROL_AE_MODE: 1
CONTROL_AE_PRECAPTURE_TRIGGER: 0
CONTROL_AE_REGIONS: [Landroid.hardware.camera2.params.MeteringRectangle;@1ba1bf6 (x:0, y:0, w:3264, h:2448, wt:0)
CONTROL_AE_TARGET_FPS_RANGE: [15, 30]
CONTROL_AF_MODE: 4
CONTROL_AF_REGIONS: [Landroid.hardware.camera2.params.MeteringRectangle;@7070bf7 (x:0, y:0, w:0, h:0, wt:0)
CONTROL_AF_TRIGGER: 0
CONTROL_AWB_LOCK: false
CONTROL_AWB_MODE: 1
CONTROL_AWB_REGIONS: [Landroid.hardware.camera2.params.MeteringRectangle;@baf8a64 (x:0, y:0, w:3264, h:2448, wt:0)
CONTROL_CAPTURE_INTENT: 2
CONTROL_EFFECT_MODE: 0
CONTROL_ENABLE_ZSL: null
CONTROL_MODE: 1
CONTROL_POST_RAW_SENSITIVITY_BOOST: 100
CONTROL_SCENE_MODE: 1
CONTROL_VIDEO_STABILIZATION_MODE: 0
DISTORTION_CORRECTION_MODE: null
EDGE_MODE: 2
FLASH_MODE: 0
HOT_PIXEL_MODE: 2
JPEG_GPS_LOCATION: Location[null 0.000000,0.000000 hAcc=??? t=?!? et=?!? alt=0.0 vAcc=??? sAcc=??? bAcc=???]
JPEG_ORIENTATION: 90
JPEG_QUALITY: 100
JPEG_THUMBNAIL_QUALITY: 100
JPEG_THUMBNAIL_SIZE: 512x384
LENS_APERTURE: 1.9
LENS_FILTER_DENSITY: 0.0
LENS_FOCAL_LENGTH: 2.9
LENS_FOCUS_DISTANCE: -1.0
LENS_OPTICAL_STABILIZATION_MODE: 0
NOISE_REDUCTION_MODE: 2
REPROCESS_EFFECTIVE_EXPOSURE_FACTOR: null
SCALER_CROP_REGION: Rect(0, 0 - 3264, 2448)
SENSOR_EXPOSURE_TIME: 0
SENSOR_FRAME_DURATION: 33333333
SENSOR_SENSITIVITY: 0
SENSOR_TEST_PATTERN_DATA: null
SENSOR_TEST_PATTERN_MODE: 0
SHADING_MODE: 2
STATISTICS_FACE_DETECT_MODE: 0
STATISTICS_HOT_PIXEL_MAP_MODE: false
STATISTICS_LENS_SHADING_MAP_MODE: 0
STATISTICS_OIS_DATA_MODE: null
TONEMAP_CURVE: null
TONEMAP_GAMMA: null
TONEMAP_MODE: 2
TONEMAP_PRESET_CURVE: null

CaptureRequest Manual:

COLOR_CORRECTION_ABERRATION_MODE: 0
COLOR_CORRECTION_GAINS: null
COLOR_CORRECTION_MODE: 2
COLOR_CORRECTION_TRANSFORM: null
CONTROL_AE_ANTIBANDING_MODE: 3
CONTROL_AE_EXPOSURE_COMPENSATION: 0
CONTROL_AE_LOCK: false
CONTROL_AE_MODE: 0
CONTROL_AE_PRECAPTURE_TRIGGER: 0
CONTROL_AE_REGIONS: [Landroid.hardware.camera2.params.MeteringRectangle;@1101852 (x:0, y:0, w:3264, h:2448, wt:0)
CONTROL_AE_TARGET_FPS_RANGE: [15, 30]
CONTROL_AF_MODE: 4
CONTROL_AF_REGIONS: [Landroid.hardware.camera2.params.MeteringRectangle;@caf8723 (x:0, y:0, w:0, h:0, wt:0)
CONTROL_AF_TRIGGER: 0
CONTROL_AWB_LOCK: false
CONTROL_AWB_MODE: 1
CONTROL_AWB_REGIONS: [Landroid.hardware.camera2.params.MeteringRectangle;@9fb6420 (x:0, y:0, w:3264, h:2448, wt:0)
CONTROL_CAPTURE_INTENT: 2
CONTROL_EFFECT_MODE: 0
CONTROL_ENABLE_ZSL: null
CONTROL_MODE: 1
CONTROL_POST_RAW_SENSITIVITY_BOOST: 100
CONTROL_SCENE_MODE: 1
CONTROL_VIDEO_STABILIZATION_MODE: 0
DISTORTION_CORRECTION_MODE: null
EDGE_MODE: 2
FLASH_MODE: 0
HOT_PIXEL_MODE: 2
JPEG_GPS_LOCATION: Location[null 0.000000,0.000000 hAcc=??? t=?!? et=?!? alt=0.0 vAcc=??? sAcc=??? bAcc=???]
JPEG_ORIENTATION: 90
JPEG_QUALITY: 100
JPEG_THUMBNAIL_QUALITY: 100
JPEG_THUMBNAIL_SIZE: 512x384
LENS_APERTURE: 4.0
LENS_FILTER_DENSITY: 0.0
LENS_FOCAL_LENGTH: 2.9
LENS_FOCUS_DISTANCE: -1.0
LENS_OPTICAL_STABILIZATION_MODE: 0
NOISE_REDUCTION_MODE: 2
REPROCESS_EFFECTIVE_EXPOSURE_FACTOR: null
SCALER_CROP_REGION: Rect(0, 0 - 3264, 2448)
SENSOR_EXPOSURE_TIME: 33333335
SENSOR_FRAME_DURATION: 333333350
SENSOR_SENSITIVITY: 300
SENSOR_TEST_PATTERN_DATA: null
SENSOR_TEST_PATTERN_MODE: 0
SHADING_MODE: 2
STATISTICS_FACE_DETECT_MODE: 0
STATISTICS_HOT_PIXEL_MAP_MODE: false
STATISTICS_LENS_SHADING_MAP_MODE: 0
STATISTICS_OIS_DATA_MODE: null
TONEMAP_CURVE: null
TONEMAP_GAMMA: null
TONEMAP_MODE: 2
TONEMAP_PRESET_CURVE: null

CaptureResult Auto:

COLOR_CORRECTION_ABERRATION_MODE: 0
COLOR_CORRECTION_GAINS: RggbChannelVector{R:1.607422, G_even:1.000000, G_odd:1.000000, B:1.955078}
COLOR_CORRECTION_MODE: 2
COLOR_CORRECTION_TRANSFORM: ColorSpaceTransform([412/256, -231/256, 77/256], [-28/256, 285/256, 1/256], [16/256, -125/256, 365/256])
CONTROL_AE_ANTIBANDING_MODE: 3
CONTROL_AE_EXPOSURE_COMPENSATION: 0
CONTROL_AE_LOCK: false
CONTROL_AE_MODE: 1
CONTROL_AE_PRECAPTURE_TRIGGER: 0
CONTROL_AE_REGIONS: [Landroid.hardware.camera2.params.MeteringRectangle;@3640182 (x:0, y:0, w:3264, h:2448, wt:0)
CONTROL_AE_TARGET_FPS_RANGE: [15, 30]
CONTROL_AF_MODE: 4
CONTROL_AF_REGIONS: [Landroid.hardware.camera2.params.MeteringRectangle;@6967093 (x:0, y:0, w:0, h:0, wt:0)
CONTROL_AF_TRIGGER: 0
CONTROL_AWB_LOCK: false
CONTROL_AWB_MODE: 1
CONTROL_AWB_REGIONS: [Landroid.hardware.camera2.params.MeteringRectangle;@90ce8d0 (x:0, y:0, w:3264, h:2448, wt:0)
CONTROL_CAPTURE_INTENT: 2
CONTROL_EFFECT_MODE: 0
CONTROL_ENABLE_ZSL: null
CONTROL_MODE: 1
CONTROL_POST_RAW_SENSITIVITY_BOOST: 100
CONTROL_SCENE_MODE: 1
CONTROL_VIDEO_STABILIZATION_MODE: 0
DISTORTION_CORRECTION_MODE: null
EDGE_MODE: 2
FLASH_MODE: 0
HOT_PIXEL_MODE: 2
JPEG_GPS_LOCATION: null
JPEG_ORIENTATION: 90
JPEG_QUALITY: 100
JPEG_THUMBNAIL_QUALITY: 100
JPEG_THUMBNAIL_SIZE: 512x384
LENS_APERTURE: 1.9
LENS_FILTER_DENSITY: 0.0
LENS_FOCAL_LENGTH: 2.9
LENS_FOCUS_DISTANCE: 0.20428
LENS_OPTICAL_STABILIZATION_MODE: 0
NOISE_REDUCTION_MODE: 2
REPROCESS_EFFECTIVE_EXPOSURE_FACTOR: null
SCALER_CROP_REGION: Rect(0, 0 - 3264, 2448)
SENSOR_EXPOSURE_TIME: 41650000
SENSOR_FRAME_DURATION: 41700000
SENSOR_SENSITIVITY: 264
SENSOR_TEST_PATTERN_DATA: null
SENSOR_TEST_PATTERN_MODE: 0
SHADING_MODE: 2
STATISTICS_FACE_DETECT_MODE: 0
STATISTICS_HOT_PIXEL_MAP_MODE: false
STATISTICS_LENS_SHADING_MAP_MODE: 0
STATISTICS_OIS_DATA_MODE: null
TONEMAP_CURVE: null
TONEMAP_GAMMA: null
TONEMAP_MODE: 2
TONEMAP_PRESET_CURVE: null

CaptureResult Manual:

COLOR_CORRECTION_ABERRATION_MODE: 0
COLOR_CORRECTION_GAINS: RggbChannelVector{R:1.607422, G_even:1.000000, G_odd:1.000000, B:1.959961}
COLOR_CORRECTION_MODE: 2
COLOR_CORRECTION_TRANSFORM: ColorSpaceTransform([412/256, -233/256, 77/256], [-28/256, 283/256, 1/256], [17/256, -126/256, 365/256])
CONTROL_AE_ANTIBANDING_MODE: 3
CONTROL_AE_EXPOSURE_COMPENSATION: 0
CONTROL_AE_LOCK: false
CONTROL_AE_MODE: 0
CONTROL_AE_PRECAPTURE_TRIGGER: 0
CONTROL_AE_REGIONS: [Landroid.hardware.camera2.params.MeteringRectangle;@25d9738 (x:0, y:0, w:3264, h:2448, wt:0)
CONTROL_AE_TARGET_FPS_RANGE: [15, 30]
CONTROL_AF_MODE: 4
CONTROL_AF_REGIONS: [Landroid.hardware.camera2.params.MeteringRectangle;@33ca311 (x:0, y:0, w:0, h:0, wt:0)
CONTROL_AF_TRIGGER: 0
CONTROL_AWB_LOCK: false
CONTROL_AWB_MODE: 1
CONTROL_AWB_REGIONS: [Landroid.hardware.camera2.params.MeteringRectangle;@aa6cc76 (x:0, y:0, w:3264, h:2448, wt:0)
CONTROL_CAPTURE_INTENT: 2
CONTROL_EFFECT_MODE: 0
CONTROL_ENABLE_ZSL: null
CONTROL_MODE: 1
CONTROL_POST_RAW_SENSITIVITY_BOOST: 100
CONTROL_SCENE_MODE: 1
CONTROL_VIDEO_STABILIZATION_MODE: 0
DISTORTION_CORRECTION_MODE: null
EDGE_MODE: 2
FLASH_MODE: 0
HOT_PIXEL_MODE: 2
JPEG_GPS_LOCATION: null
JPEG_ORIENTATION: 90
JPEG_QUALITY: 100
JPEG_THUMBNAIL_QUALITY: 100
JPEG_THUMBNAIL_SIZE: 512x384
LENS_APERTURE: 1.9
LENS_FILTER_DENSITY: 0.0
LENS_FOCAL_LENGTH: 2.9
LENS_FOCUS_DISTANCE: 1.7726043
LENS_OPTICAL_STABILIZATION_MODE: 0
NOISE_REDUCTION_MODE: 2
REPROCESS_EFFECTIVE_EXPOSURE_FACTOR: null
SCALER_CROP_REGION: Rect(0, 0 - 3264, 2448)
SENSOR_EXPOSURE_TIME: 33333335
SENSOR_FRAME_DURATION: 333333000
SENSOR_SENSITIVITY: 300
SENSOR_TEST_PATTERN_DATA: null
SENSOR_TEST_PATTERN_MODE: 0
SHADING_MODE: 2
STATISTICS_FACE_DETECT_MODE: 0
STATISTICS_HOT_PIXEL_MAP_MODE: false
STATISTICS_LENS_SHADING_MAP_MODE: 0
STATISTICS_OIS_DATA_MODE: null
TONEMAP_CURVE: null
TONEMAP_GAMMA: null
TONEMAP_MODE: 2
TONEMAP_PRESET_CURVE: null

Thank you in advance


Solution

  • I don't see anything obviously wrong here - the difference in your exposure values is small enough (~10% brightness difference expected) that it shouldn't cause a blown-out image.

    Have you tried using another manual-control camera app (like OpenCamera) to see if that works correctly?

    It's also possible there's a weird device bug here, which might be related to the output targets you've set up for your session. Do you have a single, low-resolution output (< 1080p) set up currently? If you do, can you try a higher resolution and see what happens then?