问题:大小调整/缩放图像
回答 0
是的,您可以安装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)
img
因此,这是一个包含原始图像res
的numpy数组,而这是一个包含调整大小的图像的numpy数组。interpolation
参数的一个重要方面是:有几种方法可以调整图像的大小。特别是因为你缩小图像,而原图像的大小是不是调整后的图像的大小的倍数。可能的插值方案为:
INTER_NEAREST
-最近邻插值INTER_LINEAR
-双线性插值(默认使用)INTER_AREA
-使用像素面积关系进行重采样。这可能是首选的图像抽取方法,因为它可提供无波纹的结果。但是,当图像放大时,它与INTER_NEAREST
方法类似 。INTER_CUBIC
-在4×4像素邻域上的双三次插值INTER_LANCZOS4
-在8×8像素邻域上进行Lanczos插值
与大多数选项一样,就每种调整大小模式而言,也没有“最佳”选项,在某些情况下,一种策略可能比另一种策略更可取。
回答 1
尽管可以单独使用numpy来执行此操作,但该操作不是内置的。也就是说,您可以使用scikit-image
(基于numpy构建)执行这种图像处理。
Scikit-Image重缩放文档在此处。
例如,您可以对图像执行以下操作:
from skimage.transform import resize
bottle_resized = resize(bottle, (140, 54))
这将为您处理插值,抗锯齿等问题。
回答 2
对于来自Google的人们来说,他们正在寻找一种快速降序对numpy
数组图像进行下采样以供机器学习应用程序使用的方法,这是一种超快速方法(从此处改编)。仅当输入尺寸为输出尺寸的倍数时,此方法才有效。
以下示例将采样率从128×128降采样为64×64(可以轻松更改)。
频道最后订购
# 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)
渠道第一订购
# 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)
对于灰度图像,只需将更3
改为1
如下所示:
渠道第一订购
# 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)
此方法使用的是最大池化。我发现这是最快的方法。
回答 3
如果有人来这里寻找一种简单的方法来在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)]
用法示例:将(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))
这可以缩小/缩放图像,并且可以与numpy数组一起使用。
回答 4
SciPy的imresize()
方法是另一种调整大小的方法,但是将从SciPy v 1.3.0开始将其删除。SciPy指的是PIL图像调整大小方法:Image.resize(size, resample=0)
size –请求的大小(以像素为单位),为2元组:(宽度,高度)。
重采样 –可选的重采样过滤器。这可以是PIL.Image.NEAREST(使用最近的邻居),PIL.Image.BILINEAR(线性插值),PIL.Image.BICUBIC(三次样条插值)或PIL.Image.LANCZOS(高质量的下采样滤波器)之一)。如果省略,或者图像的模式为“ 1”或“ P”,则将其设置为PIL.Image.NEAREST。
链接到这里:https : //pillow.readthedocs.io/en/3.1.x/reference/Image.html#PIL.Image.Image.resize
回答 5
是否有任何库可以在numpy / SciPy中执行此操作
当然。您可以在没有OpenCV,scikit-image或PIL的情况下执行此操作。
图像调整大小基本上是将每个像素的坐标从原始图像映射到其调整大小的位置。
由于图像的坐标必须是整数(将其视为矩阵),因此,如果映射的坐标具有十进制值,则应插值像素值以使其接近整数位置(例如,已知最接近该位置的像素)作为最近邻插值)。
您所需要做的就是为您执行此插值的功能。SciPy有interpolate.interp2d
。
您可以使用它来调整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))
当然,如果您的图像是RGB,则必须对每个通道执行插值。
如果您想了解更多信息,建议您观看“ 调整图像大小-Computerphile”。
回答 6
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)