【问题标题】:How to most efficiently use and apply Android CameraX Image Analysis setTargetRotation如何最有效地使用和应用 Android CameraX 图像分析 setTargetRotation
【发布时间】:2021-07-15 09:05:10
【问题描述】:

类似于tutorial 中的内容,我正在使用代码初始化 CameraX 的图像分析用例:

ImageAnalysis imageAnalysis =
    new ImageAnalysis.Builder()
        .setTargetResolution(new Size(1280, 720))
        .setTargetRotation(Surface.ROTATION_90)
        .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
        .build();

imageAnalysis.setAnalyzer(executor, new ImageAnalysis.Analyzer() {
    @Override
    public void analyze(@NonNull ImageProxy image) {
        int rotationDegrees = image.getImageInfo().getRotationDegrees();
            // insert your code here.
        }
    });


cameraProvider.bindToLifecycle((LifecycleOwner) this, cameraSelector, imageAnalysis, preview);

我正在尝试使用setTargetRotation 方法,但我不清楚我应该如何将此旋转应用于输出图像,如文档中模糊描述的那样:

ImageInfo 的旋转值将是旋转,如果应用于输出图像,将使图像匹配此处指定的目标旋转。

如果我在上面显示的 analyze() 方法中设置断点,则在更改 setTargetRotation 值时图像对象不会旋转,因此我假设文档告诉我使用 getTargerRotation() 获取方向感觉这两段代码(构建器与分析器)是分开编码的,并且此信息可以在两者之间传递而无需实际应用任何旋转。我理解正确吗?这对我来说真的没有意义,因为setTargetResolution 方法实际上改变了通过 ImageProxy 发送的大小。我认为setTargetRotation 也应该应用所述旋转,但它似乎没有。

如果我的理解是正确的,那么在进入analyze 方法后,是否有一种最佳的有效方式来旋转这些ImageProxy 对象?现在我正在通过

转换为位图后这样做
Bitmap myImg = BitmapFactory.decodeResource(someInutStream);

Matrix matrix = new Matrix();
matrix.postRotate(30);

Bitmap rotated = Bitmap.createBitmap(myImg, 0, 0, myImg.getWidth(), myImg.getHeight(),
        matrix, true);

以上想法来自here,但我认为这不是最有效的方法。我敢肯定我也可以想出一种方法来转置数组,但这很快就会变得乏味和混乱。有没有办法设置 ImageAnalysis Builder 直接发送旋转后的 ImageProxy 而不必制作所有内容的位图?

【问题讨论】:

    标签: android android-camerax


    【解决方案1】:

    ImageInfo 的旋转值将是旋转,如果应用 到输出图像,将使图像匹配目标旋转 此处指定。

    理解定义的一个例子是假设目标旋转与设备的方向匹配。将返回的旋转应用于输出图像将导致图像是直立的,即匹配设备的方向。因此,如果设备处于其自然纵向位置,旋转后的输出图像也将处于该方向。

    输出图像 + 旋转值旋转 --> 直立输出图像

    CameraX 的文档包含一个关于旋转的部分,因为它可能是一个令人困惑的话题。您可以查看here

    回到你关于setTargetRotationImageAnalysis 用例的问题,它并不是要旋转传递给Analyzer 的图像,但它应该会影响图像的旋转信息,即@987654325 @。转换图像(旋转、裁剪等)可能是一项昂贵的操作,因此 CameraX 不会对分析帧执行任何修改,但它提供了所需的元数据来理解输出图像,然后可以与图像处理器一起使用的元数据分析框架。

    如果您需要旋转每个分析框架,使用Bitmap 方法是一种方法,但成本可能很高。另一种更高效的方法可能是在本机代码中进行。

    【讨论】:

    • 感谢@Husayn Hakeem 提供的信息。也许问如何旋转 ImageProxy 是错误的问题。为了避免昂贵的操作,理想情况下,我想要一些 API 调用,可以格式化在创建时支持 ImageProxy 的数组,类似于setTargetResolution 的情况。我的意思是,setTargetResolution 方法似乎可以控制这个数组的维度,而setTargetRotation 没有。如果我可以setTargetResolution(144,176) 而不是setTargetResolution(176, 144) 我真的不需要做任何昂贵的“轮换”。
    • 我浏览了您发送的链接,也许我对 Kotlin 的理解不够好,但我也没有看到“应用轮换”的任何实际实现,只是识别哪个应应用旋转。对于图像捕获用例,位图方法似乎完全可行,但对于图像分析和图像预览,我认为 CameraX 会有应用旋转的方法,不是吗?不应该有一些优化的本机代码用于在目标方向上流式传输图像吗?否则我们难道不希望数组的原始方向以外的所有方向都以较慢的 fps 运行吗?
    • 只是为我的特定用例添加一些上下文。我们有一个经过“纵向”图像训练的预训练 TensorFlow Lite 模型。 analyze 方法给出的ImageProxy 以“横向”出现,因此我们需要转换为位图并旋转,然后再将其输入模型。这显然大大降低了我们处理图像的速度,所以我一直在寻找一种方法来改变支持数组的形状,而不是转换为位图并在事后旋转。当然,另一种选择是重新训练 TF Lite 模型,但这是一项非常昂贵的操作。
    • 关于您为setTargetResolution 提供的示例,它们不会影响图像的旋转,而只会影响图像的大小,因此您不会获得纵向/高大的图像,而是结束加上横向/宽幅图像,反之亦然。
    • “对于图像分析和图像预览,我认为 CameraX 会有应用旋转的方法”。不,目前不是,可能出于我在回答中提到的相同原因,因为它很昂贵。这很可能会在未来添加,但当 CameraX 将稳定其基本功能/用例时。
    猜你喜欢
    • 2020-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多