зеркало из https://github.com/mozilla/gecko-dev.git
358 строки
9.3 KiB
HTML
358 строки
9.3 KiB
HTML
<!DOCTYPE HTML>
|
|
<html>
|
|
<!--
|
|
https://bugzilla.mozilla.org/show_bug.cgi?id=965420
|
|
-->
|
|
<head>
|
|
<title>Bug 965420 - Test camera hardware API for face detection</title>
|
|
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
|
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
<script type="text/javascript" src="camera_common.js"></script>
|
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
|
</head>
|
|
<body>
|
|
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=965420">Mozilla Bug 965420</a>
|
|
<video id="viewfinder" width = "200" height = "200" autoplay></video>
|
|
<img src="#" alt="This image is going to load" id="testimage"/>
|
|
|
|
<script class="testbody" type="text/javascript;version=1.7">
|
|
|
|
function compareFaces(aFaces, expected)
|
|
{
|
|
ok(aFaces, "have detected faces object");
|
|
ok(aFaces.length == expected.faces.length,
|
|
"expected=" + expected.faces.length + ", got=" + aFaces.length);
|
|
aFaces.forEach(function (face, index) {
|
|
let result = compareFace(face, expected.faces[index]);
|
|
ok(result === "ok", "face check: " + result);
|
|
if (result !== "ok") {
|
|
return false;
|
|
}
|
|
});
|
|
return true;
|
|
}
|
|
|
|
function compareFace(aFace, expected)
|
|
{
|
|
if (aFace.id != expected.id) {
|
|
return "expected face.id=" + expected.id + ", got=" + aFace.id;
|
|
}
|
|
if (aFace.score != expected.score) {
|
|
return "expected face.score=" + expected.score + ", got=" + aFace.score;
|
|
}
|
|
if (!aFace.bounds) {
|
|
return "face.bounds is missing";
|
|
}
|
|
if (aFace.bounds.left != expected.bounds.left ||
|
|
aFace.bounds.top != expected.bounds.top ||
|
|
aFace.bounds.right != expected.bounds.right ||
|
|
aFace.bounds.bottom != expected.bounds.bottom) {
|
|
return "expected face.bounds=" + expected.bounds.toSource() +
|
|
", got=({left:" + aFace.bounds.left + ", top:" + aFace.bounds.top + ", right:" + aFace.bounds.right + ", bottom:" + aFace.bounds.bottom + "})";
|
|
}
|
|
|
|
if (aFace.leftEye && !expected.leftEye) {
|
|
return "expected null face.leftEye, got=({x:" + aFace.leftEye.x + ", y:" + aFace.leftEye.y + "})";
|
|
}
|
|
if (!aFace.leftEye && expected.leftEye) {
|
|
return "expected face.leftEye=" + expected.leftEye.toSource() + ", got null leftEye";
|
|
}
|
|
if (aFace.leftEye && expected.leftEye &&
|
|
(aFace.leftEye.x != expected.leftEye.x || aFace.leftEye.y != expected.leftEye.y)) {
|
|
return "expected face.leftEye=" + expected.leftEye.toSource() +
|
|
", got=({x:" + aFace.leftEye.x + ", y:" + aFace.leftEye.y + "})";
|
|
}
|
|
|
|
if (aFace.rightEye && !expected.rightEye) {
|
|
return "expected null face.rightEye, got=({x:" + aFace.rightEye.x + ", y:" + aFace.rightEye.y + "})";
|
|
}
|
|
if (!aFace.rightEye && expected.rightEye) {
|
|
return "expected face.rightEye=" + expected.rightEye.toSource() + ", got null rightEye";
|
|
}
|
|
if (aFace.rightEye && expected.rightEye &&
|
|
(aFace.rightEye.x != expected.rightEye.x || aFace.rightEye.y != expected.rightEye.y)) {
|
|
return "expected face.rightEye=" + expected.rightEye.toSource() +
|
|
", got=({x:" + aFace.rightEye.x + ", y:" + aFace.rightEye.y + "})";
|
|
}
|
|
|
|
if (aFace.mouth && !expected.mouth) {
|
|
return "expected null face.mouth, got=({x:" + aFace.mouth.x + ", y:" + aFace.mouth.y + "})";
|
|
}
|
|
if (!aFace.mouth && expected.mouth) {
|
|
return "expected face.mouth=" + expected.mouth.toSource() + ", got null mouth";
|
|
}
|
|
if (aFace.mouth && expected.mouth &&
|
|
(aFace.mouth.x != expected.mouth.x || aFace.mouth.y != expected.mouth.y)) {
|
|
return "expected face.mouth=" + expected.mouth.toSource() +
|
|
", got=({x:" + aFace.mouth.x + ", y:" + aFace.mouth.y + "})";
|
|
}
|
|
|
|
return "ok";
|
|
}
|
|
|
|
var suite = new CameraTestSuite();
|
|
|
|
suite.test('face-detection-op', function() {
|
|
function start(p) {
|
|
return new Promise(function(resolve, reject) {
|
|
suite.hw.attach({
|
|
startFaceDetection: function() {
|
|
ok(true, "startFaceDetection() requested");
|
|
resolve();
|
|
}
|
|
});
|
|
try {
|
|
suite.camera.startFaceDetection();
|
|
ok(true, "startFaceDetection() succeeded");
|
|
} catch(e) {
|
|
ok(false, "startFaceDetection() failed with: " + e.name);
|
|
resolve();
|
|
}
|
|
});
|
|
}
|
|
|
|
function stop(p) {
|
|
return new Promise(function(resolve, reject) {
|
|
suite.hw.attach({
|
|
stopFaceDetection: function() {
|
|
ok(true, "stopFaceDetection() requested");
|
|
resolve();
|
|
}
|
|
});
|
|
try {
|
|
suite.camera.stopFaceDetection();
|
|
ok(true, "stopFaceDetection() succeeded");
|
|
} catch(e) {
|
|
ok(false, "stopFaceDetection() failed with: " + e.name);
|
|
resolve();
|
|
}
|
|
});
|
|
}
|
|
|
|
function startFailure(p) {
|
|
return new Promise(function(resolve, reject) {
|
|
suite.hw.attach({
|
|
startFaceDetection: function() {
|
|
ok(true, "startFaceDetection() requested and failed");
|
|
resolve();
|
|
throw SpecialPowers.Cr.NS_ERROR_FAILURE;
|
|
}
|
|
});
|
|
try {
|
|
suite.camera.startFaceDetection();
|
|
ok(true, "startFaceDetection() succeeded and error swallowed");
|
|
} catch(e) {
|
|
ok(false, "startFaceDetection() failed with: " + e.name);
|
|
resolve();
|
|
}
|
|
});
|
|
}
|
|
|
|
function stopFailure(p) {
|
|
return new Promise(function(resolve, reject) {
|
|
suite.hw.attach({
|
|
stopFaceDetection: function() {
|
|
ok(true, "stopFaceDetection() requested and failed");
|
|
resolve();
|
|
throw SpecialPowers.Cr.NS_ERROR_FAILURE;
|
|
}
|
|
});
|
|
try {
|
|
suite.camera.stopFaceDetection();
|
|
ok(true, "stopFaceDetection() succeeded and error swallowed");
|
|
} catch(e) {
|
|
ok(false, "stopFaceDetection() failed with: " + e.name);
|
|
resolve();
|
|
}
|
|
});
|
|
}
|
|
|
|
return suite.getCamera()
|
|
.then(start, suite.rejectGetCamera)
|
|
.then(stop)
|
|
.then(startFailure)
|
|
.then(stopFailure);
|
|
});
|
|
|
|
suite.test('face-detection', function() {
|
|
function detectFace(msg, given, expected) {
|
|
if (expected === undefined) {
|
|
expected = given;
|
|
}
|
|
var sync = new Promise(function(resolve, reject) {
|
|
function onEvent(evt) {
|
|
try {
|
|
suite.camera.removeEventListener('facesdetected', onEvent);
|
|
ok(compareFaces(evt.faces, expected),
|
|
"facedetected event received " + msg + " correctly");
|
|
resolve();
|
|
} catch(e) {
|
|
reject(e);
|
|
}
|
|
}
|
|
suite.camera.addEventListener('facesdetected', onEvent);
|
|
});
|
|
|
|
suite.hw.fireFacesDetected(given);
|
|
return sync;
|
|
}
|
|
|
|
function detectOneFace(p) {
|
|
return detectFace('one-face',
|
|
{
|
|
faces: [ {
|
|
id: 1,
|
|
score: 2,
|
|
bounds: {
|
|
left: 3,
|
|
top: 4,
|
|
right: 5,
|
|
bottom: 6
|
|
},
|
|
leftEye: {
|
|
x: 7,
|
|
y: 8
|
|
},
|
|
rightEye: {
|
|
x: 9,
|
|
y: 10
|
|
},
|
|
mouth: {
|
|
x: 11,
|
|
y: 12
|
|
}
|
|
} ]
|
|
}
|
|
);
|
|
}
|
|
|
|
function detectTwoFaces(p) {
|
|
return detectFace('two-faces',
|
|
{
|
|
faces: [ {
|
|
id: 1,
|
|
score: 2,
|
|
bounds: {
|
|
left: 3,
|
|
top: 4,
|
|
right: 5,
|
|
bottom: 6
|
|
},
|
|
leftEye: {
|
|
x: 7,
|
|
y: 8
|
|
},
|
|
rightEye: {
|
|
x: 9,
|
|
y: 10
|
|
},
|
|
mouth: {
|
|
x: 11,
|
|
y: 12
|
|
}
|
|
},
|
|
{
|
|
id: 13,
|
|
score: 14,
|
|
bounds: {
|
|
left: 15,
|
|
top: 16,
|
|
right: 17,
|
|
bottom: 18
|
|
},
|
|
leftEye: {
|
|
x: 19,
|
|
y: 20
|
|
},
|
|
rightEye: {
|
|
x: 21,
|
|
y: 22
|
|
},
|
|
mouth: {
|
|
x: 23,
|
|
y: 24
|
|
}
|
|
} ]
|
|
}
|
|
);
|
|
}
|
|
|
|
function detectOneFaceNoFeatures() {
|
|
return detectFace('one-face-no-features',
|
|
{
|
|
faces: [ {
|
|
id: 1,
|
|
score: 100,
|
|
bounds: {
|
|
left: 3,
|
|
top: 4,
|
|
right: 5,
|
|
bottom: 6
|
|
},
|
|
leftEye: null,
|
|
rightEye: null,
|
|
mouth: null
|
|
} ]
|
|
}
|
|
);
|
|
}
|
|
|
|
function detectNoFaces() {
|
|
return detectFace('no-faces',
|
|
{
|
|
faces: []
|
|
}
|
|
);
|
|
}
|
|
|
|
function detectOneFaceExcessScore() {
|
|
return detectFace('one-face-excess-score',
|
|
{
|
|
faces: [ {
|
|
id: 1,
|
|
score: 120,
|
|
bounds: {
|
|
left: 3,
|
|
top: 4,
|
|
right: 5,
|
|
bottom: 6
|
|
},
|
|
leftEye: null,
|
|
rightEye: null,
|
|
mouth: null
|
|
} ]
|
|
},
|
|
{
|
|
faces: [ {
|
|
id: 1,
|
|
score: 100,
|
|
bounds: {
|
|
left: 3,
|
|
top: 4,
|
|
right: 5,
|
|
bottom: 6
|
|
},
|
|
leftEye: null,
|
|
rightEye: null,
|
|
mouth: null
|
|
} ]
|
|
}
|
|
);
|
|
}
|
|
|
|
return suite.getCamera()
|
|
.then(detectOneFace, suite.rejectGetCamera)
|
|
.then(detectTwoFaces)
|
|
.then(detectOneFaceNoFeatures)
|
|
.then(detectNoFaces)
|
|
.then(detectOneFaceExcessScore);
|
|
});
|
|
|
|
suite.setup()
|
|
.then(suite.run);
|
|
|
|
</script>
|
|
</body>
|
|
|
|
</html>
|