背景
我已经构建了一个基于 Web 的小应用程序,它会弹出窗口来显示您的网络摄像头。我想添加对您的提要进行色度键的功能,并且已经成功地使几种不同的算法正常工作。然而,我发现的最好的算法对于 JavaScript 来说是资源密集型的;单线程应用程序。
问题
有没有办法将密集的数学运算卸载到 GPU 上?我试过让 GPU.js 工作,但我不断收到各种错误。这是我想让 GPU 运行的功能:
let dE76 = function(a, b, c, d, e, f) {
return Math.sqrt( pow(d - a, 2) + pow(e - b, 2) + pow(f - c, 2) );
};
let rgbToLab = function(r, g, b) {
let x, y, z;
r = r / 255;
g = g / 255;
b = b / 255;
r = (r > 0.04045) ? Math.pow((r + 0.055) / 1.055, 2.4) : r / 12.92;
g = (g > 0.04045) ? Math.pow((g + 0.055) / 1.055, 2.4) : g / 12.92;
b = (b > 0.04045) ? Math.pow((b + 0.055) / 1.055, 2.4) : b / 12.92;
x = (r * 0.4124 + g * 0.3576 + b * 0.1805) / 0.95047;
y = (r * 0.2126 + g * 0.7152 + b * 0.0722) / 1.00000;
z = (r * 0.0193 + g * 0.1192 + b * 0.9505) / 1.08883;
x = (x > 0.008856) ? Math.pow(x, 1/3) : (7.787 * x) + 16/116;
y = (y > 0.008856) ? Math.pow(y, 1/3) : (7.787 * y) + 16/116;
z = (z > 0.008856) ? Math.pow(z, 1/3) : (7.787 * z) + 16/116;
return [ (116 * y) - 16, 500 * (x - y), 200 * (y - z) ];
};
这里发生的是我发送一个 RGB 值,rgbToLab
它返回 LAB 值,该值可以与我的绿屏已存储的 LAB 值进行比较dE76
。然后在我的应用程序中,我们检查该dE76
值是否为阈值,例如 25,如果该值小于此值,我会将视频源中的像素不透明度设置为 0。
GPU.js 尝试
这是我最新的 GUI.js 尝试:
// Try to combine the 2 functions into a single kernel function for GPU.js
let tmp = gpu.createKernel( function( r, g, b, lab ) {
let x, y, z;
r = r / 255;
g = g / 255;
b = b / 255;
r = (r > 0.04045) ? Math.pow((r + 0.055) / 1.055, 2.4) : r / 12.92;
g = (g > 0.04045) ? Math.pow((g + 0.055) / 1.055, 2.4) : g / 12.92;
b = (b > 0.04045) ? Math.pow((b + 0.055) / 1.055, 2.4) : b / 12.92;
x = (r * 0.4124 + g * 0.3576 + b * 0.1805) / 0.95047;
y = (r * 0.2126 + g * 0.7152 + b * 0.0722) / 1.00000;
z = (r * 0.0193 + g * 0.1192 + b * 0.9505) / 1.08883;
x = (x > 0.008856) ? Math.pow(x, 1/3) : (7.787 * x) + 16/116;
y = (y > 0.008856) ? Math.pow(y, 1/3) : (7.787 * y) + 16/116;
z = (z > 0.008856) ? Math.pow(z, 1/3) : (7.787 * z) + 16/116;
let clab = [ (116 * y) - 16, 500 * (x - y), 200 * (y - z) ];
let d = pow(lab[0] - clab[0], 2) + pow(lab[1] - clab[1], 2) + pow(lab[2] - clab[2], 2);
return Math.sqrt( d );
} ).setOutput( [256] );
// ...
// Call the function above.
let d = tmp( r, g, b, chromaColors[c].lab );
// If the delta (d) is lower than my tolerance level set pixel opacity to 0.
if( d < tolerance ){
frame.data[ i * 4 + 3 ] = 0;
}
错误:
以下是我在调用 tmp 函数时尝试使用 GPU.js 时遇到的错误列表。1)用于我上面提供的代码。2) 用于擦除 tmp 中的所有代码并仅添加一个空返回 3) 是如果我尝试在 tmp 函数中添加函数;一个有效的 JavaScript 东西,但不是 C 或内核代码。
- 未捕获的错误:未定义标识符
- 未捕获的错误:编译片段着色器时出错:错误:0:463:';' : 语法错误
- 未捕获的错误:getDependencies 中未处理的类型 FunctionExpression