在Javascript中查找坏点的算法

时间:2012-07-30 07:13:35

标签: javascript algorithm math optimization csv

我正在尝试创建一种算法,以.csv格式检测和计算强度图中的坏像素。我目前的方法是将我正在测试的像素的值除以右边的像素值(或者,如果在最右侧,则将左边的值除以)。如果被除数小于某个阈值(当前为.9),那么我将其标记为死像素。

我的问题是,是否有更好/更有效的方法来计算像素是否已经死亡?

示例csv输出:

3183    3176    3207    3183    3212
3211    3197    3198    3183    3191
3193    3177    1135    3185    3176
3175    3184    3188    3179    3181
3181    3165    3184    3187    3183

在此示例中,中间像素将是“死”像素。

4 个答案:

答案 0 :(得分:2)

<强>效率

您需要至少查看一次每个像素,这样您的运行时间就无法超越当前的O(n),其中n是像素数。您的算法使用恒定的内存量,这也是最佳的。

但是,我不确定你的算法总是正确的。 你有办法避免比较连续的死像素吗?示例输入:

3183    3176    1135    1135    3212
                ^ Not detected

更准确的方式

我假设你采用相邻像素的强度来避免比较屏幕不同区域的像素,因为屏幕的亮度可能不均匀分布。

避免漏报的一种方法是取几个附近像素的平均值,但如果区域中有很多坏点,这可能不起作用。您可以尝试从小区域中的所有像素中取出最大值。这样,只要整个区域中的单个像素没有死亡,就会检测到所有死像素。

您采样的像素数将由您对误报的容差决定。

答案 1 :(得分:2)

如果您有一组死像素,您当前的方法将无法帮助您。它还可以将卡住的像素(具有100%强度的像素)误解为有效像素,将周围像素误解为缺陷,具体取决于用于测试屏幕的图像。

而是计算数据的总体平均μ和方差σ 2 ,并将数据解释为normal distributed。根据{{​​3}} 95%的所有数据应该在区间[μ-2σ,μ+2σ]。

Standard derivation diagram

让我们看看您的样本,并确定这是否适用于您的数据:

var arr = "5000 3176 3207 3183 3212 3211 3197 3198 3183 3191 3193 3177 1135 3185 3176 3175 3184 3188 3179 3181 3181 3165 3184 3187 3183".split(" ");
var i = 0;
var avg = 0; // average/mean
var vri = 0; // variance
var sigma;   // sqrt(vri)

for(i = 0; i < arr.length; ++i){
    arr[i] = parseInt(arr[i]);
    avg += arr[i];
}
avg /= arr.length;

for(i = 0; i < arr.length; ++i){
    vri += (arr[i]-avg)*(arr[i]-avg);
}
vri /= (arr.length - 1);
sigma =  Math.sqrt(vri);

for(i = 0; i < arr.length; ++i){
    if(Math.abs(arr[i]-avg) > 2*sigma)
        console.log("entry "+i+" with value "+arr[i]+" probably dead");
}

这将导致显示死像素(总像素的8%)。请注意,我还添加了一个强度非常高的像素,可能会卡住:

entry 0 with value 5000 propably dead
entry 12 with value 1135 probably dead

然而,有一个主要缺点,因为这种方法只有在屏幕同样亮起时才有效。如果您使用纯白图像记录强度贴图,则无法检测到卡住的像素。当然,如果您的数据由于屏幕完全损坏而分散,这种方法对您没有帮助。除此之外,它很容易实现。您还可以添加本地检查以过滤误报。

请注意,此算法具有3*n的固定运行时。

68-95-99.7 rule已创建diagram

答案 2 :(得分:1)

在真实图像中,您可能会有一个合理的明显过渡,从浅到深或反之亦然 - 一条锐利的阴影线过渡到明亮的太阳,或者仅仅是白色物体的边缘在黑色背景下。因此,仅查看右侧的像素可能很容易产生一些误报。

产生误报的可能性较小的是将像素与其周围的四个像素中的至少每一个(上方,下方,左侧,右侧)进行比较。您可以允许一个像素和四个邻居中的两个之间存在明显差异,但不会在一个像素和所有四个邻居之间产生明显的差异,因为实际图像中的一个像素奇点不太可能。

如果您需要像素在多个单独的图像(不同科目)中测试失败,您甚至可以进一步消除误报。

至于如何进行此计算的详细信息,您可以执行类似于您已经提出的操作,但可以与所有四个邻居进行比较,或者谷歌搜索“死像素检测算法”会产生大量关于各种想法的文章。

答案 3 :(得分:-1)

如果这是一个真实的问题(我们正在讨论相机中的坏像素):

拍摄约5张照片。如果一个像素与它的邻居的强度明显不同(f.e. 11x11块的平均值,分别比较RGB),它几乎肯定会死亡/卡住。