javascript - 使用 Canvas 旋转坐标(面部地标),原点位于左上角

标签 javascript canvas computer-vision face-recognition google-cloud-vision

我正在使用 Google 的 Cloud Vision API 来检测人脸和其中的地标(例如眼睛、 Nose 等)。

如果脸部旋转,我想纠正旋转,以便脸部及其地标垂直放置在 canvas 元素内。

Google 提供地标的坐标,其原点位于左上角,以及以度为单位的滚动倾斜平移 属性:

enter image description here

"landmarks": [
        {
          "position": {
            "x": 371.52585,
            "y": 437.1983,
            "z": 0.0012220144
          },
          "type": "LEFT_EYE"
        },
        ...
        "panAngle": -2.0305812,
        "rollAngle": 26.898327,
        "tiltAngle": -2.6251676,
        ...

我可以通过使用 ctx.rotate( Degrees*Math.PI/180)rollAngle 属性转换为弧度来纠正图像的旋转,但是我该如何做旋转坐标以便它们与旋转后的图像匹配?

我的目标是使图像和相应的坐标如下:

enter image description here

干杯

最佳答案

我不想为此向 API 发送两个网络请求。解决方案是分别旋转 Canvas 和坐标。首先,我使用 Cloud Vision API 提供的 rollAngle 在其中心旋转 Canvas 。

function rotateCanvas(canvas, image) {

    let ctx = canvas.getContext('2d');
    let rollAngle = sampleResponse.faceAnnotations[0].rollAngle; // rotation of face provided by the Cloud Vision API

    ctx.save();
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.translate(
        canvas.width / 2,
        canvas.height / 2);
    ctx.rotate(Math.PI / 180 * -rollAngle);
    ctx.translate(
        -(canvas.width / 2),
        -(canvas.height / 2));
    ctx.drawImage(
        image,
        canvas.width / 2 - canvas.width / 2,
        canvas.height / 2 - canvas.height / 2,
        canvas.width,
        canvas.height);
    ctx.restore();

    return canvas;

}

接下来我用了this answer循环遍历 Cloud Vision API 提供的每个地标并按给定的 rollAngle 旋转它:

function rotateCoordinate(cx, cy, x, y, angle) {

    // rotate the landmarks provided by the cloud vision API if the face in the supplied
    // image isn't vertically aligned

    var radians = (Math.PI / 180) * angle,
        cos = Math.cos(radians),
        sin = Math.sin(radians),
        nx = (cos * (x - cx)) + (sin * (y - cy)) + cx,
        ny = (cos * (y - cy)) - (sin * (x - cx)) + cy;
    return [nx, ny];
}

与 Canvas 旋转一样,我从中心旋转所有内容。

function rotateLandmarks(canvas, landmarks) {

    let rollAngle = sampleResponse.faceAnnotations[0].rollAngle;

    for (let i = 0; i < landmarks.length; i++) {

        let rotated = this.rotateCoordinate(
            canvas.width / 2,
            canvas.height / 2,
            landmarks[i].position.x,
            landmarks[i].position.y,
            rollAngle)

        landmarks[i].position.x = rotated[0];
        landmarks[i].position.y = rotated[1];

    }

    return landmarks;

}

关于javascript - 使用 Canvas 旋转坐标(面部地标),原点位于左上角,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72569304/

相关文章:

javascript - 如何使用 Javascript 操作此 JSON

java - 使用Seek Bar缩放android Canvas

c# - 如何预测 Canvas 上 XAML 标签的高度

javascript - 谷歌地图API搜索标记与条件

javascript - 如何确定 javascript 脚本中的解释器类型?

android - 使用 SurfaceView 和 4 个 Canvas 图像如何找到哪个图像被触摸了?

c++ - 如何旋转图像中的特定部分?

OpenCV 背景减法 : How to precompute background model?

machine-learning - 使用Caffe对 "hand-crafted"图像特征进行分类

javascript - Pinterest "Pin It"按钮黑客攻击