我正在尝试使用谷歌视觉 API 进行面部检测并添加面具(图形叠加(,问题是我在检测和添加后无法从相机获取 ouptut mask.so 到目前为止我已经从 github 尝试了这个解决方案,https://github.com/googlesamples/android-vision/issues/24,基于这个问题我添加了一个自定义检测器类,移动视觉 API - 连接新的检测器对象以继续帧处理。 并将其添加到mydetector类如何从灰度字节缓冲区图像创建位图?.
我的检测器类
class MyFaceDetector extends Detector<Face>
{
private Detector<Face> mDelegate;
MyFaceDetector(Detector<Face> delegate) {
mDelegate = delegate;
}
public SparseArray<Face> detect(Frame frame) {
// *** add your custom frame processing code here
ByteBuffer byteBuffer = frame.getGrayscaleImageData();
byte[] bytes = byteBuffer.array();
int w = frame.getMetadata().getWidth();
int h = frame.getMetadata().getHeight();
YuvImage yuvimage=new YuvImage(bytes, ImageFormat.NV21, w, h, null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
yuvimage.compressToJpeg(new Rect(0, 0, w, h), 100, baos); // Where 100 is the quality of the generated jpeg
byte[] jpegArray = baos.toByteArray();
Bitmap bitmap = BitmapFactory.decodeByteArray(jpegArray, 0, jpegArray.length);
Log.e("got bitmap","bitmap val " + bitmap);
return mDelegate.detect(frame);
}
public boolean isOperational() {
return mDelegate.isOperational();
}
public boolean setFocus(int id) {
return mDelegate.setFocus(id);
}
}
帧处理
public SparseArray<Face> detect(Frame frame)
{
// *** add your custom frame processing code here
ByteBuffer byteBuffer = frame.getGrayscaleImageData();
byte[] bytes = byteBuffer.array();
int w = frame.getMetadata().getWidth();
int h = frame.getMetadata().getHeight();
YuvImage yuvimage=new YuvImage(bytes, ImageFormat.NV21, w, h, null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
yuvimage.compressToJpeg(new Rect(0, 0, w, h), 100, baos); // Where 100 is the quality of the generated jpeg
byte[] jpegArray = baos.toByteArray();
Bitmap bitmap = BitmapFactory.decodeByteArray(jpegArray, 0, jpegArray.length);
Log.e("got bitmap","bitmap val " + bitmap);
return mDelegate.detect(frame);
}
我得到了一个旋转的位图,即没有我添加的蒙版(图形叠加(。如何获得带蒙版的相机输出。
提前谢谢。
简单的答案是:你不能。
为什么?NV21 ByteBuffer中的Android相机输出帧。并且您必须根据分隔位图中的地标点生成蒙版,然后连接它们。抱歉,这就是 Android Camera API 的工作方式。什么也做不了。您必须手动执行此操作。
另外,我不会获得相机预览,然后将其转换为YuvImage,然后转换为位图。该过程会消耗大量资源,并使预览非常非常慢。相反,我会使用这种方法,它会更快,并在内部旋转您的预览,这样您就不会浪费时间这样做:
outputFrame = new Frame.Builder().setImageData(mPendingFrameData, mPreviewSize.getWidth(), mPreviewSize.getHeight(), ImageFormat.NV21)
.setId(mPendingFrameId)
.setTimestampMillis(mPendingTimeMillis)
.setRotation(mRotation)
.build();
mDetector.receiveFrame(outputFrame);
所有代码都可以在CameraSource中找到.java