Stay organized with collections Save and categorize content based on your preferences.

ImageAnalysis

@RequiresApi(value = 21)
public final class ImageAnalysis extends UseCase


A use case providing CPU accessible images for an app to perform image analysis on.

ImageAnalysis acquires images from the camera via an ImageReader. Each image is provided to an ImageAnalysis.Analyzer function which can be implemented by application code, where it can access image data for application analysis via an ImageProxy.

The application is responsible for calling close to close the image. Failing to close the image will cause future images to be stalled or dropped depending on the backpressure strategy.

Summary

Nested types

public interface ImageAnalysis.Analyzer

Interface for analyzing images.

public final class ImageAnalysis.Builder implements ExtendableBuilder

Builder for a ImageAnalysis.

Constants

static final int

ImageAnalysis.Analyzer option for returning the original coordinates.

static final int

Images sent to the analyzer will have RGBA format.

static final int

Images sent to the analyzer will have YUV format.

static final int

Block the producer from generating new images.

static final int

Only deliver the latest image to the analyzer, dropping images as they arrive.

Public methods

void

Removes a previously set analyzer.

@Nullable Executor

Returns the executor that will be used for background tasks.

int

Returns the mode with which images are acquired from the image producer.

int

Returns the number of images available to the camera pipeline, including the image being analyzed, for the STRATEGY_BLOCK_PRODUCER backpressure mode.

int

Gets output image format.

@Nullable ResolutionInfo

Gets resolution related information of the ImageAnalysis.

int

Returns the rotation of the intended target for images.

boolean

Checks if output image rotation is enabled.

void
setAnalyzer(
    @NonNull Executor executor,
    @NonNull ImageAnalysis.Analyzer analyzer
)

Sets an analyzer to receive and analyze images.

void
setTargetRotation(int rotation)

Sets the target rotation.

void

Sets the target rotation in degrees.

@NonNull String

Constants

COORDINATE_SYSTEM_ORIGINAL

public static final int COORDINATE_SYSTEM_ORIGINAL = 0

ImageAnalysis.Analyzer option for returning the original coordinates.

Use this option if no additional transformation is needed by the Analyzer implementation. By using this option, CameraX will pass null to updateTransform.

OUTPUT_IMAGE_FORMAT_RGBA_8888

public static final int OUTPUT_IMAGE_FORMAT_RGBA_8888 = 2

Images sent to the analyzer will have RGBA format.

All ImageProxy sent to analyze will have format RGBA_8888

The output order is a single-plane with the order of R, G, B, A in increasing byte index in the java.nio.ByteBuffer. The java.nio.ByteBuffer is retrieved from getBuffer.

OUTPUT_IMAGE_FORMAT_YUV_420_888

public static final int OUTPUT_IMAGE_FORMAT_YUV_420_888 = 1

Images sent to the analyzer will have YUV format.

All ImageProxy sent to analyze will have format YUV_420_888

STRATEGY_BLOCK_PRODUCER

public static final int STRATEGY_BLOCK_PRODUCER = 1

Block the producer from generating new images.

Once the producer has produced the number of images equal to the image queue depth, and none have been closed, the producer will stop producing images. Note that images may be queued internally and not be delivered to the analyzer until the last delivered image has been closed with close. These internally queued images will count towards the total number of images that the producer can provide at any one time.

When the producer stops producing images, it may also stop producing images for other use cases, such as Preview, so it is important for the analyzer to keep up with frame rate, on average. Failure to keep up with frame rate may lead to jank in the frame stream and a diminished user experience. If more time is needed for analysis on some frames, consider increasing the image queue depth with setImageQueueDepth.

STRATEGY_KEEP_ONLY_LATEST

public static final int STRATEGY_KEEP_ONLY_LATEST = 0

Only deliver the latest image to the analyzer, dropping images as they arrive.

This strategy ignores the value set by setImageQueueDepth. Only one image will be delivered for analysis at a time. If more images are produced while that image is being analyzed, they will be dropped and not queued for delivery. Once the image being analyzed is closed by calling close, the next latest image will be delivered.

Internally this strategy may make use of an internal Executor to receive and drop images from the producer. A performance-tuned executor will be created internally unless one is explicitly provided by setBackgroundExecutor. In order to ensure smooth operation of this backpressure strategy, any user supplied Executor must be able to quickly respond to tasks posted to it, so setting the executor manually should only be considered in advanced use cases.

Public methods

clearAnalyzer

public void clearAnalyzer()

Removes a previously set analyzer.

This will stop data from streaming to the ImageAnalysis.

getBackgroundExecutor

@ExperimentalUseCaseApi
public @Nullable Executor getBackgroundExecutor()

Returns the executor that will be used for background tasks.

Returns
@Nullable Executor

The Executor provided to setBackgroundExecutor. If no Executor has been provided, then returns null

getBackpressureStrategy

public int getBackpressureStrategy()

Returns the mode with which images are acquired from the image producer.

The backpressure strategy is set when constructing an ImageAnalysis instance using setBackpressureStrategy. If not set, it defaults to STRATEGY_KEEP_ONLY_LATEST.

Returns
int

The backpressure strategy applied to the image producer.

getImageQueueDepth

public int getImageQueueDepth()

Returns the number of images available to the camera pipeline, including the image being analyzed, for the STRATEGY_BLOCK_PRODUCER backpressure mode.

The image queue depth is set when constructing an ImageAnalysis instance using setImageQueueDepth. If not set, and this option is used by the backpressure strategy, the default will be a queue depth of 6 images.

Returns
int

The image queue depth for the STRATEGY_BLOCK_PRODUCER backpressure mode.

