简体   繁体   中英

How to calculate Gaussian-weighted Circular Window?

I have a Matrix with values filled in every Field. The size is eg 15x15(225) now I want to calculate the Weight of every Field based on the Center Field of the Matrix. For a bigger distance, the value of the Pixel will be less weighted for the calculation. This should be look like a circle around the center Field. Here a example Image:

例

The small Rectangle is the centre field. The weighting should be a Gaussain-weighted circular window with a sigma of 1.5. How could I get this done? My thought was sth. like this where every Weight is filled in a Matrix with the same Size for the calculation afterwards.

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

Where i and j are the distanze from the centre pixel (eg for first iteration i = -7, j = -7 )

For me this solution seemed to be fine, but the values I get are always very small eg:

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

Could it be, that the calculation of the weights is wrong?

The PDF of a multivariate normal distribution is

2 π -k / 2 |Σ| -0.5 exp(-0.5 ((x - μ) |Σ| -1 ((x - μ))

For your case, this translates to

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

where i and j are centered at 0 and 0, and var is the variance.

Note:

  1. This is the PDF. If you want the value to be 1 at the center, use weight(i, j, var) / weight(0, 0, var) . Otherwise, you will indeed get small numbers.

  2. The decay is specified by var - lower values will show larger decay.


The following code prints

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

for example

#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;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM