When using the Pillow module to resize an image with a neighbor neighbor I tried to verify from which pixel the value is obtained (neighborhood).
With each algorithm (nearest neighbor, bilinear, bicubic) What the image will look like (whether it will be smooth, etc.) I often see articles that mention about I didn't have much information about what the value of each pixel would be, so I wrote it.
The algorithm itself is simple. The links below will be helpful. I will omit the details here, but In short, it is an algorithm that brings the pixel value of the nearest location as it is. https://algorithm.joho.info/image-processing/nearest-neighbor-linear-interpolation/
I made an image sample for verification
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
A = np.eye(10, dtype=int)
B = np.arange(10, dtype=int) * 20
C = Image.fromarray(B * A)
plt.figure()
plt.imshow(C)
print(np.array(C))
The stored values are as follows
[[ 0 0 0 0 0 0 0 0 0 0]
[ 0 20 0 0 0 0 0 0 0 0]
[ 0 0 40 0 0 0 0 0 0 0]
[ 0 0 0 60 0 0 0 0 0 0]
[ 0 0 0 0 80 0 0 0 0 0]
[ 0 0 0 0 0 100 0 0 0 0]
[ 0 0 0 0 0 0 120 0 0 0]
[ 0 0 0 0 0 0 0 140 0 0]
[ 0 0 0 0 0 0 0 0 160 0]
[ 0 0 0 0 0 0 0 0 0 180]]
It feels like the diagonal elements have a non-zero value.
Let's resize this image with Pillow's resize (nearest neighbor) First, compress the 10x10 original image to 5x5
C_nn5 = C.resize([5, 5], resample=Image.NEAREST)
plt.figure()
plt.imshow(C_nn5)
print(np.array(C_nn5))
[[ 20 0 0 0 0]
[ 0 60 0 0 0]
[ 0 0 100 0 0]
[ 0 0 0 140 0]
[ 0 0 0 0 180]]
Here, as you can see by looking at the value, The nearest neighbor is the pixel's "backward" value (20). For example, the [0, 0] pixels after resizing are Contains the value of [1, 1] pixels of the original image. Also, the [1, 1] pixels after resizing are Contains the [3, 3] pixel value (60) of the original image.
However, it doesn't match the formula I referred to ...? According to the formula, it should be "front" of the pixel
I'(0, 0) = I([0/0.5], [0/0.5]) = I(0, 0) = 0
I'(1, 1) = I([1/0.5], [1/0.5]) = I(2, 2) = 40
So For example, the [0, 0] pixels after resizing are The value (0) of [0, 0] pixels of the original image should be stored
There was an article that solved it for some reason https://qiita.com/yoya/items/3b4a8080516259ece684 (Rather, did it make sense to write this article ...) I see, the pixel start has been changed to 0.5 ...
Then
I'(0, 0) = I([0.5/0.5], [0.5/0.5]) = I(1, 1) = 20
I'(1, 1) = I([1.5/0.5], [1.5/0.5]) = I(3, 3) = 60
And the value matched properly.
Next, compress the original image of 10x10 to 3x3.
[[ 20 0 0]
[ 0 100 0]
[ 0 0 160]]
I'(0, 0) = I([0.5/0.3], [0.5/0.3]) = I(2, 2) = 20
I'(1, 1) = I([1.5/0.3], [1.5/0.3]) = I(5, 5) = 100
I'(2, 2) = I([2.5/0.3], [2.5/0.3]) = I(8, 8) = 160
Yes, the value was correct without any problem.
For nearest neighbor and resize You can calculate the nearest pixel from the formula, Note that the original image starts at "0.5"