我使用 TF.js
在浏览器中运行一个关键点预测模型,希望能够使用 TF.js
和 WebGL
后端对每个关键点的值应用仿射变换。
对于每个关键点的值,我想做 平移(translate)
、缩放(scale)
和 旋转(rotation)
。
输入
作为模型预测的结果,我有一个形状为 [coord, n]
的张量,其中coord
是关键点在像素中的[x, y]
位置。
我的张量:
inputTensor.print();
> Tensor
[[103.9713821, 128.1083069], // <- [x, y]
[103.7512436, 107.0477371],
[103.3587036, 115.1293793],
[99.65448 , 92.0794601 ],
[103.9862061, 101.7136688],
[104.2239304, 95.8158569 ],
[104.6783295, 82.7580566 ]]
公式
我看到tf.image.transform
使用下面的公式计算像素位置。
(x', y') = ((a0 x + a1 y + a2) / k, (b0 x + b1 y + b2) / k)
其中k = c0 x + c1 y + 1.
我有[a0, a1, a2, b0 b1, b2, c0, c1]
的值,所以似乎只需要找到一种方法将此公式应用于张量中的每个(x,y)对。
CPU示例(我需要在TF.js上)
我尝试使用THREE.js在CPU上进行转换。它可以工作,但速度太慢。 希望这会给您一些关于我的期望的想法。
const landmarks: Float32Array = inputTensor.dataSync();
const output: Point3D[] = [];
for (let i = 0; i < landmarks.length - 1; i += 2) {
const x = landmarks[i];
const y = landmarks[i + 1];
const mat4 = new Matrix4();
mat4.identity();
// Fill in with the basic values
mat4.multiply(new Matrix4().makeTranslation(x, y, 0));
// Scale
mat4.multiply(
new Matrix4().makeScale(
1 / scaleX,
1 / scaleY,
1,
),
);
// Rotate
mat4.multiply(new Matrix4().makeRotationZ(rotate));
// Translate
mat4.multiply(
new Matrix4().makeTranslation(
translateX,
translateY,
0,
),
);
const p = new Vector3(x, y, 0).applyMatrix4(mat4);
output.push(new Point3D(p.x, p.y, p.z));
}
注意
据我所见,tf.image.transform
对我来说不起作用,因为它是根据元素的位置进行操作,但我需要根据其值进行操作。