我正在尝试用javascript实现一个简单的双边过滤器。这就是我到目前为止想出的:
// For each pixel
for (var y = kernelSize; y < height-kernelSize; y++) {
for (var x = kernelSize; x < width-kernelSize; x++) {
var pixel = (y*width + x)*4;
var sumWeight = 0;
outputData[pixel] = 0;
outputData[pixel+1] = 0;
outputData[pixel+2] = 0;
outputData[pixel+3] = inputData[pixel+3];
// For each neighbouring pixel
for(var i=-kernelSize; i<=kernelSize; i++) {
for(var j=-kernelSize; j<=kernelSize; j++) {
var kernel = ((y+i)*width+x+j)*4;
var dist = Math.sqrt(i*i+j*j);
var colourDist = Math.sqrt((inputData[kernel]-inputData[pixel])*(inputData[kernel]-inputData[pixel])+
(inputData[kernel+1]-inputData[pixel+1])*(inputData[kernel+1]-inputData[pixel+1])+
(inputData[kernel+2]-inputData[pixel+2])*(inputData[kernel+2]-inputData[pixel+2]));
var curWeight = 1/(Math.exp(dist*dist/72)*Math.exp(colourDist*colourDist*8));
sumWeight += curWeight;
outputData[pixel] += curWeight*inputData[pixel];
outputData[pixel+1] += curWeight*inputData[pixel+1];
outputData[pixel+2] += curWeight*inputData[pixel+2];
}
}
outputData[pixel] /= sumWeight;
outputData[pixel+1] /= sumWeight;
outputData[pixel+2] /= sumWeight;
}
}inputData来自html5画布对象,采用rgba的形式。我的图像要么没有变化,要么边缘有黑色斑块,这取决于我如何改变这个公式:
var curWeight = 1/(Math.exp(dist*dist/72)*Math.exp(colourDist*colourDist*8));不幸的是,我对html/javascript和图像视觉算法仍然是个新手,我的搜索也没有找到答案。我的猜测是curWeight的计算方式有问题。我在这里做错了什么?我是否应该先将输入图像转换为CIElab/hsv?
发布于 2011-09-23 18:34:40
我发现了代码中的错误。问题是我把每个像素都加到了自己身上,而不是它周围的相邻像素。我将把修正后的代码留在这里,以防任何人需要双边过滤算法。
outputData[pixel] += curWeight*inputData[kernel];
outputData[pixel+1] += curWeight*inputData[kernel+1];
outputData[pixel+2] += curWeight*inputData[kernel+2];发布于 2011-09-22 17:50:03
我不是Javasript专家: RGB值是0..255吗?如果是这样的话,Math.exp(colourDist*colourDist*8)将产生非常大的值--您可能希望将colourDist扩展到0..1的范围。
顺便说一下:如果之后只需要平方距离,为什么还要计算dist和colourDist的sqrt?
发布于 2011-09-22 17:55:19
首先,你的图像在边缘变得黑色/奇怪,因为你没有过滤边缘。简单看一下你的代码,你会发现你从( kernelSize,kernelSize)开始,到(宽度-内核大小,高度-内核大小)结束-这意味着你只过滤了图像内部的一个较小的矩形,你在图像的每一边都有一个未过滤的边距kernelSize。在不知道你的javscript/html5的情况下,我会假设你的outputData数组是用零(这意味着黑色)初始化的,然后不接触它们就会让它们变成黑色。请参阅我的链接评论到你的帖子,以获得处理边缘的代码。
除此之外,遵循@nikie的答案-你可能想确保颜色距离被限制在0,1的范围-你可以通过添加行colourDist = colourDist / (MAX_COMP * Math,sqrt(3)) (直接在第一行之后计算它)来做到这一点。其中MAX_COMP是图像中颜色分量可以具有的最大值(通常为255)
https://stackoverflow.com/questions/7512691
复制相似问题