[英]Resize image in python without using resize() - nearest neighbor
For an assignment I want to resize a.jpg image with a python code, but without using the pil.image.resize() function or another similar function.对于作业,我想使用 python 代码调整 a.jpg 图像的大小,但不使用 pil.image.resize() function 或其他类似的 function。 I want to write the code myself but I can't figure out how.
我想自己写代码,但我不知道怎么写。 The image is RGB.
图像是 RGB。 I have found this can be solved by nearest neighbor interpolation (as well as other methods but this one is fine for my specific assignment).
我发现这可以通过最近邻插值来解决(以及其他方法,但这对于我的特定任务来说很好)。 The height and the width should both be able to be made bigger or smaller.
高度和宽度都应该可以变大或变小。 So far I only have this:
到目前为止,我只有这个:
import numpy as np
import scipy as sc
import matplotlib as plt
import math
import PIL
from PIL import Image
img = np.array(Image.open("foto1.jpg"))
height = img.shape[0]
width = img.shape[1]
dim = img.shape[2]
new_h = int(input("New height: "))
new_w = int(input("New width: "))
imgR = img[:,:,0] #red pixels
imgG = img[:,:,1] #green pixels
imgB = img[:,:,2] #blue pixels
newR = np.empty([new_h, new_w])
newG = np.empty([new_h, new_w])
newB = np.empty([new_h, new_w])
So now all three colours have a new array of the right dimensions.所以现在所有三种颜色都有一个正确尺寸的新数组。 Unfortunately on the web I can only find people who use resize() functions... Does anyone know?
不幸的是,在 web 上,我只能找到使用 resize() 函数的人......有人知道吗?
Thank in advance!预先感谢!
The key to doing any image transformation like resizing is to have a mapping from output coordinates to input coordinates.进行任何图像转换(如调整大小)的关键是要有一个从输出坐标到输入坐标的映射。 Then you can simply iterate over the entire output and grab a pixel from the input.
然后您可以简单地遍历整个输出并从输入中获取一个像素。 Nearest neighbor makes this particularly easy, because there's never a need to interpolate a pixel that doesn't lie exactly on integer coordinates - you simply round the coordinates to the nearest integer.
最近的邻居使这特别容易,因为永远不需要插入一个不完全位于整数坐标上的像素 - 您只需将坐标四舍五入到最近的整数。
for new_y in range(new_h):
old_y = int(round(new_y * (new_h - 1) / (height - 1)))
if old_y < 0: old_y = 0
if old_y >= height: old_y = height - 1
for new_x in range(new_w):
old_x = int(round(new_x * (new_w - 1) / (width - 1)))
if old_x < 0: old_x = 0
if old_x >= width: old_x = width - 1
newR[new_y,new_x] = imgR[old_y,old_x]
newG[new_y,new_x] = imgG[old_y,old_x]
newB[new_y,new_x] = imgB[old_y,old_x]
This can only be used to resize to a dimension of (x * n or x//n, y * n or y//n, 3) , where x, y, 3 are the width, height and channels of the image and n is any natural number.这只能用于调整尺寸为(x * n 或 x//n, y * n 或 y//n, 3) ,其中 x, y, 3 是图像的宽度、高度和通道n 是任意自然数。
def resize_img(image, resize_width, resize_height):
"""
:params
image: shape -> (width, height, channels)
resize_width: The resize width dimension.
It could be something like x*n or x//n,
where x is the width of the image and n
could be any natural number.
resize_height: The resize width dimension.
It could be something like y*n or y//n,
where x is the width of the image and n
could be any natural number.
:returns
array of shape -> (resized_width, resized_height, channels)
"""
original_width, original_height, channel = image.shape
red_channel = image[:, :, 0]
green_channel = image[:, :, 1]
blue_channel = image[:, :, 2]
resized_image = np.zeros((resize_width, resize_height, channel), dtype=np.uint8)
resized_image[:, :, 0] = red_channel[0::original_width//resize_width, 0::original_height//resize_height]
resized_image[:, :, 1] = green_channel[0::original_width//resize_width, 0::original_height//resize_height]
resized_image[:, :, 2] = blue_channel[0::original_width//resize_width, 0::original_height//resize_height]
return resized_image
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.