【问题标题】:How to resize an image in python, while retaining aspect ratio, given a target size?如何在给定目标大小的情况下在 python 中调整图像大小,同时保持纵横比?
【发布时间】:2020-03-20 22:25:56
【问题描述】:

首先我觉得这是一个愚蠢的问题,对此感到抱歉。目前,我发现计算最佳缩放因子(目标像素数的最佳宽度和高度,同时保持纵横比)的最准确方法是迭代并选择最佳的,但是必须有更好的方法来做到这一点。

一个例子:

import cv2, numpy as np
img = cv2.imread("arnold.jpg")

img.shape[1] # e.g. width  = 700
img.shape[0] # e.g. height = 979

# e.g. Total  pixels : 685,300

TARGET_PIXELS = 100000
MAX_FACTOR    = 0.9
STEP_FACTOR   = 0.001
iter_factor   = STEP_FACTOR
results       = dict()

while iter_factor < MAX_RATIO:
     img2 = cv2.resize(img, (0,0), fx=iter_factor, fy=iter_factor)
     results[img2.shape[0]*img2.shape[1]] = iter_factor
     iter_factor += step_factor

best_pixels = min(results, key=lambda x:abs(x-TARGET_PIXELS))
best_ratio  = results[best_pixels]

print best_pixels # e.g. 99750
print best_ratio  # e.g. 0.208

我知道上面的代码中可能存在一些错误,即在结果字典中没有检查现有键,但我更关心一种不同的方法,我无法弄清楚它正在研究拉格朗日优化,但对于一个简单的问题,似乎也很复杂。有什么想法吗?

** 回答后编辑 **

如果有人对答案感兴趣,将提供代码

import math, cv2, numpy as np

# load up an image
img = cv2.imread("arnold.jpg")

TARGET_PIXEL_AREA = 100000.0

ratio = float(img.shape[1]) / float(img.shape[0])
new_h = int(math.sqrt(TARGET_PIXEL_AREA / ratio) + 0.5)
new_w = int((new_h * ratio) + 0.5)

img2 = cv2.resize(img, (new_w,new_h))

【问题讨论】:

  • 嗯,这段代码对我来说没有保持纵横比...例如,如果我提供一个宽幅图像,它会垂直拉伸它以填充 TARGET_PIXEL_AREA 大小的正方形
  • 我认为您需要测试纵向或横向(从纵横比),并使用两个公式之一计算从高度计算宽度或从宽度计算高度取决于大于或小于 1 的比率

标签: python opencv math


【解决方案1】:

这是我的方法,

aspectRatio = currentWidth / currentHeight
heigth * width = area

所以,

height * (height * aspectRatio) = area
height² = area / aspectRatio
height = sqrt(area / aspectRatio)

此时我们知道目标高度和width = height * aspectRatio

例如:

area = 100 000
height = sqrt(100 000 / (700/979)) = 373.974
width = 373.974 * (700/979) = 267.397

【讨论】:

  • 谢谢,是的,这就是我一直在寻找的东西,现在看起来很简单!
【解决方案2】:

我认为最快和更干净的方法是:

from PIL import Image
from math import sqrt

img=Image.open(PATH)
img.thumbnails([round(sqrt(TARGET_PIXEL_AREA))]*2)

希望对你有帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-21
    • 2013-05-12
    • 2010-12-03
    • 1970-01-01
    • 1970-01-01
    • 2013-06-26
    • 2012-04-15
    相关资源
    最近更新 更多