背景:
该应用程序允许用户上传自己的照片,然后将一副眼镜戴在脸上,看看它的样子。在大多数情况下,它工作正常。用户选择两个瞳孔的位置后,我根据瞳孔距离与眼镜中心点之间已知距离的比率自动缩放图像。那里一切正常,但现在我需要自动将眼镜图像放在眼睛上。
我正在使用 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);
需要
一个数学天才给我算法来确定图像大小调整后新的左眼位置应该在哪里
更新
在过去 6 个小时左右研究了这个之后,我想我需要做一些“翻译变换”,但我看到的例子只允许通过 x 和 y 量来设置它。而我只会知道底层图像。这是我找到的示例(对我没有帮助):
http://tutorials.jenkov.com/html5-canvas/transformation.html
这是一些看起来很有趣的东西,但它适用于 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):
var xFromCenter = self.leftEyePosition.x - self.xCenter;
var yFromCenter = self.leftEyePosition.y - self.yCenter;
var angle = Math.atan2(yFromCenter, xFromCenter);
var length = Math.hypotenuse(xFromCenter, yFromCenter);
var xNew = zoomFactor * length * Math.cos(angle);
var yNew = zoomFactor * length * Math.sin(angle);
newLeftEyeX = xNew + self.xCenter;
newLeftEyeY = yNew + self.yCenter;
但是,这仍然没有按预期工作。所以,我不确定目前的问题是什么。如果有人以前使用过 KinectJS 并且知道问题可能是什么,请告诉我。
更新 3
我在纸上检查了罗迪的计算,它们看起来很好,所以这里显然有其他东西把事情搞砸了。我在缩放因子 1 和 2 处得到了左瞳孔的坐标。有了这些坐标,也许有人可以找出问题所在是:
缩放系数 1:x = 239,y = 209
缩放系数 2:x = 201,y = 133