简体   繁体   English

在不使用 resize() 的情况下调整 python 中的图像大小 - 最近邻

[英]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.

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