Javascript KinectJS:图像大小调整后确定新X,Y坐标所需的算法

Javascript KinectJS:图像大小调整后确定新X,Y坐标所需的算法,javascript,jquery,algorithm,html,math,Javascript,Jquery,Algorithm,Html,Math,背景: //.. code before here just zooms the image, etc.. //problem is here (this is wrong, but I need to know what is the right way to calculate this) var newLeftEyeX = self.leftEyePosition.x * ratio; var newLeftEyeY = self.leftEyePosition.y * ratio;

背景:

//.. code before here just zooms the image, etc..

//problem is here (this is wrong, but I need to know what is the right way to calculate this)
var newLeftEyeX = self.leftEyePosition.x * ratio;
var newLeftEyeY = self.leftEyePosition.y * ratio;

//create a blue dot for testing (remove later)
var newEyePosition = new Kinetic.Circle({
    radius: 3,
    fill: "blue",
    stroke: "blue",
    strokeWidth: 0,
    x: newLeftEyeX,
    y: newLeftEyeY
});
self.pointsLayer.add(newEyePosition);

var glassesWidth = glassesImage.getWidth();
var glassesHeight = glassesImage.getHeight();

// this code below works perfect, as I can see the glasses center over the blue dot created above
newGlassesPosition.x = newLeftEyeX - (glassesWidth / 4);
newGlassesPosition.y = newLeftEyeY - (glassesHeight / 2);
该应用程序允许用户上传自己的照片,然后在脸上戴上一副眼镜,看看照片是什么样子。在大多数情况下,它运行良好。在用户选择2个瞳孔的位置后,我会根据瞳孔的距离与眼镜中心点之间的已知距离之间的比率自动缩放图像。在那里一切正常,但现在我需要自动将眼镜图像放在眼睛上

我使用的是KinectJS,但问题不在于该库或javascript。。这更像是一种算法要求

我必须处理的问题:

//.. code before here just zooms the image, etc..

//problem is here (this is wrong, but I need to know what is the right way to calculate this)
var newLeftEyeX = self.leftEyePosition.x * ratio;
var newLeftEyeY = self.leftEyePosition.y * ratio;

//create a blue dot for testing (remove later)
var newEyePosition = new Kinetic.Circle({
    radius: 3,
    fill: "blue",
    stroke: "blue",
    strokeWidth: 0,
    x: newLeftEyeX,
    y: newLeftEyeY
});
self.pointsLayer.add(newEyePosition);

var glassesWidth = glassesImage.getWidth();
var glassesHeight = glassesImage.getHeight();

