在我们开始之前,让我们展示他们论文中写的算法的伪代码:
procedure AdaptiveThreshold(in,out,w,h)
1: for i = 0 to w do
2: sum ← 0
3: for j = 0 to h do
4: sum ← sum+in[i, j]
5: if i = 0 then
6: intImg[i, j] ← sum
7: else
8: intImg[i, j] ← intImg[i−1, j] +sum
9: end if
10: end for
11: end for
12: for i = 0 to w do
13: for j = 0 to h do
14: x1 ← i−s/2 {border checking is not shown}
15: x2 ← i+s/2
16: y1 ← j −s/2
17: y2 ← j +s/2
18: count ← (x2−x1)×(y2−y1)
19: sum ← intImg[x2,y2]−intImg[x2,y1−1]−intImg[x1−1,y2] +intImg[x1−1,y1−1]
20: if (in[i, j]×count) ≤ (sum×(100−t)/100) then
21: out[i, j] ← 0
22: else
23: out[i, j] ← 255
24: end if
25: end for
26: end for
intImg
是输入图像到阈值的积分图像,假设灰度。
我已经成功地实现了这个算法,所以让我们谈谈你的疑惑。
那是什么count
?如果是窗口中的像素数,为什么是 2*2=4,而不是根据算法的 3*3=9?
论文中有一个他们没有谈论的潜在假设。的值s
需要是奇数,并且窗口应该是:
x1 = i - floor(s/2)
x2 = i + floor(s/2)
y1 = j - floor(s/2)
y2 = j + floor(s/2)
count
肯定是窗口中的像素总数,但您还需要确保您不会超出范围。你所拥有的当然应该是一个 3 x 3 的窗口等等s = 3
,s = 3
而不是2。我们不能有这个,所以这个以 3 x 3 窗口为中心的有效像素总数是 4,等等。对于图像范围内的窗口,则为9。i = 0, j = 0
x
y
i = 0, j = 0
count = 4
count
此外,为什么像素的原始值乘以计数?该论文说该值与周围像素的平均值进行了比较,为什么不是:
in[i,j] <= (sum/count) * ((100 - t) / 100)
然后?
您正在查看的条件位于算法的第 20 行:
20: (in[i, j]×count) ≤ (sum×(100−t)/100)
我们查看的原因in[i,j]*count
是因为我们假设这in[i,j]
是窗口内的平均强度。s x s
因此,如果我们检查一个s x s
窗口并将所有强度相加,则等于in[i,j] x count
。算法相当巧妙。基本上,我们比较窗口内假定的平均强度 ( in[i,j] x count
) s x s
,如果这小于此窗口内t%
的实际平均值s x s
( sum x ((100-t)/100)
),则输出设置为黑色。如果它更大,则输出设置为白色。但是,您已经雄辩地表示应该改为:
in[i,j] <= (sum/count) * ((100 - t) / 100)
这与第 20 行基本相同,但是您将等式两边除以count
,所以它仍然是相同的表达式。我会说这明确说明了我上面所说的内容。乘法count
肯定会令人困惑,因此您所写的内容更有意义。
因此,您只是以不同的方式看待它,那完全没问题!所以为了回答你的问题,你所说的肯定是正确的,并且等同于实际算法中看到的表达式。
希望这可以帮助!