2012-07-30 61 views
6

我正在尝试创建一种算法,以.csv格式从强度图中检测并计算坏点。我目前的做法是将我正在测试的像素的值与像素值立即分配到右侧(或者,如果在最右侧,则向左)。如果股息少于某个临界值(当前.9),那么我将其标记为坏点。在Javascript中查找坏点的算法

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

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 

在这个例子中,中间的像素将是一个 “死” 像素。

+2

@Jay:“[...]检测并计算强度图中的坏点。”我想他有必要的数据。他如何得到它,是否正确还有另一个问题,但是你也可以把这个问题解释为“如何得到值低于当地平均值的区域”。 – Zeta 2012-07-30 07:37:37

+1

@Jay:你可能在想像显示器像素;我认为OP在考虑传感器像素(数码相机等) – 2012-07-30 08:18:25

回答

2

效率

你需要在每个像素看起来至少一次,所以没有办法的运行时间都不能战胜当前O(n),其中n是像素数。你的算法使用恒定的内存量,这也是最优的。

但是,我不确定你的算法总是正确的。 你有避免比较连续坏点的方法吗?例如输入:

3183 3176 1135 1135 3212 
       ^Not detected 

更准确地

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

避免误报的一种方法是取附近几个像素的平均值,但如果该区域有很多坏点,则可能无法正常工作。您可以尝试从小区域中的所有像素中取出最大值。这样,只要整个区域的单个像素没有死,所有的坏点都会被检测到。

您抽样的像素数量取决于您对漏报的容忍度。

+0

参考:*您是否有避免比较连续坏点的方法?*我想第二次通过会起作用,并且可能将第二次通过检测到坏像素位置。 – arttronics 2012-07-30 08:22:37

1

在真实图像中,看起来您可能会从光明到黑暗或副反射的正常急剧转变 - 锐利的阴影线转换为明亮的太阳或只是黑色背景上的白色物体的边缘。所以,只看到右侧的像素很容易产生一些误报。

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

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

至于细节如何做这个计算,你可以做一些像你已经提出的东西,但比较所有四个邻居或谷歌搜索“坏点检测算法”产生各种想法的文章主机。

2

如果你有一簇坏点,你目前的做法不会对你有所帮助。它也可以将卡住的像素(具有100%强度的像素)误解为有效像素,并且将周围像素视为缺陷,这取决于用于测试画面的图像。

而是计算您的数据的整体平均值μ和方差σ并将数据解释为normal distributed。根据68-95-99.7 rule 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

(该diagram已被Mwtoews创建)

-1

如果这是现实生活中的问题(我们都在谈论相机坏点):

约需5张图片。如果一个像素与其邻居的亮度有很大差别(f.e. 11x11块的平均值,分别比较RGB),那么它几乎肯定是死的/卡住了。

+0

这不回答问题。 OP正在寻找一种* programmatic *的方式来找到这个,并且没有RGB值,只是强度值。请仔细重读该问题。 – Matt 2012-08-08 09:52:01

+0

@Matt唉,我没有告诉OP手动做,仔细阅读我的答案:)拍多张照片肯定有助于确定一个像素是否真的死了,一张照片可能是一个侥幸。我没有意识到开箱即用的想法应该避免。 – maniek 2012-08-08 12:28:49