Reputation: 125
I am using this:
blur = cv2.GaussianBlur(dst,(5,5),0)
And I wanted to show the kernel matrix by this:
print(cv2.getGaussianKernel(ksize=(5,5),sigma=0))
But I am getting a type error:
TypeError: an integer is required (got type tuple)
If I only put 5, I get a 5x1 matrix. Isn't the blur kernel 5x5? Or am I missing on something fundamental?
Upvotes: 7
Views: 19559
Reputation: 21
I think this is what the OP needed. The other answers were also correct, but this is a little simpler and straight to the point if you're looking for a quick answer.
import cv2
import numpy
oneD_kernel = cv2.getGaussianKernel(5, sigma=0)
twoD_kernel = oneD_kernel*oneD_kernel.T
print(twoD_kernel)
print(twoD_kernel.sum())
and it returns:
array([[0.00390625, 0.015625 , 0.0234375 , 0.015625 , 0.00390625],
[0.015625 , 0.0625 , 0.09375 , 0.0625 , 0.015625 ],
[0.0234375 , 0.09375 , 0.140625 , 0.09375 , 0.0234375 ],
[0.015625 , 0.0625 , 0.09375 , 0.0625 , 0.015625 ],
[0.00390625, 0.015625 , 0.0234375 , 0.015625 , 0.00390625]])
1.0
The sum of the 2D kernel also returns 1.0, in case you're wondering.
Upvotes: 2
Reputation: 351
To get the 5x5 Gaussian kernel first we can form a 7x7 Numpy array with only one 1 in the middle.
img=np.zeros((7,7))
img[3,3]=1
img
The result of the code is
array([[0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 1., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0.]])
Then apply gaussian blur:
img1 = cv2.GaussianBlur(img, (5, 5), 0)
img1
The result is:
array([[0. , 0. , 0. , 0. , 0. ,0. , 0. ],
[0. , 0.00390625, 0.015625 , 0.0234375 , 0.015625 ,0.00390625, 0. ],
[0. , 0.015625 , 0.0625 , 0.09375 , 0.0625 ,0.015625 , 0. ],
[0. , 0.0234375 , 0.09375 , 0.140625 , 0.09375 ,0.0234375 , 0. ],
[0. , 0.015625 , 0.0625 , 0.09375 , 0.0625 ,0.015625 , 0. ],
[0. , 0.00390625, 0.015625 , 0.0234375 , 0.015625 ,0.00390625, 0. ],
[0. , 0. , 0. , 0. , 0. ,0. , 0. ]])
The nonzero numbers are the Gaussian kernel. We can confirm that the sum of the numbers are 1:
np.sum(img1)
1.0
Upvotes: 7
Reputation: 41
As you can see in this example:
taken from https://theailearner.com/tag/cv2-getgaussiankernel/
We can get the dot product of the gaussian kernel with itself transposed.
First we get the 1d kernel:
k = cv2.getGaussianKernel(kSize, -1)
Then we can restore its original form before normalization just from the fact that the first element is always originally equals 1:
k /= k[0,0]
Now we can get the dot product as mentioned:
print(k @ k.T)
If you want it summed up to 1 (normalized), divide it by its sum:
kernel = k @ k.T
kernel /= kernel.sum()
print(kernel)
Upvotes: 4
Reputation: 60484
The Gaussian kernel is separable. Therefore, the kernel generated is 1D. The GaussianBlur
function applies this 1D kernel along each image dimension in turn. The separability property means that this process yields exactly the same result as applying a 2D convolution (or 3D in case of a 3D image). But the amount of work is strongly reduced. For your 5x5 kernel, the 2D convolution does 25 multiplications and additions, the separable implementation does only 5+5=10. For larger kernels, the gains are increasingly significant.
To see the full 2D kernel, apply the GaussianBlur
function to an image that is all zeros and has a single pixel in the middle set to 1. This is the discrete equivalent to the Dirac delta function, which we can use to analyze linear time-invariant functions (==convolution filters).
Upvotes: 12