Which interpolation is best for resizing an image?

I have a numpy array that I want to modify using opencv. Its values ​​range from 0 to 255. If I prefer to use cv2.INTER_CUBIC, I can get values ​​outside this range. This is undesirable since the modified array must still represent the image. One solution is to trim the results to [0, 255]. Another is to use a different interpolation method. I understand that using INTER_AREA is true for sampling the image from below, but works similarly to the nearest neighbor to increase the sampling rate, which makes it less optimal for my purpose.

Should I use INTER_CUBIC (and the clip), INTER_AREA or INTER_LINEAR?

example of values ​​out of range using INTER_CUBIC:

a = np.array( [ 0, 10, 20, 0, 5, 2, 255, 0, 255 ] ).reshape( ( 3, 3 ) )
[[  0  10  20]
 [  0   5   2]
 [255   0 255]]

b = cv2.resize( a.astype('float'), ( 4, 4 ), interpolation = cv2.INTER_CUBIC )
[[   0.            5.42489886   15.43670964   21.29199219]
 [ -28.01513672   -2.46422291    1.62949324  -19.30908203]
 [  91.88964844   25.07939219   24.75106835   91.19140625]
 [ 273.30322266   68.20603609   68.13853455  273.15966797]]

Edit: As Burke pointed out, type conversion to float (from int64) allows values ​​outside the original range. the cv2.resize () function does not work with the standard type "int64". However, converting to 'uint8' will automatically saturate the values ​​to [0..255].

In addition, as SaulloCastro pointed out, another related answer showed intermittent interpolation and that there the defualt method is cubic interpolation (with saturation).

+9
source share
3 answers

, INTER_LINEAR INTER_CUBIC. , INTER_AREA.

, , , . .

+9

, INTER_LINEAR, resize(). ( , INTER_NEAREST). .

+2

, , . , :

# create target image and copy sample image into it
(wt, ht) = imgSize # target image size
(h, w) = img.shape # given image size
fx = w / wt
fy = h / ht
f = max(fx, fy)
newSize = (max(min(wt, int(w / f)), 1),
           max(min(ht, int(h / f)), 1))  # scale according to f (result at least 1 and at most wt or ht)
img = cv2.resize(img, newSize, interpolation=cv2.INTER_CUBIC) #INTER_CUBIC interpolation
target = np.ones([ht, wt]) * 255  # shape=(64,800)
target[0:newSize[1], 0:newSize[0]] = img

openCV:

  • INTER_NEAREST -
  • INTER_LINEAR - ( )
  • INTER_AREA - . , . , INTER_NEAREST.
  • INTER_CUBIC - 4 × 4
  • INTER_LANCZOS4 - Lanczos interpolation in a neighborhood of 8 × 8 pixels

See here for the results in each interpolation.

+1
source

Source: https://habr.com/ru/post/1541929/


All Articles