Search code examples
androidandroid-cameraandroid-camera2

Camera2: setting optical stabilization does nothing (OIS)


I have Samsung S10 which has video stabilization feature. Using system default Camera app I can see the difference when it's enabled and not: first if it's enabled than there will be some zoomed preview, second it is noticeable during device movements.

enter image description here

I tried to enable stabilization in my own app using Camera2 API, also FullHD and rear camera (the same as with default system app).

I tested that characteristics.get(CameraCharacteristics.CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES) returns only CONTROL_VIDEO_STABILIZATION_MODE_OFF so this is not supported.

But characteristics.get(CameraCharacteristics.LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION) has CameraMetadata.LENS_OPTICAL_STABILIZATION_MODE_ON

So I as I understand this is exactly the option to enable video stabilization (optical), should be the same as in default system app.

But when I do the next for camera capture session configuration it doesn't change anything, no zoomed preview (as it was with default system camera app) and no changes during movement, so the video is the same in my app as it would have been in default camera app with disabled video stabilization

captureRequestBuilder.set(
    CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE,
    CameraMetadata.LENS_OPTICAL_STABILIZATION_MODE_ON
)

So setting this parameter doesn't change anything.

Why video stabilization works in default system camera app but not in my own app using Camera2 API?


Solution

  • There are two types of stabilization that camera devices can support on Android

    • Video stabilization (Electronic Image Stabilization / EIS): This is done as a post-processing step after image capture, by analyzing camera motion between frames and compensating for it by shifting the image a bit. That's why there's a zoom-in effect, to give some room for that shift/warp. This stabilizes video over time, making consecutive image frames stable. The controls for this are accessed via the CONTROL_VIDEO_STABILIZATION_MODE setting, as you've discovered.
    • Optical image stabilization (OIS): This is a set of high-speed gyros and magnets around the camera lens, which rapidly shifts the lens (or sometimes the sensor) as the camera moves to stabilize the image. The amount of motion is limited, but it's very rapid, so it stabilizes images during a single exposure, not across multiple frames. So it's generally only useful for snapshots, not video. This is accessed via SENSOR_OPTICAL_STABILIZATION_MODE.

    Unfortunately, many Android manufacturers do not make their EIS implementations available to applications outside of their default camera app. That's because making a good EIS implementation is complicated, and the manufacturers want to limit it to only working with their own app's recording mode (which is a single target to fix). For example, EIS for recorded video often applies a 1-second delay so that it can adjust image transforms for future frames, in addition to past ones, which is hard to do for real-time apps. Some manufacturers make simpler algorithms visible, or otherwise manage to make EIS work for everyone, but for others, the device doesn't list support for EIS even when the built-in app uses it.

    Turning on OIS probably works fine - you'd only see an effect on long-exposure images, where they'll be blurry due to handshake when OIS off, but be sharp when OIS is on. Since it's a self-contained hardware unit, it's easy for manufacturers to make the on-switch available to everyone.