在给定目标大小的情况下,如何在python中调整图像大小的同时保持宽高比? [英] How to resize an image in python, while retaining aspect ratio, given a target size?

查看:301
本文介绍了在给定目标大小的情况下,如何在python中调整图像大小的同时保持宽高比?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我觉得这是一个愚蠢的问题,对此感到抱歉.目前,我发现计算最佳缩放比例(目标像素数的最佳宽度和高度,同时保留长宽比)时,最准确的方法正在迭代并选择最佳缩放比例,但是必须有一种更好的方法.

一个例子:

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))

解决方案

这是我的方法,

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

First off part of me feels like this is a stupid question, sorry about that. Currently the most accurate way I've found of calculating the optimum scaling factor (best width and height for target pixel count while retaining aspect ratio) is iterating through and choosing the best one however there must be a better way of doing this.

An example:

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

I know there are probably some errors lying around in the code above i.e. there is no check in the results dictionary for an existing key but I am more concerned with a different approach which I cannot figure out was looking into lagrangian optimisation but that seems quite complex also for a simple problem. Any ideas?

** EDIT AFTER ANSWER **

Going to provide the code if anyone is interested in the answer

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))

解决方案

Here is my approach,

aspectRatio = currentWidth / currentHeight
heigth * width = area

So,

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

At that point we know the target height, and width = height * aspectRatio.

Ex:

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

这篇关于在给定目标大小的情况下,如何在python中调整图像大小的同时保持宽高比?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