当前,我们正在使用 Firebase ML Kit来检测相机发送的帧中的人脸的项目。 我们想测试预训练模型在我们自己的测试数据上的工作情况,然后尝试编写一个测试,以在所有测试图像上运行该模型,然后我们可以计算出某种准确性。
现在,我们正在运行一个Android应用程序,并尝试使用 Robolectric 进行测试,并使用 Android sdk 28 进行测试。我们一张一张地读取图像,并将它们转换为字节数组,从它们创建FirebaseVisionImages,然后调用time_zone = query_from_db
tz = datetime.strptime(time_zone, "%z")
datetime_now = datetime.now(tz.tzinfo)
。
问题是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()
解决了该问题。不知道为什么,但是每当我尝试从ByteArray运行模型时,它都会“卡住”,但是从位图运行时,它运行良好!
答案 0 :(得分:0)
问题在于所有ml推断都在工作线程中发生,并且Robolectric为UI操作和测试代码共享一个线程。
您可以调用“ shadowOf(getMainLooper())。idle();”执行在测试用例中发布到工作线程的任务。