一种用opencv实现快速求取局部标准差的方法
1. 标准差的定义及计算公式
标准差(Standard Deviation),在概率统计中最常使用作为统计分布程度上的测量。标准差定义是总体各单位标准值与其平均数离差平方的算术平均数的平方根。它反映组内个体间的离散程度。
计算公式如下:
δ
=
1
N
∑
i
=
1
N
(
x
i
−
x
ˉ
)
2
\delta=\sqrt{\frac{1}{N}\sum_{i=1}^N{(x_i-\bar{x})^2}}
δ=N1i=1∑N(xi−xˉ)2
一个较快求解的方式为:
δ
=
∑
i
=
1
N
x
i
2
N
(
∑
i
=
1
N
x
i
N
)
=
N
∑
i
=
1
N
x
i
2
−
(
∑
i
=
1
N
x
i
)
2
N
2
\delta=\sqrt{\frac{\sum_{i=1}^Nx_i^2}{N(\frac{\sum_{i=1}^N x_i}{N})}}=\sqrt{\frac{N\sum_{i=1}^N x_i^2 - (\sum_{i=1}^N x_i)^2}{N^2}}
δ=N(N∑i=1Nxi)∑i=1Nxi2=N2N∑i=1Nxi2−(∑i=1Nxi)2
2. OpenCV实现
针对式(2)进一步化解如下
δ
=
∑
i
=
1
N
x
i
2
N
−
(
∑
i
=
1
2
x
i
N
)
2
\delta=\sqrt{\frac{\sum_{i=1}^N x_i^2}{N}-(\frac{\sum_{i=1}^2 x_i}{N})^2}
δ=N∑i=1Nxi2−(N∑i=12xi)2
其中,
∑
i
=
1
N
x
i
2
N
\frac{\sum_{i=1}^N x_i^2}{N}
N∑i=1Nxi2 可以看成对输出图像
I
(
x
,
y
)
I(x,y)
I(x,y)先进行平方得到
I
2
(
x
,
y
)
I^2(x,y)
I2(x,y),然后进行均值滤波得到
I
ˉ
2
(
x
,
y
)
\bar{I}^2(x,y)
Iˉ2(x,y)。
(
∑
i
=
1
2
x
i
N
)
2
(\frac{\sum_{i=1}^2 x_i}{N})^2
(N∑i=12xi)2可以看成先成原图进行均值滤波,再求平方。
具体实现如下:
// 计算一幅图的局部标准差
void calcDeviationImage(Mat inputImg, Mat& devImg, int maskWidth, int maskHeight)
{
Mat orignalImg;
inputImg.convertTo(orignalImg, CV_32FC1);
// 计算均值图像及均值图像的平方图像
Mat meanImg,meanImg_pow;
boxFilter(orignalImg, meanImg, CV_32FC1, Size(maskWidth, maskHeight));
pow(meanImg, 2, meanImg_pow);
// 计算原图的平方图像及该图像的均值图像
Mat orignalImg_pow,orignalImg_pow_mean;
pow(orignalImg, 2, orignalImg_pow);
boxFilter(orignalImg_pow, orignalImg_pow_mean, CV_32FC1, Size(maskWidth, maskHeight));
// 作差然后开根号,得出标准差图像
Mat varianceImg; //方差图像
subtract(orignalImg_pow_mean, meanImg_pow, varianceImg);
sqrt(varianceImg, devImg);
// 转化为CV_8UC1格式
devImg.convertTo(devImg, CV_8UC1);
}
3. 计算用时
在这里选用200张1024*1024尺寸的灰度图像,进行算法耗时测试,计算平均用时为19.24ms:
原图:
结果图: