我很难让FaceTracker类在HoloLens 2上工作。一旦我尝试用ProcessNextFrameAsync Method
检测人脸,我就会得到以下类型的异常:
System.Runtime.InteropServices.COMException (0x80004005): Unspecified error
这只是错误消息的第一部分,如果需要更多信息,我可以添加。
请参阅此获取一个最小的示例。
public async void Start()
{
var selectedGroup = await FindCameraAsync();
await StartMediaCaptureAsync(selectedGroup);
}
private async Task StartMediaCaptureAsync(MediaFrameSourceGroup sourceGroup)
{
faceTracker = await FaceTracker.CreateAsync();
this.mediaCapture = new MediaCapture();
await this.mediaCapture.InitializeAsync(settings);
this.frameProcessingTimer = ThreadPoolTimer.CreatePeriodicTimer(ProcessCurrentVideoFrameAsync, timerInterval);
}
private async Task ProcessCurrentVideoFrameAsync()
{
const BitmapPixelFormat InputPixelFormat = BitmapPixelFormat.Nv12;
var deviceController = this.mediaCapture.VideoDeviceController;
this.videoProperties = deviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview) as VideoEncodingProperties;
VideoFrame videoFrame = new VideoFrame(InputPixelFormat, (int)this.videoProperties.Width (int)this.videoProperties.Height);
IList<DetectedFace> detectedFaces;
try
{
detectedFaces = await faceTracker.ProcessNextFrameAsync(videoFrame);
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine($"Failed with Exception: {e.ToString()}");
return;
}
videoFrame.Dispose();
}
- 我得到了一个合适的
MediaFrameSourceKind.Color
和MediaStreamType.VideoPreview
与FindCameraAsync()
的相机。在我看来,这很好 - 启动
MediaCapture
和StartMediaCaptureAsync()
中的FaceTracker
- 尝试在
ProcessCurrentVideoFrameAsync()
中检测人脸
以下是我测试过的东西和我收到的信息:
- 我有一张
Nv12
、PixelWidth
1504和PixelHeigt
846格式的照片 - Unity中的权限被授予网络摄像头、图片库和麦克风
- 该应用程序是使用Il2CPP编译的
- 消息CCD_ 13在启动应用程序之后出现。在其他文章中提到,权限(网络摄像头或麦克风(丢失,但事实并非如此。但可能是有联系的
- 我使用了"在一系列帧中跟踪面"one_answers"基本面跟踪"示例作为参考
我非常感谢每一个激励和想法。
更新14。2020年7月
我刚刚在HoloLens 2上本地存储的几个单独的图像上尝试了FaceDetector
。这很好用。
尽管FaceDetector
和FaceTracker
不完全相同,但它们非常相似。所以我想这个问题在某种程度上与MediaCapture
有关。
接下来,我将尝试用MediaCapture
捕获图像,并用FaceDetector
对其进行处理。
在此期间,如果有人有其他想法,我将不胜感激。
这是一个官方示例,展示了如何使用FaceTracker类在视频流中查找人脸:基本人脸跟踪示例。在第256行中,这是从捕捉设备获得预览帧的要点。
但是,根据您的代码,您已经创建了一个VideoFrame
对象,并为其指定了属性和格式,但缺少调用GetPreviewFrameAsync
将本地网络摄像头帧转换为VideoFrame
对象。
你可以尝试以下代码来修复它:
private async Task ProcessCurrentVideoFrameAsync()
{
const BitmapPixelFormat InputPixelFormat = BitmapPixelFormat.Nv12;
var deviceController = this.mediaCapture.VideoDeviceController;
this.videoProperties = deviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview) as VideoEncodingProperties;
VideoFrame videoFrame = new VideoFrame(InputPixelFormat, (int)this.videoProperties.Width (int)this.videoProperties.Height);
//add this line code.
await this.mediaCapture.GetPreviewFrameAsync(videoFrame);