Javascript 在HTML5中使用画布在视频上应用边缘过滤器,但在视频中会出现延迟。有没有比这更好的方法;你不会落后吗?
我正在使用HTML5画布并通过像素操作应用边缘过滤器。但我在视频中出现了滞后。有没有更好的方法来实现视频边缘滤波器没有任何滞后的视频 以下是我在画布和HTML 5中使用的JavaScript,用于应用效果:-Javascript 在HTML5中使用画布在视频上应用边缘过滤器,但在视频中会出现延迟。有没有比这更好的方法;你不会落后吗?,javascript,html,image-processing,canvas,Javascript,Html,Image Processing,Canvas,我正在使用HTML5画布并通过像素操作应用边缘过滤器。但我在视频中出现了滞后。有没有更好的方法来实现视频边缘滤波器没有任何滞后的视频 以下是我在画布和HTML 5中使用的JavaScript,用于应用效果:- function sobel (px) { px = greyScale(px); var vertical = convoluteFloat32(px, [-1, -2, -1, 0, 0, 0, 1, 2
function sobel (px) {
px = greyScale(px);
var vertical = convoluteFloat32(px,
[-1, -2, -1,
0, 0, 0,
1, 2, 1], false);
var horizontal = convoluteFloat32(px,
[-1, 0, 1,
-2, 0, 2,
-1, 0, 1], false);
var id = createImageData(vertical.width, vertical.height);
for (var i = 0; i < id.data.length; i += 4) {
var v = Math.abs(vertical.data[i]);
id.data[i] = v;
var h = Math.abs(horizontal.data[i]);
id.data[i + 1] = h
id.data[i + 2] = (v + h) / 4;
id.data[i + 3] = 255;
}
return id;
}
function convoluteFloat32 (pixels, weights, opaque) {
var side = Math.round(Math.sqrt(weights.length));
var halfSide = Math.floor(side / 2);
var src = pixels.data;
var sw = pixels.width;
var sh = pixels.height;
var w = sw;
var h = sh;
var output = {
width: w, height: h, data: new Float32Array(w * h * 4)
};
var dst = output.data;
var alphaFac = opaque ? 1 : 0;
for (var y = 0; y < h; y++) {
for (var x = 0; x < w; x++) {
var sy = y;
var sx = x;
var dstOff = (y * w + x) * 4;
var r = 0, g = 0, b = 0, a = 0;
for (var cy = 0; cy < side; cy++) {
for (var cx = 0; cx < side; cx++) {
var scy = Math.min(sh - 1, Math.max(0, sy + cy - halfSide));
var scx = Math.min(sw - 1, Math.max(0, sx + cx - halfSide));
var srcOff = (scy * sw + scx) * 4;
var wt = weights[cy * side + cx];
r += src[srcOff] * wt;
g += src[srcOff + 1] * wt;
b += src[srcOff + 2] * wt;
a += src[srcOff + 3] * wt;
}
}
dst[dstOff] = r;
dst[dstOff + 1] = g;
dst[dstOff + 2] = b;
dst[dstOff + 3] = a + alphaFac * (255 - a);
}
}
return output;
}
function draw() {
// First, draw it into the backing canvas
backcontext.drawImage(video, 0, 0, video.width, video.height);
// Grab the pixel data from the backing canvas
var idata = backcontext.getImageData(0, 0, video.width, video.height);
idata = sobel(idata);
context.putImageData(idata, 0, 0);
// Start over!
setTimeout(draw, 50);
}
函数sobel(px){
px=灰度(px);
var垂直=卷积流32(px,
[-1, -2, -1,
0, 0, 0,
1,2,1],假);
var水平=卷积流32(px,
[-1, 0, 1,
-2, 0, 2,
-1,0,1],假);
var id=createImageData(vertical.width,vertical.height);
对于(变量i=0;i
您可以尝试使用可分离卷积方法进行1D卷积,而不是使用2D内核进行卷积。这将显著提高速度
可以找到关于如何使用Sobel核的可分离卷积的解释
您应该将代码更改为以下内容:
function convoluteFloat32 (pixels, weights1DHorizontal, weights1DVertical, opaque){
convolveFloat321DHorizontal(pixels, weights1DHorizontal, opaque);
convolveFloat321DVertical(pixels, weights1DVertical, opaque);
}
和
convolveFloat321DHorizontal/convolveFloat321DVertical
方法与原始convolatefloat32
方法类似,但它们有3个嵌套for循环,而不是4个 您可以尝试使用可分离卷积方法进行1D卷积,而不是使用2D内核进行卷积。这将显著提高速度
可以找到关于如何使用Sobel核的可分离卷积的解释
您应该将代码更改为以下内容:
function convoluteFloat32 (pixels, weights1DHorizontal, weights1DVertical, opaque){
convolveFloat321DHorizontal(pixels, weights1DHorizontal, opaque);
convolveFloat321DVertical(pixels, weights1DVertical, opaque);
}
和
convolveFloat321DHorizontal/convolveFloat321DVertical
方法与原始convolatefloat32
方法类似,但它们有3个嵌套for循环,而不是4个 谢谢你的回复。。。事实上,你能给我发送1D卷积中上述卷积FLOAT32方法的代码吗。我试图理解一维卷积的概念,但由于我刚刚开始研究这个问题,我不知道如何将上述方法转换为一维卷积。这会有很大的帮助。感谢您的回复。。。事实上,你能给我发送1D卷积中上述卷积FLOAT32方法的代码吗。我试图理解一维卷积的概念,但由于我刚刚开始研究这个问题,我不知道如何将上述方法转换为一维卷积。这会有很大的帮助。谢谢