首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >双边滤波算法

双边滤波算法
EN

Stack Overflow用户
提问于 2011-09-22 17:39:44
回答 3查看 2.3K关注 0票数 3

我正在尝试用javascript实现一个简单的双边过滤器。这就是我到目前为止想出的:

代码语言: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的形式。我的图像要么没有变化,要么边缘有黑色斑块,这取决于我如何改变这个公式:

代码语言:javascript
复制
var curWeight = 1/(Math.exp(dist*dist/72)*Math.exp(colourDist*colourDist*8));

不幸的是,我对html/javascript和图像视觉算法仍然是个新手,我的搜索也没有找到答案。我的猜测是curWeight的计算方式有问题。我在这里做错了什么?我是否应该先将输入图像转换为CIElab/hsv?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-09-23 18:34:40

我发现了代码中的错误。问题是我把每个像素都加到了自己身上,而不是它周围的相邻像素。我将把修正后的代码留在这里,以防任何人需要双边过滤算法。

代码语言:javascript
复制
outputData[pixel] += curWeight*inputData[kernel];
outputData[pixel+1] += curWeight*inputData[kernel+1];
outputData[pixel+2] += curWeight*inputData[kernel+2];
票数 0
EN

Stack Overflow用户

发布于 2011-09-22 17:50:03

我不是Javasript专家: RGB值是0..255吗?如果是这样的话,Math.exp(colourDist*colourDist*8)将产生非常大的值--您可能希望将colourDist扩展到0..1的范围。

顺便说一下:如果之后只需要平方距离,为什么还要计算distcolourDistsqrt

票数 2
EN

Stack Overflow用户

发布于 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)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7512691

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档