在python中使用openCV和PIL通过填充、保存高度和宽度的分辨率以及固定分辨率来调整图像大小

vwhgwdsa  于 2023-03-23  发布在  Python
关注(0)|答案(1)|浏览(162)

如何在python中调整图像大小以满足以下要求?
1.如果宽度和高度不相等,则填充图像。
1.通过改变一个维度的分辨率并相应地调整另一维度以保持纵横比。
1.通过改变两个维度的分辨率但不保持纵横比。

6fe3ivhb

6fe3ivhb1#

今天我不得不写一个包含这些需求的模块。我想这将是很好的分享给其他正在研究类似问题的人,也作为将来自己的文档。

下面是一个process_image.py文件,代码如下:

import cv2
from PIL import Image
import math

# Set input image filename
input_image = 'input_image.jpg'

# Function to: Resize the input image to a square by padding the smaller dimension with a white background.
def reformat_image_to_square_by_padding(image):
    """
    Resize the input image to a square by padding the smaller dimension with a white background.

    :param image: str, path to the input image
    :return: Image, resized and padded image
    """
    image = Image.open(image, 'r')
    width, height = image.size

    if width != height:
        bigside = max(width, height)
        background = Image.new('RGBA', (bigside, bigside), (255, 255, 255, 255))
        offset = (int(round(((bigside - width) / 2), 0)), int(round(((bigside - height) / 2), 0)))
        background.paste(image, offset)
        new_image = background.convert('RGB')
        return new_image, width, height, new_image.size
    else:
        new_image = image.convert('RGB')
        return new_image, width, height, new_image.size

# Function to: Resize the input image while preserving its aspect ratio.
def reformat_image_preserve_aspect_ratio(image, width=None, height=None, inter=cv2.INTER_AREA):
    """
    Resize the input image while preserving its aspect ratio.

    :param image: str, path to the input image
    :param width: int, desired width of the resized image (default: None)
    :param height: int, desired height of the resized image (default: None)
    :param inter: interpolation method used for resizing (default: cv2.INTER_AREA)
    :return: tuple, resized image and its dimensions
    """
    # Read the image
    image = cv2.imread(image)

    # Get the original image dimensions
    (h, w) = image.shape[:2]

    if width is None and height is None:
        return image

    if width is None:
        r = height / float(h)
        dim = (int(math.ceil(w * r)), height)
    else:
        r = width / float(w)
        dim = (width, int(math.ceil(h * r)))

    # Resize the image
    new_image = cv2.resize(image, dim, interpolation=inter)

    # return new_image, w, h, r, dim
    return new_image, image, w, h, r, dim

# Function to: Resize the input image to the desired dimensions without preserving its aspect ratio.
def reformat_image_resolution(image, width=None, height=None):
    """
    Resize the input image to the desired dimensions without preserving its aspect ratio.

    :param image: str, path to the input image
    :param width: int, desired width of the resized image
    :param height: int, desired height of the resized image
    :return: tuple, resized image and its dimensions
    """
    image = cv2.imread(image)
    original_image = image.copy()
    original_height, original_width = image.shape[:2]

    # find the ratio of original:requested resolution
        # ACRONYM: ratio_width_O2R -> ratio of width Original to Requested
    requested_W, requested_H = width, height
    ratio_width_O2R = original_width / float(requested_W)
    ratio_height_O2R = original_height / float(requested_H)

    newW, newH = width, height
    rW = original_width / float(newW)
    rH = original_height / float(newH)

    new_image = cv2.resize(image, (requested_W, requested_H))
    new_height, new_width = new_image.shape[:2]

    return new_image, original_image, original_width, original_height, ratio_width_O2R, ratio_height_O2R, new_width, new_height

# Method 1: Resize to square by padding
output_image, width, height, new_width_height = reformat_image_to_square_by_padding(input_image)
output_image.save("output_image_padded_and_squared.jpg")
# NOTE: saving method for this output image is different because it is PIL object.

print("Resize to square by padding")
print("original width, original height, new_width_height")
print(width, height, new_width_height)
print()

# Method 2: Resize at desired resolution
output_image, original_image, *dimensions = reformat_image_resolution(input_image, width=320, height=320)
# print("original_height, original_width, rW, rH, new_height2, new_width2 \n", *dimensions)

print("Resize at desired resolution")
print("original_width, original_height, ratio_width_O2R, ratio_height_O2R, new_width, new_height \n", 
      *dimensions)
cv2.imwrite("output_image_resized_wxh_at_desired_resolution.jpg", output_image)
print()

# Method 3: Resize while preserving aspect ratio
output_image, original_image, w, h, r, dim = reformat_image_preserve_aspect_ratio(input_image, height=500)

print("Resize while preserving aspect ratio")
print("original_width, original_height, ratio, (new_width, new_height) \n", w, h, r, dim)
cv2.imwrite("output_image_resized_height_with_preserved_aspect_ratio.jpg", output_image)
print()

输出:

$ python preprocess_image.py 
Resize to square by padding
original width, original height, new_width_height
1280 720 (1280, 1280)

Resize at desired resolution
original_width, original_height, ratio_width_O2R, ratio_height_O2R, new_width, new_height 
 1280 720 4.0 2.25 320 320

Resize while preserving aspect ratio
original_width, original_height, ratio, (new_width, new_height) 
 1280 720 0.6944444444444444 (889, 500)

输入图片:

输出镜像:

∮ ∮ ∮ ∮ ∮一卡一卡一

相关问题