getOutputImageFormat

public int getOutputImageFormat()

Gets output image format.

The returned image format will be OUTPUT_IMAGE_FORMAT_YUV_420_888 or OUTPUT_IMAGE_FORMAT_RGBA_8888.

Returns
int

output image format.

getResolutionInfo

public @Nullable ResolutionInfo getResolutionInfo()

Gets resolution related information of the ImageAnalysis.

The returned ResolutionInfo will be expressed in the coordinates of the camera sensor. It will be the same as the resolution of the ImageProxy received from analyze.

The resolution information might change if the use case is unbound and then rebound or setTargetRotation is called to change the target rotation setting. The application needs to call getResolutionInfo again to get the latest ResolutionInfo for the changes.

Returns
@Nullable ResolutionInfo

the resolution information if the use case has been bound by the bindToLifecycle API, or null if the use case is not bound yet.

getTargetRotation

public int getTargetRotation()

Returns the rotation of the intended target for images.

The rotation can be set when constructing an ImageAnalysis instance using setTargetRotation, or dynamically by calling setTargetRotation or setTargetRotationDegrees. If not set, the target rotation defaults to the value of getRotation of the default display at the time the use case is created. The use case is fully created once it has been attached to a camera.

Returns
int

The rotation of the intended target for images.

isOutputImageRotationEnabled

public boolean isOutputImageRotationEnabled()

Checks if output image rotation is enabled. It returns false by default.

Returns
boolean

true if enabled, false otherwise.

setAnalyzer

public void setAnalyzer(
    @NonNull Executor executor,
    @NonNull ImageAnalysis.Analyzer analyzer
)

Sets an analyzer to receive and analyze images.

Setting an analyzer will signal to the camera that it should begin sending data. The stream of data can be stopped by calling clearAnalyzer.

Applications can process or copy the image by implementing the Analyzer. If frames should be skipped (no analysis), the analyzer function should return, instead of disconnecting the analyzer function completely.

Setting an analyzer function replaces any previous analyzer. Only one analyzer can be set at any time.

Parameters
@NonNull Executor executor

The executor in which the analyze will be run.

@NonNull ImageAnalysis.Analyzer analyzer

of the images.

setTargetRotation

public void setTargetRotation(int rotation)

Sets the target rotation.

This adjust the getRotationDegrees of the ImageProxy passed to analyze. The rotation value of ImageInfo will be the rotation, which if applied to the output image, will make the image match target rotation specified here.

While rotation can also be set via setTargetRotation, using setTargetRotation allows the target rotation to be set dynamically.

In general, it is best to use an android.view.OrientationEventListener to set the target rotation. This way, the rotation output to the Analyzer will indicate which way is down for a given image. This is important since display orientation may be locked by device default, user setting, or app configuration, and some devices may not transition to a reverse-portrait display orientation. In these cases, use setTargetRotationDegrees to set target rotation dynamically according to the android.view.OrientationEventListener, without re-creating the use case. See setTargetRotationDegrees for more information.

When this function is called, value set by setTargetResolution will be updated automatically to make sure the suitable resolution can be selected when the use case is bound.

If not set here or by configuration, the target rotation will default to the value of getRotation of the default display at the time the use case is bound. To return to the default value, set the value to

context.getSystemService(WindowManager.class).getDefaultDisplay().getRotation();
Parameters
int rotation

Target rotation of the output image, expressed as one of ROTATION_0, ROTATION_90, ROTATION_180, or ROTATION_270.

setTargetRotationDegrees

public void setTargetRotationDegrees(int degrees)

Sets the target rotation in degrees.

In general, it is best to use an android.view.OrientationEventListener to set the target rotation. This way, the rotation output will indicate which way is down for a given image. This is important since display orientation may be locked by device default, user setting, or app configuration, and some devices may not transition to a reverse-portrait display orientation. In these cases, use setTargetRotationDegrees() to set target rotation dynamically according to the android.view.OrientationEventListener, without re-creating the use case. The sample code is as below:

public class CameraXActivity extends AppCompatActivity {

    private OrientationEventListener mOrientationEventListener;

    
    protected void onStart() {
        super.onStart();
        if (mOrientationEventListener == null) {
            mOrientationEventListener = new OrientationEventListener(this) {
                
                public void onOrientationChanged(int orientation) {
                    if (orientation == OrientationEventListener.ORIENTATION_UNKNOWN) {
                        return;
                    }
                    mImageAnalysis.setTargetRotationDegrees(orientation);
                }
            };
        }
        mOrientationEventListener.enable();
    }

    
    protected void onStop() {
        super.onStop();
        mOrientationEventListener.disable();
    }
}

setTargetRotationDegrees() cannot rotate the camera image to an arbitrary angle, instead it maps the angle to one of ROTATION_0, ROTATION_90, ROTATION_180 and ROTATION_270 as the input of setTargetRotation. The rule is as follows:

If the input degrees is not in the range [0..359], it will be converted to the equivalent degrees in the range [0..359]. And then take the following mapping based on the input degrees.

degrees >= 315 || degrees <45 ->ROTATION_0

degrees >= 225 &°rees; <315 ->ROTATION_90

degrees >= 135 &°rees; <225 ->ROTATION_180

degrees >= 45 &°rees; <135 ->ROTATION_270

The rotation value can be obtained by getTargetRotation. This means the rotation previously set by setTargetRotation will be overridden by setTargetRotationDegrees(int), and vice versa.

When this function is called, value set by setTargetResolution will be updated automatically to make sure the suitable resolution can be selected when the use case is bound.

Parameters
int degrees

Desired rotation degree of the output image.

toString

public @NonNull String toString()