Python 哪种插值最适合调整图像大小?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23853632/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 03:32:35  来源:igfitidea点击:

Which kind of interpolation best for resizing image?

pythonopencvnumpyinterpolation

提问by Roee E

I have a numpy array that I wish to resize using opencv. Its values range from 0 to 255. If I opt to use cv2.INTER_CUBIC, I may get values outside this range. This is undesirable, since the resized array is supposed to still represent an image. One solution is to clip the results to [0, 255]. Another is to use a different interpolation method. It is my understanding that using INTER_AREA is valid for down-sampling an image, but works similar to nearest neighbor for upsampling it, rendering it less than optimal for my purpose.

我有一个 numpy 数组,我希望使用 opencv 调整大小。它的值范围从 0 到 255。如果我选​​择使用 cv2.INTER_CUBIC,我可能会得到这个范围之外的值。这是不可取的,因为调整大小的数组应该仍然表示图像。一种解决方案是将结果裁剪为 [0, 255]。另一种是使用不同的插值方法。我的理解是,使用 INTER_AREA 对图像进行下采样是有效的,但与最近邻进行上采样的工作方式类似,这使得它对于我的目的而言不是最佳的。

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

我应该使用 INTER_CUBIC(和剪辑)、INTER_AREA 还是 INTER_LINEAR?

an example for values outside of range using INTER_CUBIC:

使用 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 berak pointed out, converting the type to float (from int64) allows for values outside the original range. the cv2.resize() function does not work with the default 'int64' type. However, converting to 'uint8' will automatically saturate the values to [0..255].

编辑:正如berak所指出的,将类型转换为float(从int64)允许原始范围之外的值。cv2.resize() 函数不适用于默认的“int64”类型。但是,转换为 'uint8' 会自动使值饱和为 [0..255]。

Also, as pointed out by SaulloCastro, another related answer demonstrated scipy's interpolation, and that there the defualt method is the cubic interpolation (with saturation).

此外,正如 SaulloCastro 所指出的,另一个相关的答案展示了 scipy 的插值,并且默认方法是三次插值(具有饱和度)。

回答by Michael Burdinov

I think you should start with INTER_LINEAR which is the default option for resize() function. It combines sufficiently good visual results with sufficiently good time performance (although it is not as fast as INTER_NEAREST). And it won't create those out-of-range values.

我认为您应该从 INTER_LINEAR 开始,它是 resize() 函数的默认选项。它结合了足够好的视觉效果和足够好的时间性能(虽然它不如 INTER_NEAREST 快)。它不会创建那些超出范围的值。

回答by Shivam Kushwaha

If you are enlargingthe image, you should prefer to use INTER_LINEARor INTER_CUBICinterpolation. If you are shrinkingthe image, you should prefer to use INTER_AREAinterpolation.

如果您要放大图像,您应该更喜欢使用INTER_LINEARINTER_CUBIC插值。如果您要缩小图像,您应该更喜欢使用INTER_AREA插值。

Cubic interpolation is computationally more complex, and hence slower than linear interpolation. However, the quality of the resulting image will be higher.

三次插值在计算上更复杂,因此比线性插值慢。但是,生成的图像的质量会更高。

回答by susan097

To overcome such problem you should find out the new size of the given image where the interpolation can be made. And copy interpolated sampled image on the target image like:

为了克服这样的问题,您应该找出可以进行插值的给定图像的新尺寸。并在目标图像上复制内插采样图像,例如:

# 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

Some of the possible interpolation in openCV are:

openCV 中的一些可能的插值是:

  • INTER_NEAREST – a nearest-neighbor interpolation
  • INTER_LINEAR – a bilinear interpolation (used by default)
  • INTER_AREA – resampling using pixel area relation. It may be a preferred method for image decimation, as it gives mtheitroade'-free results. But when the image is zoomed, it is similar to the INTER_NEAREST method.
  • INTER_CUBIC – a bicubic interpolation over 4×4 pixel neighborhood
  • INTER_LANCZOS4 – a Lanczos interpolation over 8×8 pixel neighborhood
  • INTER_NEAREST – 最近邻插值
  • INTER_LINEAR – 双线性插值(默认使用)
  • INTER_AREA – 使用像素区域关系重新采样。它可能是图像抽取的首选方法,因为它提供无摩尔纹的结果。但是当图像放大时,它类似于 INTER_NEAREST 方法。
  • INTER_CUBIC – 4×4 像素邻域上的双三次插值
  • INTER_LANCZOS4 – 8×8 像素邻域上的 Lanczos 插值

See herefor results in each interpolation.

有关每个插值的结果,请参见此处