使用位图时,Android MLKit 人脸检测未检测到人脸
Posted
技术标签:
【中文标题】使用位图时,Android MLKit 人脸检测未检测到人脸【英文标题】:Android MLKit face detection not detecting faces when using Bitmap 【发布时间】:2021-08-27 19:46:52 【问题描述】:我有一个 XR 应用程序,其中显示屏显示摄像头(后部)馈送。因此,捕获屏幕与捕获相机馈送几乎相同...... 因此,我截取屏幕截图(位图),然后尝试使用 Google MLKit 检测其中的人脸。
我正在关注official guide 来检测人脸。
为此,我首先启动我的面部检测器:
FaceDetector detector;
public MyFaceDetector()
FaceDetectorOptions realTimeOpts =
new FaceDetectorOptions.Builder()
.setContourMode(FaceDetectorOptions.CONTOUR_MODE_ALL)
.build();
detector = FaceDetection.getClient(realTimeOpts);
然后我有一个传入位图的函数。我首先将位图转换为字节数组。我这样做是因为InputImage.fromBitmap
非常慢,而且 MLKit 实际上告诉我应该使用字节数组:
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 85, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream .toByteArray();
接下来,我制作 Bitmap 的可变副本(以便我可以在其上绘制),并设置一个 Canvas 对象,以及在 Bitmap 上绘制时将使用的颜色:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inMutable = true;
Bitmap bmp = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length, options);
Canvas canvas = new Canvas(bmp);
Paint p = new Paint();
p.setColor(Color.RED);
所有设置完成后,我使用字节数组创建了一个InputImage
(由 FaceDetector 使用):
InputImage image = InputImage.fromByteArray(byteArray, bmp.getWidth(), bmp.getHeight(),0, InputImage.IMAGE_FORMAT_NV21);
注意图像格式...有一个InputImage.IMAGE_FORMAT_BITMAP
,但使用它会引发 IllegalArgumentException。无论如何,我接下来尝试处理 Bitmap,检测人脸,用之前定义的颜色填充每个检测到的人脸,然后将 Bitmap 保存到磁盘:
Task<List<Face>> result = detector.process(image).addOnSuccessListener(
new OnSuccessListener<List<Face>>()
@Override
public void onSuccess(List<Face> faces)
Log.e("FACE DETECTION APP", "NUMBER OF FACES: " + faces.size());
Thread processor = new Thread(new Runnable()
@Override
public void run()
for (Face face : faces)
Rect destinationRect = face.getBoundingBox();
canvas.drawRect(destinationRect, p);
canvas.save();
Log.e("FACE DETECTION APP", "WE GOT SOME FACCES!!!");
File file = new File(someFilePath);
try
FileOutputStream fOut = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.JPEG, 85, fOut);
fOut.flush();
fOut.close();
catch (Exception e)
e.printStackTrace();
);
processor.start();
)
.addOnFailureListener(
new OnFailureListener()
@Override
public void onFailure(@NonNull Exception e)
// Task failed with an exception
// ...
);
虽然此代码运行(即没有异常)并且位图已正确写入磁盘,但从未检测到任何人脸 (faces.size() is always 0
)。我试过旋转图像。我试过改变位图的质量。我已经尝试使用和不使用线程来处理任何检测到的面孔。我已经尝试了所有我能想到的。
有人有什么想法吗?
【问题讨论】:
ML 套件输入图像。 fromByteArray 仅支持 yv12 和 nv21 格式。您需要将位图转换为其中一种格式,以便 ML 套件管道进行处理。此外,如果您拥有的原始图像是位图,您可能只使用 InputImage.fromBitmap 来构造 InputImage。它不应该比您当前的方法慢。 【参考方案1】:ML 套件输入图像。 fromByteArray 仅支持 yv12 和 nv21 格式。您需要将位图转换为其中一种格式,以便 ML 套件管道进行处理。此外,如果您拥有的原始图像是位图,您可能只使用 InputImage.fromBitmap 来构造 InputImage。它不应该比您当前的方法慢。
【讨论】:
【参考方案2】:我在使用 ImageInput.fromMediaImage(..., ...) 时遇到了同样的问题
override fun analyze(image: ImageProxy)
val mediaImage: Image = image.image.takeIf it != null ?: run
image.close()
return
val inputImage = InputImage.fromMediaImage(mediaImage, image.imageInfo.rotationDegrees)
// TODO: Your ML Code
点击此处了解更多详情 https://developers.google.com/ml-kit/vision/image-labeling/android
【讨论】:
以上是关于使用位图时,Android MLKit 人脸检测未检测到人脸的主要内容,如果未能解决你的问题,请参考以下文章
使用 CameraX 时,前置摄像头的 Facebase MLKit 人脸检测失败
MLKit 旋转面部图像使其笔直(iOS 和 Android)
android mobile vision api自定义检测器未检测到人脸