# Fitting a gaussian image using opencv

I'm reading through the opencv documentation and some questions in SO but it doesn't seem to provide this information.

I've an image $I(x,y)$ and I want to find a gaussian function $f_{\mu,\Sigma}(x,y)$ such that $$f_{\mu,\Sigma}(x,y) \approx I(x,y)$$ using LSE or MLE estimation. $\mu$ is the mean vector and $\Sigma$ is the covariance matrix. My question is if there's any opencv function that perform such task.

People suggest to implement the estimator from scratch, though some suggested to use LM algorithm for such purpose, and in general doesn't seem very difficult I wonder if there's any function for such purpose.

Is there any?

Thank you

• Do you mean the values of the Pixels (Which Gaussian Generator fits best to generate them) or the spatial Gaussian Function best fitted to the image? The question seems to suggest the 2nd option which doesn't make sense. – Royi May 12 '18 at 8:30

It doesn't seem quite as obvious as you say. I can't manage to retrieve the value of sigma with moments. Here's a reproductible code :

import cv2
import numpy as np

for i in range(1,100,5):
x, y = np.meshgrid(np.linspace(-1,1,250), np.linspace(-1,1,250))
d = np.sqrt(x*x+y*y)
sigma, mu = i/100, 0.0
im = np.exp(-( (d-mu)**2 / ( 2.0 * sigma**2 ) ) )
ms = cv2.moments(im)

w = np.sqrt(ms['mu20']/ms['m00'])
h = np.sqrt(ms['mu02']/ms['m00'])

x = ms['m10']/ms['m00']
y = ms['m01']/ms['m00']

#w,h should be proportionnal to sigma
print(x,w,y,h)


which outputs :

124.50000000000003 1.2450000000043133 124.5 1.2450000000067136
124.50000000000004 7.46999999999997 124.50000000000004 7.469999999999793
124.5 13.695000000000055 124.50000000000003 13.694999999999826
124.49999999999996 19.919999860176716 124.49999999999991 19.91999986017709
124.49999999999994 26.14445837769508 124.49999999999991 26.144458377695315
124.50000000000004 32.341175190026235 124.50000000000003 32.341175190026235
124.49999999999996 38.330785155074466 124.49999999999999 38.330785155074466
124.50000000000007 43.78215361374663 124.50000000000001 43.78215361374682
124.50000000000001 48.456482631148084 124.49999999999999 48.4564826311482
124.50000000000001 52.311348835800736 124.49999999999997 52.311348835800885
124.49999999999997 55.43113033682788 124.49999999999996 55.43113033682795
124.50000000000006 57.94254510306185 124.50000000000007 57.942545103061796
124.50000000000004 59.96906667795289 124.50000000000007 59.96906667795291
124.50000000000003 61.614844668595225 124.50000000000001 61.61484466859529
124.49999999999996 62.96253286135033 124.50000000000004 62.96253286135014
124.5 64.07604806231855 124.50000000000003 64.07604806231855
124.5 65.00437844448308 124.50000000000003 65.00437844448301
124.49999999999996 65.78506419998082 124.49999999999999 65.78506419998084
124.5 66.44700119861258 124.50000000000001 66.44700119861257
124.49999999999999 67.01258437680303 124.50000000000003 67.01258437680295


I tried other approaches but nothing seems to work.

I'd like to have the sigma in number of pixels, or the actual sigma from the gaussian definition, but i can retrieve neither. Would you tell me a bit more about how to proceed please ?

(ps I'm sorry I don't have the reputation points to comment directly your answer, which is weird)

• It's not clear to me what you're expecting vs what you get? Can you expand on that a bit? Discretization and limit effects will stop the moments being accurate for small and large values of i. – Peter K. May 1 '18 at 16:18

One simple approach is to compute the image moments. The OpenCV function moments does this.

m00 says something about the intensity scaling, m01 and m10 give the origin of the Gaussian, and mu20 and mu02 give the variances along the axes. If the Gaussian can be rotated, you need to include mu11 in the mix. These three last values then form the covariance matrix of the Gaussian.

That is,

\begin{aligned} \mu &= [\texttt{m10}, \texttt{m01}]^T\\ \Sigma &= \begin{bmatrix} \texttt{m20}, \texttt{m11} \\ \texttt{m11}, \texttt{m02}\end{bmatrix} \end{aligned}

• Can you please provide information as to how to extract the sigma attribute of the gaussian thanks to moments ? – Damien MENIGAUX Apr 29 '18 at 15:29
• @DamienMENIGAUX: sigma is the standard deviation of the Gaussian, so the square root of the variance is sigma. – Cris Luengo Apr 30 '18 at 1:17
• Hi, out of curiosity is this approach based on the characteristic function? – user8469759 May 30 '18 at 15:34
• If you are referring to the Fourier transform of the probability density function, then no, this is not related to that. But if you see your image as a probability density function, then its moments describe that probability density function. The Gaussian distribution has the nice property that it is completely described by the first two moments, corresponding to its mean and variance. – Cris Luengo May 30 '18 at 15:44