我想使用Android Vision FaceDetector
API对视频文件(例如用户图库中的MP4)执行面部检测/跟踪。我可以看到很多关于使用CameraSource类在直接来自摄像头的流上执行面部跟踪的示例(例如on the android-vision github),但视频文件没有任何内容。
我尝试通过Android Studio查看CameraSource
的源代码,但它被混淆了,我无法在线查看原始内容。我认为使用相机和使用文件有很多共性。据推测,我只是在Surface
上播放视频文件,然后将其传递给管道。
或者,我可以看到Frame.Builder
包含setImageData
和setTimestampMillis
功能。如果我能够将视频读作ByteBuffer
,我该如何将其传递给FaceDetector
API?我猜this question是相似的,但没有答案。同样,将视频解码为Bitmap
帧并将其传递给setBitmap
。
理想情况下,我不想将视频呈现到屏幕上,处理应该与FaceDetector
API一样快。
答案 0 :(得分:2)
或者我可以看到Frame.Builder有函数setImageData和setTimestampMillis。如果我能够将视频作为ByteBuffer读入,我将如何将其传递给FaceDetector API?
只需致电SparseArray<Face> faces = detector.detect(frame);
,其中detector
必须创建如下:
FaceDetector detector = new FaceDetector.Builder(context)
.setProminentFaceOnly(true)
.build();
答案 1 :(得分:1)
如果处理时间不是问题,则使用MediaMetadataRetriever.getFrameAtTime
解决问题。正如Anton所说,您也可以使用FaceDetector.detect
:
Bitmap bitmap;
Frame frame;
SparseArray<Face> faces;
MediaMetadataRetriever mMMR = new MediaMetadataRetriever();
mMMR.setDataSource(videoPath);
String timeMs = mMMR.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION); // video time in ms
int totalVideoTime= 1000*Integer.valueOf(timeMs); // total video time, in uS
for (int time_us=1;time_us<totalVideoTime;time_us+=deltaT){
bitmap = mMMR.getFrameAtTime(time_us, MediaMetadataRetriever.OPTION_CLOSEST_SYNC); // extract a bitmap element from the closest key frame from the specified time_us
if (bitmap==null) break;
frame = new Frame.Builder().setBitmap(bitmap).build(); // generates a "Frame" object, which can be fed to a face detector
faces = detector.detect(frame); // detect the faces (detector is a FaceDetector)
// TODO ... do something with "faces"
}
其中deltaT=1000000/fps
和fps
是每秒所需的帧数。例如,如果要每秒提取4个帧,deltaT=250000
(请注意,faces
将在每次迭代时被覆盖,因此您应该在循环中执行某些操作(存储/报告结果)