使用 cv2.resize() 的图像插值会更改整数位置像素
Image interpolation with cv2.resize() changes the integer positon pixel
我正在尝试使用 cv2.resize()
对图像进行插值,同时保持新图像中的整数位置像素与原始图像相同。所以我写了这段代码来测试:
import cv2, scipy
import scipy.misc
import numpy as np
im = cv2.imread('img')
print(im[:,:,0].shape)
print(im[:,:,0])
im = cv2.resize(im, None, fx=2, fy=2, interpolation=cv2.INTER_LANCZOS4)
print(im[::2,::2,0].shape)
print(im[::2,::2,0])
输出:
(128, 128)
[[79 62 64 ... 81 81 79]
[73 59 57 ... 79 81 79]
[69 51 51 ... 90 88 87]
...
[40 48 43 ... 79 84 88]
[45 46 44 ... 84 84 83]
[48 46 44 ... 80 80 83]]
(128, 128)
[[82 66 63 ... 82 81 80]
[76 64 57 ... 80 79 79]
[71 57 50 ... 90 85 85]
...
[38 46 45 ... 77 84 87]
[43 46 45 ... 83 84 84]
[48 47 44 ... 81 81 82]]
上面的代码对图像进行了 2x 插值,理想情况下两个输出应该相同,因为 im[::2,::2,0]
应该是插值前的像素。
代码中是否有错误或是否正确执行?
我在某处找到了OpenCV坐标系的解释,但找不到了,所以这个答案是靠记忆的。
OpenCV 将像素视为一个小方块,而不是网格中的点样本。整数值的插值将这个正方形分成更小的正方形。对于均匀大小的插值,none 个新方形中心将与原始方形中心匹配。
对于奇数插值,其中一个新方块将位于中心,但在原始图像左上角像素的顶部和左侧也会有其他新方块。这些像素已被外推!
也就是说,如果您像我一样将图像视为一组样本,那么 OpenCV 中的插值永远不会符合您的期望。
解决方法是在插值的同时将图像向左和向上移动半个原始像素。虽然不确定如何在 OpenCV 中实现它。
或者您可以在 DIPlib 中尝试 skimage.transform.rescale
in skimage or diplib.Resampling
(我是作者)。对于最后一个,我知道它开箱即用。
我正在尝试使用 cv2.resize()
对图像进行插值,同时保持新图像中的整数位置像素与原始图像相同。所以我写了这段代码来测试:
import cv2, scipy
import scipy.misc
import numpy as np
im = cv2.imread('img')
print(im[:,:,0].shape)
print(im[:,:,0])
im = cv2.resize(im, None, fx=2, fy=2, interpolation=cv2.INTER_LANCZOS4)
print(im[::2,::2,0].shape)
print(im[::2,::2,0])
输出:
(128, 128)
[[79 62 64 ... 81 81 79]
[73 59 57 ... 79 81 79]
[69 51 51 ... 90 88 87]
...
[40 48 43 ... 79 84 88]
[45 46 44 ... 84 84 83]
[48 46 44 ... 80 80 83]]
(128, 128)
[[82 66 63 ... 82 81 80]
[76 64 57 ... 80 79 79]
[71 57 50 ... 90 85 85]
...
[38 46 45 ... 77 84 87]
[43 46 45 ... 83 84 84]
[48 47 44 ... 81 81 82]]
上面的代码对图像进行了 2x 插值,理想情况下两个输出应该相同,因为 im[::2,::2,0]
应该是插值前的像素。
代码中是否有错误或是否正确执行?
我在某处找到了OpenCV坐标系的解释,但找不到了,所以这个答案是靠记忆的。
OpenCV 将像素视为一个小方块,而不是网格中的点样本。整数值的插值将这个正方形分成更小的正方形。对于均匀大小的插值,none 个新方形中心将与原始方形中心匹配。
对于奇数插值,其中一个新方块将位于中心,但在原始图像左上角像素的顶部和左侧也会有其他新方块。这些像素已被外推!
也就是说,如果您像我一样将图像视为一组样本,那么 OpenCV 中的插值永远不会符合您的期望。
解决方法是在插值的同时将图像向左和向上移动半个原始像素。虽然不确定如何在 OpenCV 中实现它。
或者您可以在 DIPlib 中尝试 skimage.transform.rescale
in skimage or diplib.Resampling
(我是作者)。对于最后一个,我知道它开箱即用。