问题描述
我正在尝试编写一个 React 应用程序,该应用程序从网络摄像头抓取帧并将其传递给 Azure 人脸 SDK (documentation) 以检测图像中的人脸并获取这些人脸的属性 - 在这种情况下,情绪和头部姿势。
我得到了 the quickstart example code here 的修改版本,它调用了 detectWithUrl() 方法。但是,我的代码中的图像是位图,所以我想我会尝试调用 detectWithStream() 来代替。这个方法的文档说它需要传递 msRest.HttpRequestBody 类型的东西 - 我发现了一些 documentation for this type,它看起来像是一个 Blob、字符串、ArrayBuffer 或 ArrayBufferView。问题是,我真的不明白那些是什么或者我如何从位图图像获取到那种类型的 HttpRequestBody 。我之前处理过 HTTP 请求,但我不太明白为什么要传递给这个方法,或者如何实现。
我找到了一些类似的例子和我正在尝试做的事情的答案,例如 this one。不幸的是,它们要么使用不同的语言,要么调用 Face API 而不是使用 SDK。
编辑:我之前忘记绑定 detectFaces() 方法,因此我最初遇到了与此相关的不同错误。现在我已经解决了这个问题,我收到以下错误:
Uncaught (in promise) Error: image must be a string,Blob,ArrayBuffer,ArrayBufferView,or a function returning NodeJS.ReadableStream
内部构造函数():
this.detectFaces = this.detectFaces.bind(this);
const msRest = require("@azure/ms-rest-js");
const Face = require("@azure/cognitiveservices-face");
const key = <key>;
const endpoint = <endpoint>;
const credentials = new msRest.ApiKeyCredentials({ inHeader: { 'Ocp-Apim-Subscription-Key': key } });
const client = new Face.FaceClient(credentials,endpoint);
this.state = {
client: client
}
// get video
const constraints = {
video: true
}
navigator.mediaDevices.getUserMedia(constraints).then((stream) => {
let videoTrack = stream.getVideoTracks()[0];
const imageCapture = new ImageCapture(videoTrack);
imageCapture.grabFrame().then(function(imageBitmap) {
// detect faces
this.detectFaces(imageBitmap);
});
})
detectFaces() 方法:
async detectFaces(imageBitmap) {
const detectedFaces = await this.state.client.face.detectWithStream(
imageBitmap,{
returnFaceAttributes: ["Emotion","HeadPose"],detectionModel: "detection_01"
}
);
console.log (detectedFaces.length + " face(s) detected");
});
谁能帮助我了解要传递给 detectWithStream() 方法的内容,或者帮助我了解使用哪种方法来检测网络摄像头图像中的人脸效果更好?
解决方法
我想通了,感谢标题“Image to blob”下的 this page!这是我在调用 detectFaces()
之前添加的代码:
// convert image frame into blob
let canvas = document.createElement('canvas');
canvas.width = imageBitmap.width;
canvas.height = imageBitmap.height;
let context = canvas.getContext('2d');
context.drawImage(imageBitmap,0);
canvas.toBlob((blob) => {
// detect faces
this.detectFaces(blob);
})
此代码将位图图像转换为 Blob,然后将 Blob 传递给 detectFaces()
。我也将 detectFaces()
更改为接受 blob
而不是 imageBitmap
,就像这样,然后一切正常:
async detectFaces(blob) {
const detectedFaces = await this.state.client.face.detectWithStream(
blob,{
returnFaceAttributes: ["Emotion","HeadPose"],detectionModel: "detection_01"
}
);
...
}