如何计算高斯加权圆窗?

时间:2016-10-06 08:30:22

标签: c++ matrix statistics gaussian

我有一个矩阵,每个字段都填充了值。尺寸例如是15x15(225)现在我想根据矩阵的中心场计算每个场的权重。对于更大的距离,Pixel的值将更少用于计算的加权。这应该看起来像围绕中心场的圆圈。这里有一个示例图片:

Example

小矩形是中心字段。加权应该是一个Gaussain加权圆形窗口,西格玛为1.5。我怎么能这样做?我的想法是......像这样,每个重量都填充在一个具有相同尺寸的矩阵中,然后进行计算。

expf = 1.f/(2.f * 1.5 * 1.5);
[...]
W[k] = (i*i + j*j) * expf;

其中i和j是中心像素的距离(例如,第一次迭代i = -7, j = -7

对我来说,这个解决方案似乎很好,但我得到的值总是非常小,例如:

W[0]: 3.48362e-10
W[1]: 6.26123e-09
W[2]: 7.21553e-08
W[3]: 5.3316e-07
W[4]: 2.52596e-06
W[5]: 7.67319e-06
W[6]: 1.49453e-05
[...]
W[40]: 0.000523195
W[41]: 0.000110432
W[42]: 1.49453e-05
W[43]: 1.29687e-06
W[44]: 7.21553e-08
W[45]: 5.3316e-07
W[46]: 9.58266e-06
W[47]: 0.000110432
W[48]: 0.000815988
[...]
W[85]: 0.055638
W[86]: 0.0117436
W[87]: 0.00158933
W[88]: 0.000137913
[...]
W[149]: 7.67319e-06
W[150]: 2.52596e-06
W[151]: 4.53999e-05
W[152]: 0.000523195
W[153]: 0.00386592

可能是,重量的计算错了吗?

1 个答案:

答案 0 :(得分:2)

PDF of a multivariate normal distribution

-k / 2 |Σ| -0.5 exp(-0.5((x-μ)|Σ| -1 < / sup>((x - μ))

对于您的情况,这转换为

double weight(int i, int j, double var) {
    return 1 / (2 * M_PI) * std::exp(-0.5 * (i * i + j * j) / var / var);
}

其中ij的中心位置为0和0,而var是方差。

注意:

  1. 这是PDF。如果您希望值在中心为1,请使用weight(i, j, var) / weight(0, 0, var)。否则,你的确会得到一些小数字。

  2. 衰减由var指定 - 较低的值会显示较大的衰减。

  3. 以下代码打印

    $ g++ --std=c++11 gs.cpp && ./a.out 
    1
    0.884706
    1
    4.78512e-06
    

    例如

    #include <cmath>
    #include <iostream>
    
    double weight(int i, int j, double var) {
        return 1 / (2 * M_PI) * std::exp(-0.5 * (i * i + j * j) / var / var);
    }
    
    int main() {
        {
            const double f = weight(0, 0, 20);
            std::cout << weight(0, 0, 20) / f << std::endl;
            std::cout << weight(-7, -7, 20) / f << std::endl;
        }
        {
            const double f = weight(0, 0, 2);
            std::cout << weight(0, 0, 2) / f << std::endl;
            std::cout << weight(-7, -7, 2) / f << std::endl;
        }
    }