Python Numpy 调整大小/重新缩放图像
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/48121916/
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
Numpy Resize/Rescale Image
提问by Brian Hamill
I would like to take an image and change the scale of the image, while it is a numpy array.
我想拍摄图像并更改图像的比例,而它是一个 numpy 数组。
For example I have this image of a coca-cola bottle: bottle-1
例如,我有一个可口可乐瓶的图像: bottle-1
Which translates to a numpy array of shape (528, 203, 3)
and I want to resize that to say the size of this second image:
bottle-2
这转化为一个 numpy 形状数组,(528, 203, 3)
我想调整它的大小以说明第二个图像的大小:
bottle-2
Which has a shape of (140, 54, 3)
.
其形状为(140, 54, 3)
。
How do I change the size of the image to a certain shape while still maintaining the original image? Other answers suggest stripping every other or third row out, but what I want to do is basically shrink the image how you would via an image editor but in python code. Are there any libraries to do this in numpy/SciPy?
如何在保持原始图像的同时将图像的大小更改为特定形状?其他答案建议每隔一行或第三行剥离,但我想要做的基本上是通过图像编辑器但在 python 代码中缩小图像。在 numpy/SciPy 中是否有任何库可以执行此操作?
回答by Willem Van Onsem
Yeah, you can install opencv
(this is a library used for image processing, and computer vision), and use the cv2.resize
function. And for instance use:
是的,你可以安装opencv
(这是一个用于图像处理和计算机视觉的库),并使用该cv2.resize
功能。例如使用:
import cv2
import numpy as np
img = cv2.imread('your_image.jpg')
res = cv2.resize(img, dsize=(54, 140), interpolation=cv2.INTER_CUBIC)
Here img
is thus a numpy array containing the original image, whereas res
is a numpy array containing the resizedimage. An important aspect is the interpolation
parameter: there are several ways how to resize an image. Especially since you scale down the image, and the size of the original image is nota multiple of the size of the resized image. Possible interpolation schemas are:
img
因此,这是一个包含原始图像res
的 numpy 数组,而一个包含调整大小的图像的 numpy 数组。一个重要的方面是interpolation
参数:有几种方法可以调整图像大小。特别是因为你缩小图像,而原图像的大小是不是调整后的图像的大小的倍数。可能的插值模式是:
INTER_NEAREST
- a nearest-neighbor interpolationINTER_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 theINTER_NEAREST
method.INTER_CUBIC
- a bicubic interpolation over 4x4 pixel neighborhoodINTER_LANCZOS4
- a Lanczos interpolation over 8x8 pixel neighborhood
INTER_NEAREST
- 最近邻插值INTER_LINEAR
- 双线性插值(默认使用)INTER_AREA
- 使用像素区域关系重新采样。它可能是图像抽取的首选方法,因为它提供无摩尔纹的结果。但是当图像被放大时,它的INTER_NEAREST
方法是类似的 。INTER_CUBIC
- 4x4 像素邻域上的双三次插值INTER_LANCZOS4
- 8x8 像素邻域上的 Lanczos 插值
Like with most options, there is no "best" option in the sense that for every resize schema, there are scenarios where one strategy can be preferred over another.
与大多数选项一样,没有“最佳”选项,因为对于每个调整大小模式,在某些情况下,一种策略可能优于另一种策略。
回答by jakevdp
While it might be possible to use numpy alone to do this, the operation is not built-in. That said, you can use scikit-image
(which is built on numpy) to do this kind of image manipulation.
虽然可以单独使用 numpy 来执行此操作,但该操作不是内置的。也就是说,您可以使用scikit-image
(基于 numpy)来进行这种图像处理。
Scikit-Image rescaling documentation is here.
Scikit-Image 重新缩放文档在这里。
For example, you could do the following with your image:
例如,您可以对图像执行以下操作:
from skimage.transform import resize
bottle_resized = resize(bottle, (140, 54))
This will take care of things like interpolation, anti-aliasing, etc. for you.
这将为您处理诸如插值、抗锯齿等问题。
回答by Waylon Flinn
For people coming here from Google looking for a fast way to downsample images in numpy
arrays for use in Machine Learning applications, here's a super fast method (adapted from here). This method only works when the input dimensions are a multiple of the output dimensions.
对于从 Google 来到这里寻找一种快速方法来对numpy
数组中的图像进行下采样以用于机器学习应用程序的人,这里有一种超快速方法(改编自此处)。此方法仅在输入维度是输出维度的倍数时有效。
The following examples downsample from 128x128 to 64x64 (this can be easily changed).
以下示例将采样从 128x128 降为 64x64(这可以轻松更改)。
Channels last ordering
频道最后排序
# large image is shape (128, 128, 3)
# small image is shape (64, 64, 3)
input_size = 128
output_size = 64
bin_size = input_size // output_size
small_image = large_image.reshape((output_size, bin_size,
output_size, bin_size, 3)).max(3).max(1)
Channels first ordering
渠道优先排序
# large image is shape (3, 128, 128)
# small image is shape (3, 64, 64)
input_size = 128
output_size = 64
bin_size = input_size // output_size
small_image = large_image.reshape((3, output_size, bin_size,
output_size, bin_size)).max(4).max(2)
For grayscale images just change the 3
to a 1
like this:
对于灰度图像只是改变了3
一个1
这样的:
Channels first ordering
渠道优先排序
# large image is shape (1, 128, 128)
# small image is shape (1, 64, 64)
input_size = 128
output_size = 64
bin_size = input_size // output_size
small_image = large_image.reshape((1, output_size, bin_size,
output_size, bin_size)).max(4).max(2)
This method uses the equivalent of max pooling. It's the fastest way to do this that I've found.
此方法使用等效于最大池化。这是我找到的最快的方法。
回答by Romwell
If anyone came here looking for a simple method to scale/resize an image in Python, without using additional libraries, here's a very simple image resize function:
如果有人来这里寻找一种在 Python 中缩放/调整图像大小的简单方法,而不使用其他库,这里有一个非常简单的图像调整大小函数:
#simple image scaling to (nR x nC) size
def scale(im, nR, nC):
nR0 = len(im) # source number of rows
nC0 = len(im[0]) # source number of columns
return [[ im[int(nR0 * r / nR)][int(nC0 * c / nC)]
for c in range(nC)] for r in range(nR)]
Example usage: resizing a (30 x 30) image to (100 x 200):
用法示例:将 (30 x 30) 图像调整为 (100 x 200):
import matplotlib.pyplot as plt
def sqr(x):
return x*x
def f(r, c, nR, nC):
return 1.0 if sqr(c - nC/2) + sqr(r - nR/2) < sqr(nC/4) else 0.0
# a red circle on a canvas of size (nR x nC)
def circ(nR, nC):
return [[ [f(r, c, nR, nC), 0, 0]
for c in range(nC)] for r in range(nR)]
plt.imshow(scale(circ(30, 30), 100, 200))
This works to shrink/scale images, and works fine with numpy arrays.
这适用于缩小/缩放图像,并且适用于 numpy 数组。
回答by cemsazara
SciPy's imresize()
method was another resize method, but it will be removed starting with SciPy v 1.3.0 . SciPy refers to PILimage resize method: Image.resize(size, resample=0)
SciPy 的imresize()
方法是另一种调整大小的方法,但它将从 SciPy v 1.3.0 开始被删除。SciPy 指的是PIL图像大小调整方法:Image.resize(size, resample=0)
size– The requested size in pixels, as a 2-tuple: (width, height).
resample– An optional resampling filter. This can be one of PIL.Image.NEAREST (use nearest neighbour), PIL.Image.BILINEAR (linear interpolation), PIL.Image.BICUBIC (cubic spline interpolation), or PIL.Image.LANCZOS (a high-quality downsampling filter). If omitted, or if the image has mode “1” or “P”, it is set PIL.Image.NEAREST.
size– 请求的像素大小,作为 2 元组:(宽度,高度)。
resample– 一个可选的重采样过滤器。这可以是 PIL.Image.NEAREST(使用最近邻)、PIL.Image.BILINEAR(线性插值)、PIL.Image.BICUBIC(三次样条插值)或 PIL.Image.LANCZOS(高质量下采样滤波器)之一)。如果省略,或者图像具有模式“1”或“P”,则设置为 PIL.Image.NEAREST。
Link here: https://pillow.readthedocs.io/en/3.1.x/reference/Image.html#PIL.Image.Image.resize
链接在这里:https: //pillow.readthedocs.io/en/3.1.x/reference/Image.html#PIL.Image.Image.resize
回答by yellow01
Are there any libraries to do this in numpy/SciPy
在 numpy/SciPy 中是否有任何库可以执行此操作
Sure. You can do this without OpenCV, scikit-image or PIL.
当然。您可以在没有 OpenCV、scikit-image 或 PIL 的情况下执行此操作。
Image resizing is basically mapping the coordinates of each pixel from the original image to its resized position.
图像大小调整基本上是将每个像素的坐标从原始图像映射到其调整大小的位置。
Since the coordinates of an image must be integers (think of it as a matrix), if the mapped coordinate has decimal values, you should interpolate the pixel value to approximate it to the integer position (e.g. getting the nearest pixel to that position is known as Nearest neighbor interpolation).
由于图像的坐标必须是整数(将其视为矩阵),如果映射的坐标具有十进制值,则应插入像素值以将其近似为整数位置(例如,已知距离该位置最近的像素作为最近邻插值)。
All you need is a function that does this interpolation for you. SciPy has interpolate.interp2d
.
您所需要的只是一个为您执行此插值的函数。SciPy 有interpolate.interp2d
.
You can use it to resize an image in numpy array, say arr
, as follows:
您可以使用它来调整 numpy 数组中的图像大小,例如arr
,如下所示:
W, H = arr.shape[:2]
new_W, new_H = (600,300)
xrange = lambda x: np.linspace(0, 1, x)
f = interp2d(xrange(W), xrange(H), arr, kind="linear")
new_arr = f(xrange(new_W), xrange(new_H))
Of course, if your image is RGB, you have to perform the interpolation for each channel.
当然,如果您的图像是RGB,则必须对每个通道进行插值。
If you would like to understand more, I suggest watching Resizing Images - Computerphile.
如果您想了解更多,我建议您观看Resizing Images - Computerphile。
回答by M. Farzalizadeh
import cv2
import numpy as np
image_read = cv2.imread('filename.jpg',0)
original_image = np.asarray(image_read)
width , height = 452,452
resize_image = np.zeros(shape=(width,height))
for W in range(width):
for H in range(height):
new_width = int( W * original_image.shape[0] / width )
new_height = int( H * original_image.shape[1] / height )
resize_image[W][H] = original_image[new_width][new_height]
print("Resized image size : " , resize_image.shape)
cv2.imshow(resize_image)
cv2.waitKey(0)