【问题标题】:How to feed CameraX's ImageProxy to tensorflow lite model如何将 CameraX 的 ImageProxy 提供给 tensorflow lite 模型
【发布时间】:2021-07-28 15:39:12
【问题描述】:

这是我的代码:

imageAnalysis.setAnalyzer(ThreadManager.getInstance().cameraExecutor, new ImageAnalysis.Analyzer() {
                @SuppressLint("UnsafeOptInUsageError")
                @Override
                public void analyze(@NonNull ImageProxy image) {
                    int rotationDegrees = image.getImageInfo().getRotationDegrees();
                    // insert your code here.

                    Log.d(TAG, "starting");

                    Bitmap bmp = Bitmap.createBitmap(270,480, Bitmap.Config.ARGB_8888);
                    conv.yuvToRgb(image.getImage(), bmp);



                    ByteBuffer buffer = ByteBuffer.allocate(3*270*480*4);

                    int pixelVals[] = new int[480*270*3];

                    bmp.getPixels(pixelVals, 0, bmp.getWidth(), 0, 0, bmp.getWidth(), bmp.getHeight());

                    int itr = 0;

                    for(int i=0;i<480;++i)
                    {
                        for(int j=0;j<270;++j)
                        {
                            int x = pixelVals[itr++];

                            float red = ((x >> 16) & 0xFF) / 256.f;
                            float green = ((x >> 8) & 0xFF) / 256.f;
                            float blue = (x & 0xFF) / 256.f;

                            buffer.putFloat(red);
                            buffer.putFloat(green);
                            buffer.putFloat(blue);
                        }
                    }

                    float[][] output = new float[1][1];

                

                    tflite.run(buffer, output);

                    float out = output[0][0];

                    ContextCompat.getMainExecutor(MainActivity.this).execute(new Runnable() {
                        @Override
                        public void run() {
                            scoretv.setText(out+"");
                            Log.d(TAG, "updating");
                        }
                    });

                    image.close();
                }
            });

问题是tflite.run() 总是返回相同的输出,不管输入是什么。我已经在我的电脑上使用 python 脚本测试了我的.tflite 模型,它可以正常工作。

我不确定buffer 是否在调用run() 时保存正确转换的图像,但使用调试器我验证它至少看起来像正确的图像数据,当然不应该每次都给出相同的结果。 (缓冲区数据改变,所以输出也应该改变)

此外,当检测到对象时,此模型应输出更接近 1.0 的浮点数,而在没有检测到对象时应输出更接近 0.0 的浮点数。如果图像在转换过程中损坏,模型应该输出低值(通过我的电脑上的测试确认)。

模型总是输出 0.7001277

编辑: 这是经过编辑的版本,原始问题现已过时。抱歉,我可能应该再等一会儿再问问题。

【问题讨论】:

  • 为什么要用RGB_565?我问这是否是故意的,否则您可以轻松使用 TensorFlow Lite 支持库
  • 不,事实上我不知道我应该使用什么位图选项,但这是唯一一个具有“RGB”的选项,而不是 ARGB 的 RGBA @Farmaker

标签: java android keras android-bitmap tensorflow-lite


【解决方案1】:

请先查看原模型的图片格式。 Java端的图像格式和数据模式应该和Python训练阶段的一致。

【讨论】:

    【解决方案2】:

    因为我没有看到你的 yuvToRgb 方法,所以之后我会给你一些提示。所以首先把这个依赖放在你的 build.gradle 文件中

    实现'org.tensorflow:tensorflow-lite-support:0.2.0'

    这适用于 TensorFlow Lite 支持库。您可以找到很多信息here,这基本上就是我要在下面写的内容。所以有了这个库,你可以做很多事情,比如将位图转换为字节缓冲区。我们必须这样做,因为 ImageProcessor 现在无法处理从ImageAnalysis of CameraX 输出的 YUV 格式的 media.Image。我希望这会在几个月内改变,我们可以直接将图像提供给支持库。检查以下:

     //Convert image to Bitmap
        Bitmap bitmap = imageToRGB(image, image.getWidth(), image.getHeight());
        Log.v("TFLITE_w", String.valueOf(image.getWidth()));
        Log.v("TFLITE_h", String.valueOf(image.getHeight()));
    
        //Loads bitmap into a TensorImage.
        int imageTensorIndex = 0;
        int[] imageShape = tfLite.getInputTensor(imageTensorIndex).shape();
        DataType imageDataType = tfLite.getInputTensor(imageTensorIndex).dataType();
        //Log.v("TFLITE", String.valueOf(imageShape[0]));
    
        TensorImage tensorImage = new TensorImage(imageDataType);
        tensorImage.load(bitmap);
    
        ImageProcessor imageProcessor = new ImageProcessor.Builder()
                .add(new ResizeOp(inputSize, inputSize, ResizeOp.ResizeMethod.BILINEAR))
                //.add(new Rot90Op(numRotation))
                .build();
                        /*.add(new ResizeWithCropOrPadOp(cropSize, cropSize))
                        // To get the same inference results as lib_task_api, which is built on top of the Task
                        // Library, use ResizeMethod.BILINEAR.
                        .add(new ResizeOp(480, 640, ResizeOp.ResizeMethod.BILINEAR))
                        .add(new Rot90Op(numRotation))
                        .add(getPreprocessNormalizeOp())
                        .build();*/
    
        TensorImage tensorImageInput = imageProcessor.process(tensorImage);
    
        long endTimeForLoadImage = SystemClock.uptimeMillis();
        Trace.endSection();
        Log.v(TAG, "Time-Cost to load the image: " + (endTimeForLoadImage - startTimeForLoadImage));
        Trace.endSection(); // preprocessBitmap
    
        float[][] output = new float[1][1];
        tflite.run(tensorImageInput.buffer, output);
    

    对于 ImageProcessor,您可以查看 this 以找出您想要的选项

    对于 imageToRGB 方法,如果您的方法不起作用,您可以看到 this link

    如果您需要更多帮助,请联系我

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-04-14
      • 1970-01-01
      • 1970-01-01
      • 2018-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多