简体   繁体   English

使用 cv2.resize() 进行图像插值更改整数位置像素

[英]Image interpolation with cv2.resize() changes the integer positon pixel

I'm trying to interpolate up an image with cv2.resize() , while keeping the integer position pixel in new image same as the original image.我正在尝试使用cv2.resize()插入图像,同时保持新图像中的整数位置像素与原始图像相同。 So I wrote this code to test:所以我写了这段代码来测试:

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])

Output:输出:

(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]]

The above code interpolated the image 2x and ideally the two output should be the same, since im[::2,::2,0] should be the pixel before interpolation.上面的代码对图像进行了 2x 插值,理想情况下两个输出应该相同,因为im[::2,::2,0]应该是插值前的像素。

Is there something wrong in the code or anyway to do it properly?代码中是否有问题或无论如何正确执行?

I found an explanation of the OpenCV coordinate system at some point, but it can't find it back, so this answer is from memory.我在某个时候找到了 OpenCV 坐标系的解释,但找不到,所以这个答案来自记忆。

OpenCV sees a pixel as a little square, not a point sample in a grid. OpenCV 将像素视为一个小方块,而不是网格中的点样本。 Interpolation by an integer amount splits up this square into smaller squares.整数量的插值将这个正方形分成更小的正方形。 For even-sized interpolation, none of the new square centers will match the original square center.对于偶数大小的插值,新的方形中心都不会与原始方形中心匹配。

For odd-sized interpolation, one of the new squares will be at the center, but there will also be other new squares to the top and left of the top-left pixel of the original image.对于奇数大小的插值,新方块之一将位于中心,但在原始图像左上角像素的顶部和左侧也会有其他新方块。 These pixels have been extrapolated!这些像素是外推的!

That is, if you think of an image as a set of samples, like I do, then interpolation in OpenCV will never match your expectations.也就是说,如果您像我一样将图像视为一组样本,那么 OpenCV 中的插值将永远不会符合您的期望。

The solution is to shift the image by half an original pixel to the left and up while interpolating.解决方案是在插值时将图像向左和向上移动半个原始像素。 Not sure how to implement that in OpenCV though.不知道如何在 OpenCV 中实现它。

Or you could try skimage.transform.rescale in skimage or diplib.Resampling in DIPlib (I'm an author).或者你可以尝试skimage.transform.rescale在skimage或diplib.Resampling在DIPlib(我是一个作家)。 For the last one, I know it does the right thing out of the box.对于最后一个,我知道它开箱即用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM