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

时间:2014-05-25 09:00:51

标签: python opencv numpy interpolation

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

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

使用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]]

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

另外,正如SaulloCastro指出的那样,另一个相关的答案显示了scipy的插值,并且defualt方法是三次插值(饱和度)。

3 个答案:

答案 0 :(得分:4)

如果您要放大图像,则最好使用 INTER_LINEAR INTER_CUBIC 插值。 如果您要缩小图像,则应该使用 INTER_AREA 插值。

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

答案 1 :(得分:2)

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

答案 2 :(得分: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 –在8×8像素邻域上的Lanczos插值

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