I believe the application of lanczos or cubic merely gives you a sample at the given position… but it doesn’t take care of the aliasing that happens when downsampling with high frequency content still there. to prevent that, downsampling always needs a lowpass step. I guess PIL does that implicitly, while OpenCV doesn’t. pyrDown
contains a lowpass step before the decimation but it’s fixed to a scale factor of 0.5.
I’m not into the math. you could apply a gaussian filter of a certain \sigma that is proportional to the scale factor… pyrDown suggests that you’d want a gaussian with \sigma = 2 \cdot \text{scale}.
pyrDown (i.e. scale 0.5) appears to use something that isn’t quite a gaussian, but approaches a gaussian with \sigma = 1: OpenCV: Image Filtering
here’s a gaussian for \sigma = 1 for comparison:
im = np.zeros((5,5))
im[2,2] = 1
out = cv.GaussianBlur(im, ksize=(5,5), sigmaX=1.0) * 256
# array([[ 3.04027, 6.81278, 11.23237, 6.81278, 3.04027],
# [ 6.81278, 15.26638, 25.17 , 15.26638, 6.81278],
# [11.23237, 25.17 , 41.49832, 25.17 , 11.23237],
# [ 6.81278, 15.26638, 25.17 , 15.26638, 6.81278],
# [ 3.04027, 6.81278, 11.23237, 6.81278, 3.04027]])