// this code below works perfect, as I can see the glasses center over the blue dot created above
newGlassesPosition.x = newLeftEyeX - (glassesWidth / 4);
newGlassesPosition.y = newLeftEyeY - (glassesHeight / 2);
  • 瞳孔(眼睛)之间的距离
  • 瞳孔间距(眼镜)
  • 眼镜宽度
  • 眼镜高度
  • 变焦比
  • 一些代码:

    //.. code before here just zooms the image, etc..
    
    //problem is here (this is wrong, but I need to know what is the right way to calculate this)
    var newLeftEyeX = self.leftEyePosition.x * ratio;
    var newLeftEyeY = self.leftEyePosition.y * ratio;
    
    //create a blue dot for testing (remove later)
    var newEyePosition = new Kinetic.Circle({
        radius: 3,
        fill: "blue",
        stroke: "blue",
        strokeWidth: 0,
        x: newLeftEyeX,
        y: newLeftEyeY
    });
    self.pointsLayer.add(newEyePosition);
    
    var glassesWidth = glassesImage.getWidth();
    var glassesHeight = glassesImage.getHeight();
    
    // this code below works perfect, as I can see the glasses center over the blue dot created above
    newGlassesPosition.x = newLeftEyeX - (glassesWidth / 4);
    newGlassesPosition.y = newLeftEyeY - (glassesHeight / 2);
    
    需要

    一个数学天才给了我一个算法,在图像调整大小后,确定新的左眼位置应该在哪里

    更新

    在研究了6个小时后,我想我需要做一些“转换”,但是我看到的例子只允许设置x和y的数量。。而我只知道底层图像的比例。下面是我找到的例子(这对我没有帮助):

    下面是一些看起来很有趣的东西,但这是Silverlight的:

    在Html5和/或KinectJS中是否有类似的方法?也许我走错了路。。。有什么想法吗

    更新2

    我试过这个:

    // if zoomFactor > 1, then picture got bigger, so...
    if (zoomFactor > 1) {
        // if x = 10 (for example) and if zoomFactor = 2, that means new x should be 5
        // current x / zoomFactor => 10 / 2 = 5
        newLeftEyeX = self.leftEyePosition.x / zoomFactor;
        // same for y
        newLeftEyeY = self.leftEyePosition.y / zoomFactor;
    }
    else {
        // else picture got smaller, so...
        // if x = 10 (for example) and if zoomFactor = 0.5, that means new x should be 20
        // current x * (1 / zoomFactor) => 10 * (1 / 0.5) = 10 * 2 = 20
        newLeftEyeX = self.leftEyePosition.x * (1 / zoomFactor);
        // same for y
        newLeftEyeY = self.leftEyePosition.y * (1 / zoomFactor);
    }
    
    这不起作用,所以我尝试了Rody Oldenhuis的建议(谢谢Rody):

    然而,这仍然没有达到预期效果。因此,我不确定目前的问题是什么。如果有人曾经与KinectJS合作过,并且知道问题可能是什么,请告诉我

    更新3

    我检查了Rody在纸上的计算结果,它们看起来很好,所以这里显然有其他东西把事情搞砸了。。我得到了左瞳孔在缩放因子1和2的坐标。有了这些坐标,也许有人能找出问题所在:

    缩放系数1:x=239,y=209


    缩放因子2:x=201,y=133,好的,因为这是一个算法问题,所以我将保留这个泛型,只编写伪代码

    如果我理解正确,您需要的是:

  • 变换所有坐标,使坐标系的原点位于缩放中心(通常为中心像素)

  • 计算从该新原点绘制的线与感兴趣点与正x轴的夹角。还要计算这条线的长度

  • 缩放后的新x和y坐标是通过延长这条线来定义的,这样新线就是缩放因子乘以原始线的长度

  • 将新找到的x和y坐标转换回对计算机有意义的坐标系(例如,左上角像素=0,0)

  • 对所有感兴趣的点重复上述步骤

  • 在伪代码中(带公式):

    请注意,这假定用于长度和宽度的像素数在缩放后保持不变。还要注意,应该进行一些舍入(使所有内容都保持双精度,并且在所有计算之后只舍入到int)

    在上面的代码中,
    atan2
    是四象限反正切,在大多数编程语言中都可用,
    hypot
    只是
    sqrt(x*x+y*y)
    ,但随后计算得更仔细(例如,为了避免溢出等),在大多数编程语言中也可用


    这真的是你想要的吗

    在你说了一些关于人眼的话后我迷路了,这很有帮助,但由于某种原因没有解决问题..无论如何谢谢你抽出时间。。因为上面的内容很有趣,也很有意义。这里一定有什么我忽略了的地方。当你使用这种方法时会发生什么?你看到了什么错误?很难解释,但我发现了一点:在缩放因子1时,左瞳孔为239209,在缩放因子2时,左瞳孔为201133。这有用吗?嗯,那张图像的分辨率是多少?谢谢你问这个问题!我突然想到。。因为图像实际上是在一个550x500的容器中,但是当您在上面提到时,我看了一下图像本身,它是550x568。。当我调整图像大小以匹配容器时,一切都正常。现在唯一的问题是,用户可以上传自己的照片,而我无法控制照片的尺寸。。如果我能确定用户照片的尺寸,我能以某种方式将其纳入等式中吗?