バックグラウンド:
このアプリを使用すると、ユーザーは自分の写真をアップロードしてから、顔に眼鏡をかけてどのように見えるかを確認できます。ほとんどの場合、正常に動作しています。ユーザーが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);
必要
画像のサイズが変更された後、新しい左目の位置を決定するアルゴリズムを私に与える数学の天才
アップデート
過去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
Rodyの計算を紙で確認したところ、問題がないように見えたので、明らかに他の何かが混乱しています。ズーム係数1と2で左瞳孔の座標を取得しました。これらの座標を使用すると、誰かが問題を理解できる可能性があります。は:
ズーム率1:x = 239、y = 209
ズーム率2:x = 201、y = 133