计算图像积分

时间:2012-10-28 16:33:07

标签: opencv

如何从图像积分中找到平均值,标准偏差和渐变?给出如下图像:

summed area table and normal table of numbers

如上图所示,要查找突出显示部分的总和,sum = C+A-B-D 所以我们有sum = 22

我如何继续下去才能找到:

  • 平均数
  • Std dev
  • 渐变

3 个答案:

答案 0 :(得分:3)

如果C + A-B-C是区域内所有灰度级的总和,那么均值

mean = C+A-B-D/4

mean = C+A-B-D/K

其中K是区域中的graylevels数。

此外,

dev = sqrt( C'+A'-B'-D'/4 - (mean*mean) )

不是stdev,因为

dev = sqrt( (1/N)*sum_N ( x_i - u )^2 )

这里的等式相当于

dev = sqrt( (1/N)*sum_N ( (x_i)^2 ) - u^2 )

这些等式不等同。

答案 1 :(得分:2)

C+A-B-D为您提供A,B,C,D分隔的区域中灰度级的总和,以获得您需要按区域区域潜水的平均值:

mean = (C+A-B-D)/4

要获取dev,您必须计算 square 区域表的总和(使用cv::integral,您可以传递其他参数以获得平方和)。引用wikipedia,标准差等于(平方的平均值减去平均值的平方)的平方根。假设A',B',C',D'是 square 区域表中的值:

dev = sqrt((C'+A'-B'-D')/4 - (mean*mean))

因此,使用积分图像计算平均值和使用积分图像非常快<非常,特别是如果您想在随机位置和随机尺寸的图像补丁上计算这些数量。

关于渐变,它更复杂。您确定不想使用sobel运营商吗?

答案 2 :(得分:2)

jmch没有说的是,如果sqrt( C'+A'-B'-D'/K - (mean*mean) )不是你如何计算积分图像的标准偏差,那么你是如何做到的?

首先,让我切换到Python / numpy代码,这样我们就可以得到一些符号一致性,并且表达式更容易检查。给定一个样本数组X,比如说:

X = array([random() * 10.0 for i in range(0, 9)])

X的{​​{3}}可以定义为:

std = (sum((X - mean(X)) ** 2) / len(X)) ** 0.5 # 1

uncorrected sample standard deviation应用于(X - mean(X)) ** 2我们得到:

std = (sum(X ** 2 - X * 2 * mean(X) + mean(X) ** 2) / len(X)) ** 0.5 # 2

鉴于求和操作的binomial theorem,我们可以:

std = ((sum(X ** 2) - 2 * mean(X) * sum(X) + len(X) * mean(X) ** 2) / len(X)) ** 0.5 # 3

如果我们提出S = sum(X)S2 = sum(X ** 2)M = mean(X)N = len(X),我们会:

std = ((S2 - 2 * M * S + N * M ** 2) / N) ** 0.5 # 4

现在可以从I计算图像P和两个积分图像P2I(其中P2是平方像素值的积分图像) ,我们知道,给定四个边缘坐标A = (i0, j0)B = (i0, j1)C = (i1, j0)D = (i1, j1)SS2,{的值可以针对M范围计算{1}}和N

I[A:D]

然后可以将其应用于上面的等式(4),得到范围S = P[A] + P[D] - P[B] - P[C] S2 = P2[A] + P2[D] - P2[B] - P2[C] N = (i1 - i0) * (j1 - j0) M = S / N 的标准偏差。

编辑:这不是完全必要的,但考虑到I[A:D],我们可以将以下替换和简化应用于等式(4):

M = S / N

实际上,这与雷米给出的方程式非常接近。