1

目前,我们正在开发一个项目,使用Firebase ML Kit 来检测相机发送的帧中的人脸。我们想测试预训练模型在我们自己的测试数据上的效果如何,并且我们尝试编写一个测试来在所有测试图像上运行模型,然后我们可以计算某种准确度

现在我们正在运行一个 Android 应用程序并尝试使用Robolectric进行测试,并使用Android sdk 28运行测试。我们一一读取图像并将它们转换为字节数组,从中创建 FirebaseVisionImages 然后调用detectInFace(image).

问题是detectInFace(image)使用回调函数返回结果。我们检查了回调函数是否被调用过,但似乎没有。我们试图通过使用等待任务完成,await(task)但事实证明任务似乎永远不会完成。

有谁知道为什么回调函数从未被调用/似乎从未被调用?有没有其他方法可以使用测试套件获得自定义图像的准确性?

我们拥有的代码:

 FirebaseApp.initializeApp(InstrumentationRegistry.getInstrumentation().targetContext)
 val faceDetectorOptions: FirebaseVisionFaceDetectorOptions = FirebaseVisionFaceDetectorOptions.Builder()
            .setPerformanceMode(FirebaseVisionFaceDetectorOptions.FAST)
            .setContourMode(FirebaseVisionFaceDetectorOptions.NO_CONTOURS)
            .enableTracking()
            .build()

        // facedetector object with specified settings
        val faceDetector =
            FirebaseVision.getInstance()
                .getVisionFaceDetector(faceDetectorOptions)

        val metadata = FirebaseVisionImageMetadata.Builder()
            .setWidth(720) // 480x360 is typically sufficient for
            .setHeight(720) // image recognition
            .setFormat(FirebaseVisionImageMetadata.IMAGE_FORMAT_NV21)
            .setRotation(FirebaseVisionImageMetadata.ROTATION_0)
            .build()

// Convert image to byteArray
        val inputStream =
          InstrumentationRegistry.getInstrumentation().targetContext.getAssets()?.open("testImage1.jpg")
        val bufferedStream = BufferedInputStream(inputStream);
        val bmp = BitmapFactory.decodeStream(bufferedStream)
        val outstream = ByteArrayOutputStream()
        bmp.compress(Bitmap.CompressFormat.PNG, 100, outstream)
        val bytearr = outstream.toByteArray()

      // detect the face in the image
        val task =  faceDetector.detectInImage(FirebaseVisionImage.fromByteArray(bytearr, metadata))
                .addOnSuccessListener { faces ->
                   // This seems to never be called
                }
                .addOnFailureListener {
                    // this also is never called
                }
        }
    } 

编辑:感谢您的回答和建议,最后我通过使用FirebaseVisionImage.fromBitmap()而不是FirebaseVisionImage.fromByteArray(). 不知道为什么,但是每当我尝试从 ByteArray 运行模型时,它就会“卡住”,但是从位图运行它时效果很好!

4

1 回答 1

1

问题是所有的机器学习推理都发生在一个工作线程中,而 Robolectric 为 UI 操作和测试代码共享一个线程。

你可以调用“shadowOf(getMainLooper()).idle();” 在测试用例中执行发布到工作线程的任务。

http://robolectric.org/blog/2019/06/04/paused-looper/

于 2020-05-14T05:42:21.177 回答