question about generateGaussianKernels function
SunnyWuYang opened this issue · 1 comments
generateGaussianKernels()
function uses gaussian kernels generated from generateGaussianKernels()
, however, (for example) the third image from the top of the 2nd octave don't have a blur factor=4*sigma
gaussian kernel generated by generateGaussianKernels()
:[1.6, 1.2262735, 1.54500779, 1.94658784, 2.452547, 3.09001559]
1st octave:[1.6, sqrt(1.6 ** 2 + 1.22627 ** 2)=2.01587, sqrt(2.01587 ** 2 + 1.54501 ** 2) = 2.53984, sqrt(2.53984 ** 2 + 1.94659 ** 2) = 3.2, sqrt(3.2**2 + 2.452547**2)=4.03174, sqrt(4.03174**2 + 3.090015**2)=5.07967]
2nd octave: [3.2, sqrt(3.2 ** 2 + 1.22627 ** 2)=3.42691, sqrt(3.426913**2 + 1.54501 ** 2)=3.75909, sqrt(3.75909**2 + 1.94659 ** 2)=4.233198, sqrt(4.233198**2 + 2.452547**2)=4.892336, sqrt(4.892336**2 + 3.090015**2)=5.78646]
2nd_octave[-3] != 4*1.6
HI @SunnyWuYang, I'm sorry for the extremely long wait.
This confusion is caused by the fact that we are downsampling the image by a factor of 2 between each octave. The Gaussian smoothing is done in the units of the current octave. Remember that one pixel in an octave actually corresponds to 2 pixels in the previous octave. So your kernel computation would look like this:
1st octave in 1st octave pixel units: [1.6, sqrt(1.6 ** 2 + 1.22627 ** 2)=2.01587, sqrt(2.01587 ** 2 + 1.54501 ** 2) = 2.53984, sqrt(2.53984 ** 2 + 1.94659 ** 2) = 3.2, sqrt(3.2**2 + 2.452547**2)=4.03174, sqrt(4.03174**2 + 3.090015**2)=5.07967]
2nd octave in 2nd octave pixel units: [1.6, sqrt(1.6 ** 2 + 1.22627 ** 2)=2.01587, sqrt(2.01587 ** 2 + 1.54501 ** 2) = 2.53984, sqrt(2.53984 ** 2 + 1.94659 ** 2) = 3.2, sqrt(3.2**2 + 2.452547**2)=4.03174, sqrt(4.03174**2 + 3.090015**2)=5.07967]
(numbers are identical to the 1st octave)
2nd octave in 1st octave pixel units: [2 * 1.6 = 3.2, 2 * 2.01587 = 4.03174, 2 * 2.53984 = 5.07968 , 2 * 3.2 = 6.4, 2 * 4.03174 = 8.06348, 2 * 5.07967 = 10.15934]
(upsample everything by 2)
In other words, after computing the 2nd octave blurs in the 2nd octave pixel units, you have to multiply everything by 2 to convert to 1st octave pixel units. Now you have 2nd_octave[-3] == 4 * 1.6
in 1st octave pixel units.
Also, you can see that OpenCV computes this in exactly the same way I do. Although the way they write it is a little confusing, it's mathematically equivalent to PythonSIFT. See the function definition for SIFT_Impl::buildGaussianPyramid
here:
https://github.com/opencv/opencv/blob/master/modules/features2d/src/sift.dispatch.cpp
If you feel this still doesn't answer your question, feel free to reopen this issue.