双边滤波算法
Bilateral filter algorithm
我试图在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吗?
我不是javascript专家:RGB值是0..255吗?如果是这样,Math.exp(colourDist*colourDist*8)
将产生非常大的值-你可能想要将colordist缩放到[0..1]的范围。
BTW:如果你只需要之后的平方距离,为什么还要计算dist
和colourDist
的sqrt
?
首先,你的图像在边缘变得黑色/奇怪,因为你没有过滤边缘。简短地看一下你的代码,你会发现你开始于(kernelSize,kernelSize),结束于(width-kernelSize,height-kernelSize)——这意味着你只过滤了图像中一个较小的矩形,其中每边都有一个未过滤的kernelSize边距。在不知道你的javascript/html5的情况下,我会假设你的outputData数组被初始化为零(这意味着黑色),然后不触摸它们会让它们变黑。查看我的链接,评论到你的帖子的代码,确实处理边缘。
除此之外,遵循@nikie的答案-你可能想确保颜色距离被限制在[0,1]的范围内-你可以通过添加colourDist = colourDist / (MAX_COMP * Math,sqrt(3))
行来做到这一点(直接在第一行之后计算它)。其中MAX_COMP
是图像中颜色分量的最大值(通常为255)
我发现了代码中的错误。问题是我将每个像素添加到自己而不是周围的邻居。我将把更正后的代码留在这里,以防有人需要双边过滤算法。
outputData[pixel] += curWeight*inputData[kernel];
outputData[pixel+1] += curWeight*inputData[kernel+1];
outputData[pixel+2] += curWeight*inputData[kernel+2];
- 循环比赛位置算法
- javascript扫雷器floodfill算法不能正常工作
- Node JS中的排名系统算法
- 查找仅适用于原始图像的图像放大算法的名称
- 在数组的 2/3 上调用自身的排序算法
- Luhn算法的实现
- 算法:从数组(javascript/angular)中按当前日期获取上一个和下一个事件
- 加速单纯形算法
- 最短路径算法js错误
- 代码战争中的算法混乱
- 用于自动放置流程图形状的算法
- PHP或JavaScript的基本遗传算法开源代码
- 用Javascript实现算法
- 堆中for循环的奇怪行为's算法
- 一种从随机数的序列中查找值的简单算法
- Node.js上的高性能算法
- JavaScript排序算法不起作用 - 任何明显的我做错了
- 需要使用JavaScript实现我的算法
- 用于计算产品价格的JavaScript构建和算法
- Vanilla Javascript算法,如何做和解释